Halcon实战——基于NCC模板匹配的芯片检测(附源码)

Halcon实战——基于NCC模板匹配的芯片检测(附源码)


关于作者


作者:小白熊

作者简介:精通python、matlab、c#语言,擅长机器学习,深度学习,机器视觉,目标检测,图像分类,姿态识别,语义分割,路径规划,智能优化算法,数据分析,各类创新融合等等。

联系邮箱:xbx3144@163.com

科研辅导、知识付费答疑、个性化定制以及其他合作需求请联系作者~



  在机器视觉中,模板匹配是用于检测图像中目标物体的核心技术。归一化互相关(NCC,Normalized Cross Correlation)是模板匹配中的经典方法。它通过计算模板图像与测试图像对应区域的归一化相关系数来判断匹配程度。归一化操作的目的是消除图像亮度变化的影响,使得模板匹配对不同光照条件具有更强的鲁棒性。在芯片检测任务中,模板匹配技术尤其适用于精确定位和检测芯片上的特定图案或结构。本文结合一段Halcon代码,详细讲解如何通过NCC模板匹配完成图像中目标物体的识别。



1、图像读取

  读取模板图像和测试图像是进行图像处理的第一步。read_image 算子能够加载不同格式的图像(如 BMP、JPEG 等)。在这个示例中,我们分别加载了模板图像和待检测的测试图像。

read_image (ReferImage, 'template.bmp')
read_image (TestImage, 'test.bmp')



2、图像灰度化

  灰度图像是图像处理中的常见格式。在进行模板匹配时,将彩色图像转换为灰度图像能减少计算复杂度,从而提高匹配效率。Halcon 提供的 rgb1_to_gray 算子能够快速完成这一操作。灰度化的图像只包含亮度信息,不再包含颜色信息,这使得处理起来更加简单、快速。

rgb1_to_gray(ReferImage,ReferGrayImage)
rgb1_to_gray(TestImage,TestGrayImage)



3、定义模板区域

  模板匹配的关键之一在于选择合适的模板区域。为了更精确地进行匹配,我们可以通过 draw_rectangle1 算子手动绘制一个矩形,定义图像中需要用作模板的区域。在芯片检测任务中,如何定义模板非常关键。芯片上的很多结构可能是规则性的,定义一个合适的模板区域可以显著提高检测效率。通过手动选择芯片的关键区域作为模板,可以减少无关区域的干扰,并提高匹配的精度和速度。

draw_rectangle1 (WindowHandle, Row1, Column1, Row2, Column2)
gen_rectangle1 (Rectangle, Row1, Column1, Row2, Column2)



4、创建NCC模板

  在 create_ncc_model 算子中,Halcon 会根据裁剪后的模板区域创建一个NCC模板。该模板能够在指定的角度范围内进行旋转匹配,使得它在寻找旋转不变的物体时表现出色。在本例中,模板在 -180° 到 180° 之间的旋转范围内进行匹配。

create_ncc_model (ImageReduced, 'auto', -rad(180), rad(180), 'auto', 'use_polarity', ModelID)



5、查找匹配

  find_ncc_model 算子通过搜索测试图像中与模板相匹配的区域,返回匹配区域的行、列坐标、角度和匹配得分。在该命令中,我们设置了匹配的最小得分为 0.5,意味着只有匹配置信度大于50%的区域才会被认为是有效匹配。此外,30 限制了最多返回 30 个匹配结果,0.5 则规定了匹配区域的重叠比例不能超过50%。

find_ncc_model (TestGrayImage, ModelID, -rad(180), rad(180), 0.5, 30, 0.5, 'true', 0, Row, Column, Angle, Score)



6、显示结果

  匹配结果通过返回的 RowColumnAngle 向量表示。如果没有匹配结果,程序将清除创建的NCC模板并退出。否则,程序将关闭当前窗口,重新打开一个用于显示测试图像的窗口,准备绘制匹配区域。找到匹配后,程序使用 gen_rectangle2() 生成矩形,以标记测试图像中的匹配区域,并通过 dev_display() 将其显示出来。每个匹配区域都会用红色边框绘制,线条宽度为 3,这使得匹配的结果直观可见。

* 如果没有找到匹配的模板
if (|Row| == 0)* 清除NCC模板,释放内存clear_ncc_model (ModelID)* 退出程序return ()
else* 如果找到匹配,关闭当前窗口并打开一个新的窗口显示测试图像dev_close_window ()dev_open_window (0, 0, Width*n, Height*n, 'black', WindowHandle)dev_display (TestImage)* 设置绘图模式为边缘模式dev_set_draw ('margin')* 设置绘图颜色为红色dev_set_color ('red')* 设置线条宽度为3dev_set_line_width (3)* 对每个找到的匹配位置进行绘制for Index := 1 to |Row| by 1* 生成矩形以标记在测试图像中找到的匹配区域gen_rectangle2 (Rectangle1, Row[Index-1], Column[Index-1], Angle[Index-1], width/2, height/2)* 显示矩形dev_display (Rectangle1)endfor* 清除NCC模板,释放内存clear_ncc_model (ModelID)
endif

