热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

基于halcon的特征匹配实例

特征匹配原图模板识别图代码结果原图模板识别图代码*这个例子在图片数据库中查找文章的页面。*第一步是训练不同的页面并创建模型。*然后搜索未知图像并检测出正确的文章页面。*请注意&


特征匹配

  • 原图
    • 模板
    • 识别图
  • 代码
  • 结果


原图


模板

在这里插入图片描述
在这里插入图片描述


识别图

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述


代码

*这个例子在图片数据库中查找文章的页面。*第一步是训练不同的页面并创建模型。*然后搜索未知图像并检测出正确的文章页面。*请注意,这个例子需要一些内存来训练模型。
dev_update_off ()
dev_close_window ()
read_image (Image, 'book/1')
get_image_size (Image, Width, Height)
dev_open_window_fit_image (Image, 0, 0, -1, -1, WindowHandle)
set_display_font (WindowHandle, 14, 'mono', 'true', 'false')
dev_set_draw ('margin')
dev_display (Image)
*定义需要使用变量
ModelIDs := []
ModelsFound := 0
NumPoints := []
NumModels := 2
TotalTime := 0
*
* Create region for visualization purpose.
*生成需要处理区域矩形
RowRoi := [10,10,Height - 10,Height - 10]
ColRoi := [10,Width - 10,Width - 10,10]
gen_rectangle1 (Rectangle, 10, 10, Height - 10, Width - 10)
disp_message (WindowHandle, ['Press \'Run\' to start model creation ...','(may take a few minutes)'], 'window', 10, 10, 'black', 'true')
disp_continue_message (WindowHandle, 'black', 'true')
stop ()
*
* For every page the descriptor model is created.
for Index := 1 to NumModels by 1read_image (Image, 'book/' + Index)rgb1_to_gray (Image, ImageGray)get_image_size (ImageGray, Width, Height)*截取需要处理的区域reduce_domain (ImageGray, Rectangle, ImageReduced)dev_clear_window ()dev_display (ImageGray)disp_message (WindowHandle, 'Creating model no. ' + Index + '/' + NumModels + ' ... please wait.', 'window', 10, 10, 'black', 'true')* * Create the descriptor model with default parameters (except scaling)* For a fast detection, the harris binomial point detector is chosen.*运算符create_uncalib_descriptor_model准备图像区域的描述符模型,该模型在图像模板中传递,可用于基于描述符的匹配。*通过随后调用find_uncalib_descriptor_model,可以获得从模板到搜索图像的投影2D变换(单应性)。*模板中区域的重心作为模型的原点。与create_calib_descriptor_model相比,不需要校准相机,因此后续匹配的结果是2D投影。*请注意,在模板图像中可见的对象部分必须是平面的。*create_uncalib_descriptor_model(Template : : DetectorType, DetectorParamName, DetectorParamValue,* DescriptorParamName, DescriptorParamValue, Seed : ModelID)*描述符模型描述了一组感兴趣的点。它存储了它们的位置和对其局部灰度邻域的区分性描述。*兴趣点提取由DetectorType、DetectorParamName和DetectorParamValue参数化。*兴趣点周围的相应描述符由DescriptorParamName和DescriptorParamValue参数化。*Seed种子随机数生成器,在构造描述符时使用。*返回的ModelID是对生成的描述符模型的引用。该模型可以有效地检测学习模板的实例,并允许模型和搜索图像之间的透视变换。*由于基于描述子的匹配依赖于稳定的、有区别的兴趣点的存在,因此需要对待检测对象进行纹理化处理,但不能重复。** Detector parameters*如前所述,检测器用于提取图像中稳定的兴趣点。通过参数DetectorType,可以选择要使用的兴趣点运算符。*目前,支持points_lepetit、points_harris及其二项近似点points_harris_binordinary('lepetit','harris','harris_binormal')。*对于低对比度的模板或搜索图像,应使用harris点运算符之一。*根据所选的DetectorType,可以在DetectorParamName和DetectorParamValue中设置适当的参数名称和值。*DetectorParamName的可能参数名称和相应的默认值为:* 'lepetit':* ['radius','check_neighbor', 'min_check_neighbor_diff','min_score','subpix']*[3, 1, 15, 30, 'interpolation']*'harris':*['sigma_grad','sigma_smooth','alpha', 'threshold']*[ 0.7, 2.0, 0.08, 1000]*'harris_binomial':*['mask_size_grd','mask_size_smooth', 'alpha','threshold','subpix']*[ 5, 15, 0.08, 1000, 'on']*Descriptor parameters 描述符参数*有关这些参数含义的更多详细信息,请分别在points_harris、points_harris_binordinary和points_lepetit中找到。*如果传递了空元组或DetectorParamName中未提供参数,则采用上述默认值。*在调整算子参数的同时,应针对性地提取一组50450个特征点(取决于模板的纹理和大小),这些特征点均匀分布在模板的ROI上。*因此,建议事先运行所选的点运算符,并通过gen_cross_contour_xld可视化结果。在大多数情况下,使用默认设置就足够了。*点描述子是一种分类器,它为兴趣点建立灰度邻域的特征描述。*目前,描述符是用所谓的随机化蕨类植物来实现的,它可以学习在兴趣点周围区域的随机位置确定的成对像素的灰度差的极性。*在该模型中寻找匹配点(find_uncalib_descriptor_model)的特征点。*描述符只需要存储投射稳定的兴趣点(这些兴趣点将出现在模板的许多投影视图中)。*为了评估兴趣点的稳定性,我们进行了一个模拟:模板经过多次仿射变换,在大多数视图中可以提取的点被认为是稳定的。*仿射变换是兴趣点局部邻域内射影变换的一个很好的近似。*可以使用DescriptorParamName和DescriptorParamValue设置以下描述符参数:***描述符大小参数:*'depth': *分类蕨类植物的深度。更深入的随机蕨类植物可以更好地区分兴趣点。然而,蕨类植物的内存需求增长了2倍,达到了“深度”的幂次。典型值为[5。。11] ,默认值为11*'number_ferns': *所用蕨类植物结构的数量。使用更多的蕨类植物提高了识别的鲁棒性,但也增加了匹配的运行时间。如果描述符所需的内存应该很小,则应使用许多深度较小的蕨类植物(例如,“number_ferns”=150,“depth”=5)*如果探测速度更为重要,则应使用较少深度较大的蕨类植物(例如,“数量蕨类”=10,“深度”=11)。典型值为[1。。150],默认值为30*'patch_size': *描述兴趣点的二次邻域的边长。此参数的值太大会影响运行时。典型值为[15。。33],默认值为17* 总之,参数'depth''number_ferns''patch_size'允许对检测鲁棒性、速度和内存消耗进行透明控制。****Simulation parameters:*'tilt':*在模拟阶段打开或关闭投影变换。当开关打开时,模型的鲁棒性得到了提高,并且可以发现倾斜较大的物体。当关闭时,训练时间可以大大减少,并且模型仍然能够识别射影不变的物体。*可能的值为['on''off'],默认值为'on'*'min_rot':*围绕模板法向量的最小旋转角度。典型值为[-180。。0],默认值为-180*'max_rot':*模板法向量的最大旋转角。典型值为[0。。180],默认值为180*'min_scale':*模板的最小比例。典型值为[0.1。。1.0],默认值为0.5*'max_scale':*模板的最大尺度。典型值为[1.0。。3.5],默认值为1.4**参数“min_rot”、“max_rot”、“min_scale”和“max_scale”允许手动设置模板的哪些仿射变换视图用于训练描述符。*设置这些参数有助于减少训练时间,尤其是与“倾斜”参数结合使用时。*请注意,这些参数对find_uncalib_descriptor_model的结果有直接影响,因此必须谨慎设置。*例如,如果旋转范围被限制在“min_rot”=-10到“max_rot”=10,则无法找到旋转角度超出该范围的模板视图。*有限的训练范围需要较少的蕨类植物/蕨类植物的深度来找到模板。*在这种情况下,蕨类植物的数量和深度可以进一步减少,从而优化了模型。count_seconds (Seconds1)*1、生成图像区域的描述符模型create_uncalib_descriptor_model (ImageReduced, 'harris_binomial', [], [], ['min_rot','max_rot','min_scale','max_scale'], [-90,90,0.2,1.1], 30, ModelID)count_seconds (Seconds2)TotalTime := TotalTime + (Seconds2 - Seconds1)* * For the correct projection of the rectangles in a later step the origin* of the model has to be set to the image origin***set_descriptor_model_origin( : : ModelID, Row, Column : )*为descriptor 模型设置原点(参照点)*描述:参照点 通常和创建模型时候(create_uncalib_descriptor_model, orcreate_calib_descriptor_model)使用的region输入的重力中心点相关,参数的设定即表示相对于重力中心点的位移,eg:一个原点是(-20,-10)表示这个原点在重力中心点的左上角。* 在设定了参照点之后,使用find_uncalib_descriptor_modeland find_calib_descriptor_model来搜索模型的形态和转换信息 *注意:这里设置的参照点是属于模型的一部分,是模型的一个属性/*ModelIDs :=[ModelIDs, ModelID] 把生成的modelID存入数组*2、设置模型原点set_descriptor_model_origin (ModelID, -Height / 2, -Width / 2)ModelIDs := [ModelIDs,ModelID]* * Store the points which are extracted from the model for later matching.*存储生成的模型中的兴趣点*/get_descriptor_model_points( : : ModelID, Set, Subset : Row, Column)*Set可以控制是取出模型中的兴趣点还是上一次搜索的图片中的兴趣点,*subset表示取出几个点,默认为‘all'(这里用all也会比较慢,可以考虑选取其他数值),后两个参数是输出,保存了这些点的信息。*Subset : 每个如果是搜索的话,每个正确的匹配的兴趣点是所有兴趣点的一个子集 *3、获取模型中的兴趣点get_descriptor_model_points (ModelID, 'model', 'all', Row_D, Col_D)NumPoints := [NumPoints,|Row_D|]write_descriptor_model (ModelID, Index+'.dsm')
endfor
*
* Model creation finished.
dev_display (ImageGray)
disp_message (WindowHandle, NumModels + ' models created in ' + TotalTime$'.4' + ' seconds.', 'window', 10, 10, 'black', 'true')
disp_continue_message (WindowHandle, 'black', 'true')
stop ()read_image (Image, 'book/1')
*再次初始化窗口,因为图像大小已更改。
dev_resize_window_fit_image (Image, 0, 0, -1, -1)
set_display_font (WindowHandle, 14, 'mono', 'true', 'false')
*
* Main loop:
* Search the models in all images
*6张图进行遍历,找出图中对应的匹配项
for Index1 :&#61; 1 to 6 by 1OutputString :&#61; []NumMsgs :&#61; 0ModelsFound :&#61; 0TotalTime :&#61; 0read_image (Image, &#39;book/&#39; &#43; Index1)rgb1_to_gray (Image, ImageGray)dev_display (Image)disp_message (WindowHandle, &#39;Searching image ...&#39;, &#39;window&#39;, 10, 10, &#39;black&#39;, &#39;true&#39;)* * Search every model in each image*对每张图像进行所有模型的遍历搜索for Index2 :&#61; 0 to |ModelIDs| - 1 by 1read_descriptor_model ((Index2&#43;1)&#43;&#39;.dsm&#39; ,ModelID1)ModelIDs[Index2] :&#61; ModelID1* * Find model (using default parameters)count_seconds (Seconds1)*4、在图像中查找描述符模型的最佳匹配项。find_uncalib_descriptor_model (ImageGray, ModelIDs[Index2], [], [], [&#39;min_score_descr&#39;,&#39;guided_matching&#39;], [0.003,&#39;on&#39;], 0.25, 1, &#39;num_points&#39;, HomMat2D, Score)*** find_uncalib_descriptor_model(Image : : ModelID, DetectorParamName, DetectorParamValue, * DescriptorParamName, DescriptorParamValue, MinScore, NumMatches, ScoreType * : HomMat2D, Score)*描述&#xff1a;寻找描述模型&#xff0c;DetectorParamName和DescriptorParamName应该与创建模型时候相同。*MinScore&#xff1a;当Score超过MinScore时候&#xff0c;这个匹配才被接受。*对于每一个接受的匹配&#xff0c;都会产生一个3x3的矩阵HomMat2D用来描述转换。*当一张图片中有多个匹配被接受的时候&#xff0c;单应性转换矩阵会串行的保存在tuple中。* &#xff08;应该是很多3x3矩阵串行保存&#xff09;匹配的个数等于NumOfMatch &#61;|HomMat2D|/9*NumMatches&#xff1a;用来限制匹配的个数&#xff0c;最多有几个&#xff0c;选择最优的*ScoreType: 可以选择匹配的点的个数或者是相关点的半径两种来表示匹配的优劣程度*所以&#xff0c;这里的Score并不是一个01的值&#xff0c;而是一个可能比较大的整数count_seconds (Seconds2)*单个模型搜索花费时间Time :&#61; Seconds2 - Seconds1*所有模型搜索花费时间TotalTime :&#61; TotalTime &#43; Time* * Check if the found instance is to be considered as a possible right match* depending on the number of points which were consideredif ((|HomMat2D| > 0) and (Score > NumPoints[Index2] / 4))*5、获取描述点坐标get_descriptor_model_points (ModelIDs[Index2], &#39;search&#39;, 0, Row, Col)gen_cross_contour_xld (Cross, Row, Col, 6, 0.785398)* * Project the ROI rectangle and points*6、投影变换ROI区域及边界点投影projective_trans_region (Rectangle, TransRegion, HomMat2D, &#39;bilinear&#39;)projective_trans_pixel (HomMat2D, RowRoi, ColRoi, RowTrans, ColTrans)*7、根据边界点求夹角angle_ll (RowTrans[2], ColTrans[2], RowTrans[1], ColTrans[1], RowTrans[1], ColTrans[1], RowTrans[0], ColTrans[0], Angle)*8、夹角转换为角度值Angle :&#61; deg(Angle)* * Check if the projected rectangle is to be considered as a right match* depending on the angle in the right upper edge.*9、根据夹角角度值范围筛选 并显示结果if (Angle > 70 and Angle < 110)area_center (TransRegion, Area, Row, Column)ModelsFound :&#61; ModelsFound &#43; 1dev_set_color (&#39;green&#39;)dev_set_line_width (4)dev_display (TransRegion)dev_set_colored (12)dev_set_line_width (1)dev_display (Cross)disp_message (WindowHandle, &#39;Page &#39; &#43; (Index2 &#43; 1), &#39;window&#39;, Row, Column, &#39;black&#39;, &#39;true&#39;)OutputString :&#61; [OutputString,&#39;Page &#39; &#43; (Index2 &#43; 1) &#43; &#39; found in &#39; &#43; (Time * 1000)$&#39;.4&#39; &#43; &#39; ms\n&#39;]endifendifendforif (ModelsFound &#61;&#61; 0)OutputString :&#61; &#39;No model found&#39;endifNumMsgs :&#61; NumMsgs &#43; 1OutputString :&#61; [&#39;Search time over all pages: &#39; &#43; (TotalTime * 1000)$&#39;.4&#39; &#43; &#39; ms&#39;,OutputString]disp_message (WindowHandle, OutputString, &#39;window&#39;, 10, 10, &#39;black&#39;, &#39;true&#39;)disp_continue_message (WindowHandle, &#39;black&#39;, &#39;true&#39;)stop ()
endfor
dev_display (ImageGray)
disp_message (WindowHandle, &#39;Program finished.\nPress \&#39;Run\&#39; to clear all descriptor models.&#39;, &#39;window&#39;, 10, 10, &#39;black&#39;, &#39;true&#39;)
for i :&#61; 0 to |ModelIDs|-1 by 1*10、清楚模型clear_descriptor_model (ModelIDs[i])
endfor

结果

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述


推荐阅读
  • 带添加按钮的GridView,item的删除事件
    先上图片效果;gridView无数据时显示添加按钮,有数据时,第一格显示添加按钮,后面显示数据:布局文件:addr_manage.xml<?xmlve ... [详细]
  • Java太阳系小游戏分析和源码详解
    本文介绍了一个基于Java的太阳系小游戏的分析和源码详解。通过对面向对象的知识的学习和实践,作者实现了太阳系各行星绕太阳转的效果。文章详细介绍了游戏的设计思路和源码结构,包括工具类、常量、图片加载、面板等。通过这个小游戏的制作,读者可以巩固和应用所学的知识,如类的继承、方法的重载与重写、多态和封装等。 ... [详细]
  • 1、工具VS2015OpenCV3.20下载地址:https:sourceforge.netprojectsopencvlibrary2、步骤1.下载工具ÿ ... [详细]
  • 本文介绍了在Mac上搭建php环境后无法使用localhost连接mysql的问题,并通过将localhost替换为127.0.0.1或本机IP解决了该问题。文章解释了localhost和127.0.0.1的区别,指出了使用socket方式连接导致连接失败的原因。此外,还提供了相关链接供读者深入了解。 ... [详细]
  • d3dx9_26.dll极品飞车9修复工具下载及修复教程
    本文介绍了d3dx9_26.dll文件的修复工具下载和修复教程,解释了该dll文件的作用和安装方法,同时提供了其他dll文件下载安装的方法。文章涵盖了3d、windows、p2p、dll、visual studio等知识点,并由未来可期1212投稿。希望该技术和经验能帮到你解决dll文件相关技术问题。 ... [详细]
  • 本文详细介绍了Java中vector的使用方法和相关知识,包括vector类的功能、构造方法和使用注意事项。通过使用vector类,可以方便地实现动态数组的功能,并且可以随意插入不同类型的对象,进行查找、插入和删除操作。这篇文章对于需要频繁进行查找、插入和删除操作的情况下,使用vector类是一个很好的选择。 ... [详细]
  • Java学习笔记之面向对象编程(OOP)
    本文介绍了Java学习笔记中的面向对象编程(OOP)内容,包括OOP的三大特性(封装、继承、多态)和五大原则(单一职责原则、开放封闭原则、里式替换原则、依赖倒置原则)。通过学习OOP,可以提高代码复用性、拓展性和安全性。 ... [详细]
  • Android开发实现的计时器功能示例
    本文分享了Android开发实现的计时器功能示例,包括效果图、布局和按钮的使用。通过使用Chronometer控件,可以实现计时器功能。该示例适用于Android平台,供开发者参考。 ... [详细]
  • Go Cobra命令行工具入门教程
    本文介绍了Go语言实现的命令行工具Cobra的基本概念、安装方法和入门实践。Cobra被广泛应用于各种项目中,如Kubernetes、Hugo和Github CLI等。通过使用Cobra,我们可以快速创建命令行工具,适用于写测试脚本和各种服务的Admin CLI。文章还通过一个简单的demo演示了Cobra的使用方法。 ... [详细]
  • Python爬虫中使用正则表达式的方法和注意事项
    本文介绍了在Python爬虫中使用正则表达式的方法和注意事项。首先解释了爬虫的四个主要步骤,并强调了正则表达式在数据处理中的重要性。然后详细介绍了正则表达式的概念和用法,包括检索、替换和过滤文本的功能。同时提到了re模块是Python内置的用于处理正则表达式的模块,并给出了使用正则表达式时需要注意的特殊字符转义和原始字符串的用法。通过本文的学习,读者可以掌握在Python爬虫中使用正则表达式的技巧和方法。 ... [详细]
  • 使用圣杯布局模式实现网站首页的内容布局
    本文介绍了使用圣杯布局模式实现网站首页的内容布局的方法,包括HTML部分代码和实例。同时还提供了公司新闻、最新产品、关于我们、联系我们等页面的布局示例。商品展示区包括了车里子和农家生态土鸡蛋等产品的价格信息。 ... [详细]
  • 本文详细介绍了使用C#实现Word模版打印的方案。包括添加COM引用、新建Word操作类、开启Word进程、加载模版文件等步骤。通过该方案可以实现C#对Word文档的打印功能。 ... [详细]
  • 本文介绍了一种求解最小权匹配问题的方法,使用了拆点和KM算法。通过将机器拆成多个点,表示加工的顺序,然后使用KM算法求解最小权匹配,得到最优解。文章给出了具体的代码实现,并提供了一篇题解作为参考。 ... [详细]
  • 点击上方“新机器视觉”,选择加”星标”或“置顶”重磅干货,第一时间送达很早就想总结一下前段时间学习HALCON的心得,但由于其他的事情总是抽不出时间。去年有过一段时间的集中学习,做 ... [详细]
  • 完成字符串和时间对象的转化(DateFormat)、(以及日历Calendar用法)
    DateFormat 和SimpleDateFormat示例(时间格式的书写)packagecn.date;importjava.text.DateFormat;importjav ... [详细]
author-avatar
我心永恒2602922374_902
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有