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

2024-06-11 21:38

本文主要是介绍OpenCV 图像清晰度评价算法(相机自动对焦),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

相机的自动对焦要求相机根据拍摄环境和场景的变化,通过相机内部的微型驱动马达,自动调节相机镜头和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 图像清晰度评价算法(相机自动对焦)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1052345

相关文章

OpenCV实现实时颜色检测的示例

《OpenCV实现实时颜色检测的示例》本文主要介绍了OpenCV实现实时颜色检测的示例,通过HSV色彩空间转换和色调范围判断实现红黄绿蓝颜色检测,包含视频捕捉、区域标记、颜色分析等功能,具有一定的参考... 目录一、引言二、系统概述三、代码解析1. 导入库2. 颜色识别函数3. 主程序循环四、HSV色彩空间

MyBatis Plus 中 update_time 字段自动填充失效的原因分析及解决方案(最新整理)

《MyBatisPlus中update_time字段自动填充失效的原因分析及解决方案(最新整理)》在使用MyBatisPlus时,通常我们会在数据库表中设置create_time和update... 目录前言一、问题现象二、原因分析三、总结:常见原因与解决方法对照表四、推荐写法前言在使用 MyBATis

Python使用smtplib库开发一个邮件自动发送工具

《Python使用smtplib库开发一个邮件自动发送工具》在现代软件开发中,自动化邮件发送是一个非常实用的功能,无论是系统通知、营销邮件、还是日常工作报告,Python的smtplib库都能帮助我们... 目录代码实现与知识点解析1. 导入必要的库2. 配置邮件服务器参数3. 创建邮件发送类4. 实现邮件

Python中OpenCV与Matplotlib的图像操作入门指南

《Python中OpenCV与Matplotlib的图像操作入门指南》:本文主要介绍Python中OpenCV与Matplotlib的图像操作指南,本文通过实例代码给大家介绍的非常详细,对大家的学... 目录一、环境准备二、图像的基本操作1. 图像读取、显示与保存 使用OpenCV操作2. 像素级操作3.

C/C++中OpenCV 矩阵运算的实现

《C/C++中OpenCV矩阵运算的实现》本文主要介绍了C/C++中OpenCV矩阵运算的实现,包括基本算术运算(标量与矩阵)、矩阵乘法、转置、逆矩阵、行列式、迹、范数等操作,感兴趣的可以了解一下... 目录矩阵的创建与初始化创建矩阵访问矩阵元素基本的算术运算 ➕➖✖️➗矩阵与标量运算矩阵与矩阵运算 (逐元

C/C++的OpenCV 进行图像梯度提取的几种实现

《C/C++的OpenCV进行图像梯度提取的几种实现》本文主要介绍了C/C++的OpenCV进行图像梯度提取的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的... 目录预www.chinasem.cn备知识1. 图像加载与预处理2. Sobel 算子计算 X 和 Y

C/C++和OpenCV实现调用摄像头

《C/C++和OpenCV实现调用摄像头》本文主要介绍了C/C++和OpenCV实现调用摄像头,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一... 目录准备工作1. 打开摄像头2. 读取视频帧3. 显示视频帧4. 释放资源5. 获取和设置摄像头属性

c/c++的opencv图像金字塔缩放实现

《c/c++的opencv图像金字塔缩放实现》本文主要介绍了c/c++的opencv图像金字塔缩放实现,通过对原始图像进行连续的下采样或上采样操作,生成一系列不同分辨率的图像,具有一定的参考价值,感兴... 目录图像金字塔简介图像下采样 (cv::pyrDown)图像上采样 (cv::pyrUp)C++ O

c/c++的opencv实现图片膨胀

《c/c++的opencv实现图片膨胀》图像膨胀是形态学操作,通过结构元素扩张亮区填充孔洞、连接断开部分、加粗物体,OpenCV的cv::dilate函数实现该操作,本文就来介绍一下opencv图片... 目录什么是图像膨胀?结构元素 (KerChina编程nel)OpenCV 中的 cv::dilate() 函

Python使用pynput模拟实现键盘自动输入工具

《Python使用pynput模拟实现键盘自动输入工具》在日常办公和软件开发中,我们经常需要处理大量重复的文本输入工作,所以本文就来和大家介绍一款使用Python的PyQt5库结合pynput键盘控制... 目录概述:当自动化遇上可视化功能全景图核心功能矩阵技术栈深度效果展示使用教程四步操作指南核心代码解析