[Qt学习笔记]Qt下使用Halcon实现采图时自动对焦的功能(Brenner梯度法)

目录

1、介绍

在机器视觉的开发中,现在有很多通过电机去做相机的聚焦调节,对比手工调节,自动调节效果更好,而且其也能满足设备自动的需求,尤其在一些高倍成像的环境下应用场景更广泛,图像清晰度是衡量图像质量的一个重要的指标,手动调焦的过程是通过人为去判定图像的清晰度,调节镜头的焦距,使得图像从模糊到清洗,再到模糊的过程,确定清洗度的峰值,自动调焦就是通过算法对采集的每一张图像的清晰度进行评价,最终给出图像清晰的峰值,从而确定调焦获取的焦距最佳。

常见的图像清晰度评价一般都是基于梯度的方法,本文主要介绍Brenner梯度法。

本节使用了30张不同清晰度的图像来模拟相机采图时从对焦模糊到清晰再到模糊的过程。

2、实现方法

2.1 算法实现过程

void MainWindow::AutoFocus(HObject ho_Image)
{
 
    HObject  ho_ImagePart00, ho_ImagePart20;
    HObject  ho_ImageSub, ho_ImageResult, ho_ImagePart01, ho_ImagePart10;
    HObject  ho_ImageSub1, ho_ImageResult1, ho_ImageSub2, ho_ImageResult2;

    HTuple  hv_I, hv_Width, hv_Height, hv_WindowID;
    HTuple  hv_Value, hv_Deviation;
    try
    {
        GetImageSize(ho_Image,&hv_Width,&hv_Height);
        CropPart(ho_Image, &ho_ImagePart00, 0, 0, hv_Width, hv_Height-2);
        ConvertImageType(ho_ImagePart00, &ho_ImagePart00, "real");
        CropPart(ho_Image, &ho_ImagePart20, 2, 0, hv_Width, hv_Height-2);
        ConvertImageType(ho_ImagePart20, &ho_ImagePart20, "real");
        SubImage(ho_ImagePart20, ho_ImagePart00, &ho_ImageSub, 1, 0);
        MultImage(ho_ImageSub, ho_ImageSub, &ho_ImageResult, 1, 0);
        Intensity(ho_ImageResult, ho_ImageResult, &hv_Value, &hv_Deviation);

        double d=hv_Deviation.D();
        QString strDev=QString::number(d,'f',3);
        ui->labDev->setText(strDev);

        //记录最大偏差值
        if(hv_PreDeviation<hv_Deviation)
        {
            hv_PreDeviation=hv_Deviation;
        }
    }
    catch(HalconCpp::HException &except)
    {
        qDebug()<<except.ProcName().Text()<<endl;
        qDebug()<<except.ErrorMessage().Text()<<endl;
        qDebug()<<except.ErrorCode()<<endl;
    }
}

如Brenner算法的公式所示,首先将图像转换成real类型,然后对图像进行图像差处理,然后进行图像乘积,最后获得平均值及偏差,把偏差作为清晰度的评价参数

2.2 模拟采集流程

这里创建一个线程,然后使用延时的定时器,从文件夹中依次读取30张图像,每张图像进行Brenner算法处理。

线程定义如下:

    camera = new CameraCtrl();
    liveThread = new QThread();
    camera->moveToThread(liveThread);
    connect(liveThread,&QThread::finished,camera,&QObject::deleteLater);
    connect(this,&MainWindow::ContinuousGrab,camera,&CameraCtrl::HandleContinuousGrab);
    liveThread->start();

然后线程开始后进行连续读取图像处理流程

//读取图像并调用Brenner算法函数
void CameraCtrl::HandleContinuousGrab()
{    
    HTuple  hv_I;
    HObject  ho_Image;    
    for (hv_I=1; hv_I<=30; hv_I+=1)
    {
        ReadImage(&ho_Image, ("E:/Qt_Test/AutoFacus/Buddha/"+hv_I)+".png");
        Delay_MSec(tInter);
        emit hobjectReady(ho_Image);
        if(isFocus==true)
        {
            emit hobjectFocus(ho_Image);
        }
    }
}

其中定义延时定时器

void CameraCtrl::Delay_MSec(unsigned int msec)
{
    QEventLoop loop;//定义一个新的事件循环
    QTimer::singleShot(msec, &loop, SLOT(quit()));//创建单次定时器,槽函数为事件循环的退出函数
    loop.exec();//事件循环开始执行,程序会卡在这里,直到定时时间到,本循环被退出
}

3、总结

一个好的评价函数需要具有单峰性,无偏性,灵敏性,常见的图像清晰度评价的算法有多种,比如Brenner梯度法、Tenegrad梯度法、laplace梯度法、方差法、能量梯度法等等,本节只介绍了Brenner梯度法,目前反馈的Brenner梯度法效果较好,以后有机会会介绍一下其他的方法。

4、代码展示

本小例程的代码放到我的开源gitte项目里,欢迎一起学习,也希望能收获你的小星星。
AutoFacus源码

相关推荐
一律清风5 小时前
QT-文件创建时间修改器
c++·qt
不知所云,5 小时前
qt cmake自定义资源目录,手动加载资源(图片, qss文件)
开发语言·qt
Death2006 小时前
Qt 6 相比 Qt 5 的主要提升与更新
开发语言·c++·qt·交互·数据可视化
机器视觉知识推荐、就业指导6 小时前
使用Qt实现实时数据动态绘制的折线图示例
开发语言·qt
Geek之路9 小时前
QT系统学习篇(1)
开发语言·qt·学习
Geek之路17 小时前
Qt系统学习篇(6)-QMainWindow
数据库·qt·学习
初阳78518 小时前
【Qt】控件概述(2)—— 按钮类控件
开发语言·qt
初阳78518 小时前
【Qt】控件概述(3)—— 显示类控件
开发语言·qt
efls11119 小时前
Qt_绘图
开发语言·c++·qt
TravisBytes19 小时前
在 Qt 项目中使用 spdlog 的全攻略
开发语言·c++·qt