前言
相機(jī)的自動(dòng)對焦要求相機(jī)根據(jù)拍攝環(huán)境和場景的變化,通過相機(jī)內(nèi)部的微型驅(qū)動(dòng)馬達(dá),自動(dòng)調(diào)節(jié)相機(jī)鏡頭和CCD之間的距離,保證像平面正好投影到CCD的成像表面上。這時(shí)候物體的成像比較清晰,圖像細(xì)節(jié)信息豐富。相機(jī)自動(dòng)對焦的過程,其實(shí)就是對成像清晰度評價(jià)的過程,對焦不準(zhǔn)確,拍攝出來的圖像清晰度低,視覺效果模糊,如果是在工業(yè)檢測測量領(lǐng)域,對焦不準(zhǔn)導(dǎo)致的后果可能是致命的;對焦準(zhǔn)確的圖像清晰度較高,層次鮮明,對比度高。
圖像清晰度評價(jià)算法有很多種,在空域中,主要思路是考察圖像的領(lǐng)域?qū)Ρ榷?,即相鄰像素間的灰度特征的梯度差;在頻域中,主要思路是考察圖像的頻率分量,對焦清晰的圖像高頻分量較多,對焦模糊的圖像低頻分量較多。
這里實(shí)現(xiàn)3種清晰度評價(jià)方法,分別是Tenengrad梯度方法、Laplacian梯度方法和方差方法。
Tenengrad梯度方法
Tenengrad梯度方法利用Sobel算子分別計(jì)算水平和垂直方向的梯度,同一場景下梯度值越高,圖像越清晰。以下是具體實(shí)現(xiàn),這里衡量的指標(biāo)是經(jīng)過Sobel算子處理后的圖像的平均灰度值,值越大,代表圖像越清晰。
#include 《highgui/highgui.hpp》
#include 《imgproc/imgproc.hpp》
using namespace std;
using namespace cv;
int main()
{
Mat imageSource = imread(“2.jpg”);
Mat imageGrey;
cvtColor(imageSource, imageGrey, CV_RGB2GRAY);
Mat imageSobel;
Sobel(imageGrey, imageSobel, CV_16U, 1, 1);
//圖像的平均灰度
double meanValue = 0.0;
meanValue = mean(imageSobel)[0];
//double to string
stringstream meanValueStream;
string meanValueString;
meanValueStream 《《 meanValue;
meanValueStream 》》 meanValueString;
meanValueString = “Articulation(Sobel Method): ” + meanValueString;
putText(imageSource, meanValueString, Point(20, 50), CV_FONT_HERSHEY_COMPLEX, 0.8, Scalar(255, 255, 25), 2);
imshow(“Articulation”, imageSource);
waitKey();
}
使用三張測試圖片模擬不同對焦。第一張最清晰,得分最高,第二三張?jiān)絹碓侥:?,得分依次降低?/p>
?
? ? ?
? ??
Laplacian梯度方法:
Laplacian梯度是另一種求圖像梯度的方法,在上例的OpenCV代碼中直接替換Sobel算子即可。
#include 《highgui/highgui.hpp》
#include 《imgproc/imgproc.hpp》
using namespace std;
using namespace cv;
int main()
{
Mat imageSource = imread(“1.jpg”);
Mat imageGrey;
cvtColor(imageSource, imageGrey, CV_RGB2GRAY);
Mat imageSobel;
Laplacian(imageGrey, imageSobel, CV_16U);
//Sobel(imageGrey, imageSobel, CV_16U, 1, 1);
//圖像的平均灰度
double meanValue = 0.0;
meanValue = mean(imageSobel)[0];
//double to string
stringstream meanValueStream;
string meanValueString;
meanValueStream 《《 meanValue;
meanValueStream 》》 meanValueString;
meanValueString = “Articulation(Laplacian Method): ” + meanValueString;
putText(imageSource, meanValueString, Point(20, 50), CV_FONT_HERSHEY_COMPLEX, 0.8, Scalar(255, 255, 25), 2);
imshow(“Articulation”, imageSource);
waitKey();
}
用同樣的三張測試圖片測試,結(jié)果一致,隨著對焦模糊得分降低:
?
方差方法:
方差是概率論中用來考察一組離散數(shù)據(jù)和其期望(即數(shù)據(jù)的均值)之間的離散(偏離)成都的度量方法。方差較大,表示這一組數(shù)據(jù)之間的偏差就較大,組內(nèi)的數(shù)據(jù)有的較大,有的較小,分布不均衡;方差較小,表示這一組數(shù)據(jù)之間的偏差較小,組內(nèi)的數(shù)據(jù)之間分布平均,大小相近。
對焦清晰的圖像相比對焦模糊的圖像,它的數(shù)據(jù)之間的灰度差異應(yīng)該更大,即它的方差應(yīng)該較大,可以通過圖像灰度數(shù)據(jù)的方差來衡量圖像的清晰度,方差越大,表示清晰度越好。
#include 《highgui/highgui.hpp》
#include 《imgproc/imgproc.hpp》
using namespace std;
using namespace cv;
int main()
{
Mat imageSource = imread(“2.jpg”);
Mat imageGrey;
cvtColor(imageSource, imageGrey, CV_RGB2GRAY);
Mat meanValueImage;
Mat meanStdValueImage;
//求灰度圖像的標(biāo)準(zhǔn)差
meanStdDev(imageGrey, meanValueImage, meanStdValueImage);
double meanValue = 0.0;
meanValue = meanStdValueImage.at《double》(0, 0);
//double to string
stringstream meanValueStream;
string meanValueString;
meanValueStream 《《 meanValue*meanValue;
meanValueStream 》》 meanValueString;
meanValueString = “Articulation(Variance Method): ” + meanValueString;
putText(imageSource, meanValueString, Point(20, 50), CV_FONT_HERSHEY_COMPLEX, 0.8, Scalar(255, 255, 25), 2);
imshow(“Articulation”, imageSource);
waitKey();
}
方差數(shù)值隨著清晰度的降低逐漸降低:
?
在工業(yè)應(yīng)用中,最清晰的對焦拍攝出來的圖像不一定是最好的,有可能出現(xiàn)摩爾紋(水波紋)現(xiàn)象,一般需要在最清晰對焦位置附件做一個(gè)微調(diào)。
評論