结果



7、完整代码

* 禁用自动更新显示,避免在过程中不断刷新窗口,提高效率
dev_update_off ()* 关闭之前可能已经打开的显示窗口,确保窗口的正确初始化
dev_close_window ()* 读取模板图像和测试图像
read_image (ReferImage, 'template.bmp')
read_image (TestImage, 'test.bmp')* 将模板图像和测试图像转换为灰度图像
rgb1_to_gray(ReferImage,ReferGrayImage)
rgb1_to_gray(TestImage,TestGrayImage)* 获取模板图像的尺寸(宽度和高度)
get_image_size (ReferImage, Width, Height)* 窗口缩放比例
n := 1.0/2* 打开一个显示窗口,用于显示模板图像
dev_open_window (0, 0, Width*n, Height*n, 'black', WindowHandle)* 显示参考图像
dev_display (ReferImage)* 在窗口中手动绘制一个矩形,用于定义模板区域
draw_rectangle1 (WindowHandle, Row1, Column1, Row2, Column2)* 根据绘制的矩形生成一个矩形区域
gen_rectangle1 (Rectangle, Row1, Column1, Row2, Column2)* 计算矩形的宽度和高度
width := Column2 - Column1
height := Row2 - Row1* 将模板图像在矩形区域内进行裁剪,减少计算域
reduce_domain (ReferGrayImage, Rectangle, ImageReduced)* 创建NCC(归一化互相关)模板,用于在测试图像中查找匹配
* 模板会在 -180° 到 180° 的旋转范围内进行匹配
create_ncc_model (ImageReduced, 'auto', -rad(180), rad(180), 'auto', 'use_polarity', ModelID)* 在测试图像中查找与模板匹配的区域
find_ncc_model (TestGrayImage, ModelID, -rad(180), rad(180), 0.5, 30, 0.5, 'true', 0, Row, Column, Angle, Score)* 如果没有找到匹配的模板
if (|Row| == 0)* 清除NCC模板,释放内存clear_ncc_model (ModelID)* 退出程序return ()
else* 如果找到匹配,关闭当前窗口并打开一个新的窗口显示测试图像dev_close_window ()dev_open_window (0, 0, Width*n, Height*n, 'black', WindowHandle)dev_display (TestImage)* 设置绘图模式为边缘模式dev_set_draw ('margin')* 设置绘图颜色为红色dev_set_color ('red')* 设置线条宽度为3dev_set_line_width (3)* 对每个找到的匹配位置进行绘制for Index := 1 to |Row| by 1* 生成矩形以标记在测试图像中找到的匹配区域gen_rectangle2 (Rectangle1, Row[Index-1], Column[Index-1], Angle[Index-1], width/2, height/2)* 显示矩形dev_display (Rectangle1)endfor* 清除NCC模板,释放内存clear_ncc_model (ModelID)
endif



8、总结

  NCC模板匹配是一种基于统计相关性的方法。通过计算模板与测试图像对应区域的相关系数,能够准确地定位目标位置。由于NCC对亮度变化具有较强的鲁棒性,因此特别适合在光照条件变化或图像噪声较大的环境下使用。本文通过Halcon代码演示了如何实现高效的图像匹配。

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

OpenCV高级图形用户界面(10)创建一个新的窗口函数namedWindow()的使用

操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 算法描述 创建一个窗口。 函数 namedWindow 创建一个可以作为图像和跟踪条占位符的窗口。创建的窗口通过它们的名字来引用。 如果已经存在同名的窗口&am…

应用层协议 序列化

自定义应用层协议 例子:网络版本计算器 序列化反序列化 序列化:将消息,昵称,日期整合成消息-昵称-日期 反序列化:消息-昵称-日期->消息,昵称,日期 在序列化中,定义一个结构体…

第8篇:网络安全基础

目录 引言 8.1 网络安全的基本概念 8.2 网络威胁与攻击类型 8.3 密码学的基本思想与加密算法 8.4 消息认证与数字签名 8.5 网络安全技术与协议 8.6 总结 第8篇:网络安全基础 引言 在现代信息社会中,计算机网络无处不在,从互联网到局…

C语言_指针_进阶

引言:在前面的c语言_指针初阶上,我们了解了简单的指针类型以及使用,下面我们将进入更深层次的指针学习,对指针的理解会有一个极大的提升。从此以后,指针将不再是难点,而是学习底层语言的一把利器。 本章重点…

Mysql(2)—SQL语法详解(通俗易懂)

一、关于SQL 1.1 简介 SQL(Structured Query Language,结构化查询语言)是一种用于管理关系型数据库的标准编程语言。它主要用于数据的查询、插入、更新和删除等操作。SQL最初在1970年代由IBM的研究人员开发,旨在处理关系数据模型…

API的力量:解决编程技术问题的利器

