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

news2024/11/28 2:39:35

目录

  • 1、介绍
  • 2、实现方法
    • 2.1 算法实现过程
    • 2.2 模拟采集流程
  • 3、总结
  • 4、代码展示

1、介绍

在机器视觉的开发中,现在有很多通过电机去做相机的聚焦调节,对比手工调节,自动调节效果更好,而且其也能满足设备自动的需求,尤其在一些高倍成像的环境下应用场景更广泛,图像清晰度是衡量图像质量的一个重要的指标,手动调焦的过程是通过人为去判定图像的清晰度,调节镜头的焦距,使得图像从模糊到清洗,再到模糊的过程,确定清洗度的峰值,自动调焦就是通过算法对采集的每一张图像的清晰度进行评价,最终给出图像清晰的峰值,从而确定调焦获取的焦距最佳。
常见的图像清晰度评价一般都是基于梯度的方法,本文主要介绍Brenner梯度法。
Brenner梯度法.jpg
本节使用了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梯度法效果较好,以后有机会会介绍一下其他的方法。
5.AutoFacus.PNG

4、代码展示

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1530357.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

高效的Gitlab Flow最佳实践

文章目录 一、git flow二、github flow三、gitlab flow四、基于gitlab flow的最佳实践1.语义化版本号2.测试发布3.bug修复 参考 业界包含三种flow&#xff1a; Git flowGithub flowGitlab flow 三种工作流程&#xff0c;有一个共同点&#xff1a;都采用"功能驱动式开发&…

圆弧齿的模型怎么建立?

今天咱们聊一聊圆弧齿的相关内容&#xff0c;有兴趣的小伙伴一起来看看吧。 圆弧齿轮发展历史 早期齿轮传动的速度较低、传递的功率小&#xff0c;长期的生产实践使得人们开始意识到对齿轮单个轮齿形状&#xff08;轮齿齿形&#xff09;的研究的重要性&#xff0c;齿轮的齿形…

5G安全技术新突破!亚信安全5G安全迅龙引擎正式发布

5G专网应用飞速增长&#xff1a;2020年5G专网数量800个&#xff0c;2021年2300个&#xff0c;2022年5325个&#xff0c;2023年已经超过16000个&#xff0c;5G与垂直行业的融合快速加深&#xff0c;5G带来的变革正加速渗透至各行各业。 5G网络出现安全问题&#xff0c;将是异常严…

MNN createFromBuffer(一)

系列文章目录 MNN createFromBuffer&#xff08;一&#xff09; MNN createRuntime&#xff08;二&#xff09; MNN createSession 之 Schedule&#xff08;三&#xff09; MNN createSession 之创建流水线后端&#xff08;四&#xff09; MNN Session::resize 之流水线编码&am…

C语言例3-12:自增和自减运算的例子

i 先引用后加1--i 先减1后引用 代码如下&#xff1a; #include<stdio.h> int main(void) {int i2, j2;char c1d, c2D; //d(100) D(68)printf("i %d\n",i); //3, i3printf("j-- %d\n",j--); …

Design Script之案例练习:曲线组合

让我们来探索一下如何创建分组曲线函数。这个函数将取一个无序曲线列表(必须是连续的),并将它们组合成分组的循环。 在这个例子中,我们将采取一系列的9个爆炸矩形,并洗牌合成曲线。这给了我们36条单独的曲线,它们可以正确地组合回各自的矩形中。 一些分散的曲线显示在右边…

发布镜像到阿里云仓库

发布上一篇Dockerfile实战-自定义的centos镜像。 1、登录阿里云 2、找到容器镜像服务 3、创建命令空间 4、创建镜像仓库 5、点击进入这个镜像仓库&#xff0c;可以看到所有的信息 6、根据操作指南测试推送发布 6.1登录阿里云 [rootzhoujunru home]# docker login --usernam…

数据仓库系列总结

一、数据仓库架构 1、数据仓库的概念 数据仓库&#xff08;Data Warehouse&#xff09;是一个面向主题的、集成的、相对稳定的、反映历史变化的数据集合&#xff0c;用于支持管理决策。 数据仓库通常包含多个来源的数据&#xff0c;这些数据按照主题进行组织和存储&#x…

mapboxgl添加雪碧图 addImage loadImage png/jpg svg

