相机的自动对焦要求相机根据拍摄环境和场景的变化,通过相机内部的微型驱动马达,自动调节相机镜头和CCD之间的距离,保证像平面正好投影到CCD的成像表面上。这时候物体的成像比较清晰,图像细节信息丰富。

相机自动对焦的过程,其实就是对成像清晰度评价的过程,对焦不准确,拍摄出来的图像清晰度低,视觉效果模糊,如果是在工业检测测量领域,对焦不准导致的后果可能是致命的;对焦准确的图像清晰度较高,层次鲜明,对比度高。

图像清晰度评价算法有很多种,在空域中,主要思路是考察图像的领域对比度,即相邻像素间的灰度特征的梯度差;在频域中,主要思路是考察图像的频率分量,对焦清晰的图像高频分量较多,对焦模糊的图像低频分量较多。

这里实现3种清晰度评价方法,分别是Tenengrad梯度方法、Laplacian梯度方法和方差方法。

Tenengrad梯度方法

Tenengrad梯度方法利用Sobel算子分别计算水平和垂直方向的梯度,同一场景下梯度值越高,图像越清晰。以下是具体实现,这里衡量的指标是经过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();
}

使用三张测试图片模拟不同对焦。第一张最清晰,得分最高,第二三张越来越模糊,得分依次降低。

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();
}

用同样的三张测试图片测试,结果一致,随着对焦模糊得分降低:

方差方法:

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

对焦清晰的图像相比对焦模糊的图像,它的数据之间的灰度差异应该更大,即它的方差应该较大,可以通过图像灰度数据的方差来衡量图像的清晰度,方差越大,表示清晰度越好

#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; //求灰度图像的标准差
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();
}

方差数值随着清晰度的降低逐渐降低:

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


OpenCV 图像清晰度评价(相机自动对焦)的更多相关文章

  1. OpenCV 图像清晰度(相机自动对焦)

    相机的自动对焦要求相机根据拍摄环境和场景的变化,通过相机内部的微型驱动马达,自动调节相机镜头和CCD之间的距离,保证像平面正好投影到CCD的成像表面上.这时候物体的成像比较清晰,图像细节信息丰富. 相 ...

  2. Atitit 图像清晰度 模糊度 检测 识别 评价算法 源码实现attilax总结

    Atitit 图像清晰度 模糊度 检测 识别 评价算法 源码实现attilax总结 1.1. 原理,主要使用像素模糊后的差别会变小1 1.2. 具体流程1 1.3. 提升性能 可以使用采样法即可..1 ...

  3. Atitit 图像清晰度 模糊度 检测 识别 评价算法 原理

    Atitit 图像清晰度 模糊度 检测 识别 评价算法 原理 1.1. 图像边缘一般都是通过对图像进行梯度运算来实现的1 1.2. Remark: 1 1.3.  1.失焦检测. 衡量画面模糊的主要方 ...

  4. 相机自动对焦AF原理

    相机自动对焦AF原理 AF性能是判断相机好坏的重要指标,主要从准确度和速度两个方面来进行考察,本文将介绍自动对焦的几种方式. 一.凸透镜成像原理 二.三种对焦方法 有公式在手,只要给相机安个测距仪就好 ...

  5. <学习opencv>图像和大型阵列类型

    OPenCV /*=========================================================================*/ // 图像和大型阵列类型 /* ...

  6. <学习opencv>图像、视频和数据文件

    /*=========================================================================*/ // openCV中的函数 /*====== ...

  7. OpenCV图像金字塔:高斯金字塔、拉普拉斯金字塔与图片尺寸缩放

    这篇已经写得很好,真心给作者点个赞.题目都是直接转过来的,直接去看吧. Reference Link : http://blog.csdn.net/poem_qianmo/article/detail ...

  8. 【OpenCV新手教程之十三】OpenCV图像金字塔:高斯金字塔、拉普拉斯金字塔与图片尺寸缩放

    本系列文章由@浅墨_毛星云 出品,转载请注明出处. 文章链接:http://blog.csdn.net/poem_qianmo/article/details/26157633 作者:毛星云(浅墨) ...

  9. Opencv 图像叠加 添加水印

    Opencv 图像叠加 添加水印 C++: void Mat::copyTo(OutputArray m) const C++: void Mat::copyTo(OutputArray m, Inp ...

随机推荐

  1. 关于stm32的启动模式

    1)用户闪存 = 芯片内置的Flash,这个应该就是在Keil中选择那个,每个芯片的flash不一样,具体可以在建立工程时查看内置flash的大小. 2)SRAM = 芯片内置的RAM区,就是内存啦. ...

  2. 数据结构与算法实验题 6.1 s_sin’s bonus

    数据结构与算法实验题 6.1 s_sin's bonus ★实验任务 正如你所知道的 s_sin 是一个非常贪玩的人 QAQ(如果你非常讨厌他请直接从第二段开 始看),并且令人感到非常遗憾的是,他是一 ...

  3. 微服务API模拟框架frock介绍

    本文来源于我在InfoQ中文站翻译的文章,原文地址是:http://www.infoq.com/cn/news/2016/02/introducing-frock Urban Airship是一家帮助 ...

  4. Qt信号槽传递自定义类型参数(qRegisterMetaType)

    1 #include <QMetaType>//记得包含这个头文件 2 //my_type是我自己定义的类型 3 qRegisterMetaType<my_type>(&quo ...

  5. 正确理解Spring事务和数据库事务和锁

    Lock wait timeout exceeded; try restarting transaction解决方案 参考文章 Spring中@Transactional事务回滚 http://www ...

  6. BZOJ 1588 HNOI2002 营业额统计 裸Treap

    题目大意:...题目描写叙述不全看这里好了 给定一个序列 对于每一个元素我们定义该数的最小波动值为这个数与前面全部数的差中的最小值(第一个数的最小波动值为第一个数本身) 求最小波动值之和 找近期的数仅 ...

  7. Linux系统编程——线程私有数据

    在多线程程序中.常常要用全局变量来实现多个函数间的数据共享.因为数据空间是共享的,因此全局变量也为全部线程共同拥有. 測试代码例如以下: #include <stdio.h> #inclu ...

  8. python 标准库 —— io(StringIO)

    0. io流(io stream) 流是一种抽象概念,它代表了数据的无结构化传递.按照流的方式进行输入输出,数据被当成无结构的字节序或字符序列.从流中取得数据的操作称为提取操作,而向流中添加数据的操作 ...

  9. oracle 列授权相关测试

    create tablespace liangtbs datafile '/home/oradata/lgjdb/liangtbs01.dbf' size 50m autoextend on;crea ...

  10. 【a601】雇佣计划

    Time Limit: 1 second Memory Limit: 32 MB [问题描述] 一位管理项目的经理想要确定每个月需要的工人,他知道每月所需的最少工人数.当他雇佣或解雇一个工人时,会有一 ...