在软件开发的世界里,编程技术问题无处不在。从数据获取到用户认证,从支付处理到地图服务,这些问题的解决方案往往需要深厚的专业知识和大量的开发时间。然而,应用程序编程接口(API)的出现,为开发…

长序列时间序列预测模型:Informer与TimesNet

Informer超越长序列时间序列预测 Informer是一种针对长序列时间序列预测的高效Transformer模型,旨在解决传统Transformer在处理长序列时的局限性。该模型引入了一些关键技术,以提高效率和准确性。以下是对Informer模型的详细介绍: 1. 模型背…

CMOS晶体管的串联与并联

CMOS晶体管的串联与并联 前言 对于mos管的串联和并联,一直没有整明白,特别是设计到EDA软件中,关于MOS的M和F参数,就更困惑了,今天看了许多资料以及在EDA软件上验证了电路结构与版图的对应关系,总算有点收…

opencv 图像翻转- python 实现

在做图像数据增强时会经常用到图像翻转操作 flip。 具体代码实现如下: #-*-coding:utf-8-*- # date:2021-03 # Author: DataBall - XIAN # Function: 图像翻转import cv2 # 导入OpenCV库path test.jpgimg cv2.imread(path)# 读取图片 cv2.namedWindow(image,1) …

go压缩的使用

基础:使用go创建一个zip func base(path string) {// 创建 zip 文件zipFile, err : os.Create("test.zip")if err ! nil {panic(err)}defer zipFile.Close()// 创建一个新的 *Writer 对象zipWriter : zip.NewWriter(zipFile)defer zipWriter.Close()// 创…

D39【python 接口自动化学习】- python基础之函数

day39 函数的返回值 学习日期:20241016 学习目标:函数﹣-52 函数的返回值:如何得到函数的执行结果? 学习笔记: return语句 返回值类型 def foo():return abc var foo() print(var) #abc# 函数中return函…

pc轨迹回放制作

亲爱的小伙伴,在您浏览之前,烦请关注一下,在此深表感谢! 课程主题:pc轨迹回放制作 主要内容:制作车辆轨迹操作页,包括查询条件、动态轨迹回放、车辆轨迹详情表单等 应用场景:车辆…

微软的 Drasi:一种轻量级的事件驱动编程方法

微软的开源数据变化处理平台有望提供一种全新的方式来构建和管理可产生持续事件流的云应用程序。 Microsoft Azure 孵化团队是微软超大规模云中比较有趣的组成部分之一。它介于传统软件开发团队和研究组织之间,致力于构建大规模分布式系统问题的解决方案。 这些解决…

普通java web项目集成spring-session

之前的老项目,希望使用spring-session管理会话,存储到redis。 项目环境:eclipse、jdk8、jetty嵌入式启动、非spring项目。 实现思路: 1.添加相关依赖jar。 2.配置redis连接。 3.配置启动spring。 4.配置过滤器,拦…

gaussdb 主备 8 数据库安全学习

1 用户及权限 1.1 默认权限机制-未开启三权分立 1.1.1 数据库系统管理员具有与对象所有者相同的权限。也就是说对象创建后,默认只有对象所有者或者系统管理员可以查询、修改和销毁对象,以及通过GRANT将对象的权限授予其他用户。 1.1.2 GaussDB支持以下的…

【C51】单片机与LED数码管的静态显示接口案例分析

目录 ---案例需求--- 1、电路设计 2、程序 3、元器件清单 4、程序仿真 LED数码管有静态显示和动态显示两种显示方式。静态显示是指无论有多少位LE数码管,其都同处于显示状态。数码管工作于静态显示方式时,各位的共阴极(或共阳极&#xf…

“网络协议入门:HTTP通信的四大组成部分“

White graces:个人主页 🙉专栏推荐:Java入门知识🙉 🐹今日诗词: 春水满四泽,夏云多奇峰🐹 ⛳️点赞 ☀️收藏⭐️关注💬卑微小博主🙏 ⛳️点赞 ☀️收藏⭐️关注💬卑微…

USART串口(发送和接收)

目录 一. USART串口协议 二. USART串口外设 三. 串口发送接收 四. 效果展示 一. USART串口协议 USART(Universal Synchronous/Asynchronous Receiver/Transmitter)通用同步/异步收发器。 通信的目的:将一个设备的数据传送到另一个设备,扩展硬件系统。…

端点物联网学习资源合集

端点物联网 学习资源合集 导航 1. 物联网实战--入门篇 文章链接 简介:物联网是一个包罗万象的行业和方向,知识碎片严重,本系列文章通过 边学边用 的思想,逐步建立学习者的信心和兴趣,从而进行更深入透彻的学习和探索…

kaptcha依赖maven无法拉取的问题

老依赖了,就是无法拉取,也不知道为什么,就是用maven一直拉去不成功,还以为是魔法的原因,试了好久发现不是,只好在百度寻求帮助了,好在寻找到了这位大佬的文章Maven - 解决无法安装 Kaptcha 依赖…