一、mapboxgl可以添加png或者jpg类型的图片到雪碧图中 async function addPng(id, url) {const img await new Promise((resolve) > {map.loadImage(url, (error, image) > {if (error) throw error;resolve(image);});});if (!map.hasImage(id)) {map.addImage(id, img…

【链表】算法例题

目录 八、 链表 57. 环形链表 ① 58. 两数相加 ② √ 59. 合并两个有序链表 ① √- 60. 随机链表的复制 ② 61. 反转链表II ② 62. K个一组翻转链表 ③ 63. 删除链表的倒数第N个结点 ② √- 64. 删除排序链表中的重复元素II ② √- 65. 旋转链表 ② √- 66. 分隔链…

【目标检测】图解 YOLOv3 的网络结构(Darknet-53 作为 backbone)

到了 YOLOv3&#xff0c;backbone 从 YOLOv2 的 Darknet-19 升级到了 Darknet-53。 下面一张完整的结构示意图来一起理解一下 YOLOv3 的网络结构。 我们怎么理解最后输出的 3 个特征图&#xff08;feature map&#xff09;的这个 255&#xff1f; 同 YOLOv2 一样&#xff0c;…

常见传感器的原理 和 常见滤波算法实现

阅读引言&#xff1a; 分析常见的传感器的电路原理、向大家提供一些ADC常见的滤波算法的实现, 介绍声、光、热、电、力、气和磁传感器的大致工作原理。 目录 一、常见传感器工作原理 1.声音传感器-动圈&电容咪头 2.光传感器-光敏电阻 3.热传感器-热电偶 4.电传感器-电…

YOLOv8改进 | 主干篇 | 利用图像分割网络UNetV2改善图像分割检测性能(全网独家首发)

一、本文介绍 本文给大家带来的改进机制是利用图像分割网络UNetV2的主干来改进我们的YOLOv8分割模型&#xff08;本文的内容虽然YOLOv8所有的功能的用户都能使用&#xff0c;但是还是建议分割的用户使用&#xff09;&#xff0c;U-Net v2 旨在改进医学图像分割的性能&#xff…

Spring-Gateway服务网关

一、网关介绍 1. 为什么需要网关 Gateway网关是我们服务的守门神&#xff0c;所有微服务的统一入口。 网关的核心功能特性&#xff1a; 请求路由 权限控制 限流 架构图&#xff1a; 权限控制&#xff1a;网关作为微服务入口&#xff0c;需要校验用户是是否有请求资格&am…

Zerotier 异地组网方案初探

前言 我之前想要异地组网的话&#xff0c;一般都采用内网穿透的方法&#xff0c;但是这个内网穿透有弊端就是都是要通过公网服务器转发流量&#xff0c;对于大流量的传输就比较不方便&#xff0c;我发现了Zerotier 这个工具非常的好用&#xff0c;是基于p2p的 这是一个类似于…

【SpringBoot3+Mybatis】框架快速搭建

文章目录 GitHub 项目一、依赖二、 配置文件三、启动类四、SpringBoot3兼容Druid报错五、工具类5.1 结果封装类5.2 解决枚举类5.3 MD5加密工具类 GitHub 项目 springboot-part——springboot-integrate-07 Mybatis-plus版完整CRUD项目文档记录&#xff1a; 【SpringBoot3Myba…

【项目实践Day06】异步请求与同步请求+Ajax+微信小程序上实现发送异步请求

什么是同步和异步 同步 在主线程上排队执行的任务&#xff0c;只有前一个任务执行完毕&#xff0c;才能继续执行下一个任务。也就是一旦调用开始&#xff0c;就必须等待其返回结果&#xff0c;程序的执行顺序和任务排列顺序一致。客户端必须等待服务器端的响应。在等待的期间客…

【保姆级】前端使用node.js基础教程

文章目录 安装和版本管理&#xff1a;npm 命令&#xff08;Node 包管理器&#xff09;&#xff1a;运行 Node.js 脚本&#xff1a;调试和开发工具&#xff1a;其他常用命令&#xff1a;模块管理&#xff1a;包管理&#xff1a;调试工具&#xff1a;异步编程和包管理&#xff1a…

kafka2.x版本配置SSL进行加密和身份验证

背景&#xff1a;找了一圈资料&#xff0c;都是东讲讲西讲讲&#xff0c;最后我还没搞好&#xff0c;最终决定参考官网说明。 官网指导手册地址&#xff1a;Apache Kafka 需要预备的知识&#xff0c;keytool和openssl 关于keytool的参考&#xff1a;keytool的使用-CSDN博客 …

【漏洞复现】正方教学管理信息服务平台ReportServer存在任意文件读取

免责声明&#xff1a;文章来源互联网收集整理&#xff0c;请勿利用文章内的相关技术从事非法测试&#xff0c;由于传播、利用此文所提供的信息或者工具而造成的任何直接或者间接的后果及损失&#xff0c;均由使用者本人负责&#xff0c;所产生的一切不良后果与文章作者无关。该…