OpenCV 图像清晰度评价(相机自动对焦)

最近想实现相机自动对焦,也就是需要图像清晰度评价,在网上查找。

第一个不错文章是:无参考图像的清晰度评价方法

 http://nkwavelet.blog.163.com/blog/static/227756038201461532247117

这个对理论或者公式介绍很详细,共有16个计算方法,值得一学。

(1)Brenner 梯度函数

(2)Tenengrad 梯度函数

(3)Laplacian 梯度函数

(4)SMD(灰度方差)函数

...

后面是模糊检测,噪点检测,噪点和模糊的组合

文章注重理论,没有具体的样例程序。有结果对比图。

第二个不错文章是:OpenCV 图像清晰度评价(相机自动对焦)

https://blog.csdn.net/dcrmg/article/details/53543341

这个集中上面前三个方法的实现,这3个在opencv 都有函数实现。实现3种清晰度评价方法,分别是Tenengrad梯度方法、Laplacian梯度方法和方差方法。

Tenengrad梯度方法,衡量的指标是经过Sobel算子处理后的图像的平均灰度值,值越大,代表图像越清晰。Sobel 函数。

Laplacian梯度方法:同上,但用的是 Laplacian 函数

方差方法:方差是概率论中用来考察一组离散数据和其期望(即数据的均值)之间的离散(偏离)程度的度量方法。方差较大,表示这一组数据之间的偏差就较大,组内的数据有的较大,有的较小,分布不均衡;方差较小,表示这一组数据之间的偏差较小,组内的数据之间分布平均,大小相近。方差越大,表示清晰度越好。

这个有样例程序可参考。

下面给出第一个算法的代码如下(第二个只是注销部分差异):

#include 
#include 
 
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);
  //Laplacian(imageGrey, imageSobel, CV_16U); 算法2
 
	//图像的平均灰度
	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();
}

这里的评估值就是 meanValue ,值越大越清晰。// double to string 部分只是加在图上显示。

方差计算的差异是:

//求灰度图像的标准差
	meanStdDev(imageGrey, meanValueImage, meanStdValueImage);
	double meanValue = 0.0;
	meanValue = meanStdValueImage.at(0, 0);

文中也提到:

在工业应用中,最清晰的对焦拍摄出来的图像不一定是最好的,有可能出现摩尔纹(水波纹)现象,一般需要在最清晰对焦位置附件做一个微调。 

 

 

你可能感兴趣的:(c++)