热门标签 | 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

结果

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


推荐阅读
  • Python正则表达式学习记录及常用方法
    本文记录了学习Python正则表达式的过程,介绍了re模块的常用方法re.search,并解释了rawstring的作用。正则表达式是一种方便检查字符串匹配模式的工具,通过本文的学习可以掌握Python中使用正则表达式的基本方法。 ... [详细]
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • 在Android开发中,使用Picasso库可以实现对网络图片的等比例缩放。本文介绍了使用Picasso库进行图片缩放的方法,并提供了具体的代码实现。通过获取图片的宽高,计算目标宽度和高度,并创建新图实现等比例缩放。 ... [详细]
  • 本文主要解析了Open judge C16H问题中涉及到的Magical Balls的快速幂和逆元算法,并给出了问题的解析和解决方法。详细介绍了问题的背景和规则,并给出了相应的算法解析和实现步骤。通过本文的解析,读者可以更好地理解和解决Open judge C16H问题中的Magical Balls部分。 ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • Python爬虫中使用正则表达式的方法和注意事项
    本文介绍了在Python爬虫中使用正则表达式的方法和注意事项。首先解释了爬虫的四个主要步骤,并强调了正则表达式在数据处理中的重要性。然后详细介绍了正则表达式的概念和用法,包括检索、替换和过滤文本的功能。同时提到了re模块是Python内置的用于处理正则表达式的模块,并给出了使用正则表达式时需要注意的特殊字符转义和原始字符串的用法。通过本文的学习,读者可以掌握在Python爬虫中使用正则表达式的技巧和方法。 ... [详细]
  • Commit1ced2a7433ea8937a1b260ea65d708f32ca7c95eintroduceda+Clonetraitboundtom ... [详细]
  • android listview OnItemClickListener失效原因
    最近在做listview时发现OnItemClickListener失效的问题,经过查找发现是因为button的原因。不仅listitem中存在button会影响OnItemClickListener事件的失效,还会导致单击后listview每个item的背景改变,使得item中的所有有关焦点的事件都失效。本文给出了一个范例来说明这种情况,并提供了解决方法。 ... [详细]
  • Java容器中的compareto方法排序原理解析
    本文从源码解析Java容器中的compareto方法的排序原理,讲解了在使用数组存储数据时的限制以及存储效率的问题。同时提到了Redis的五大数据结构和list、set等知识点,回忆了作者大学时代的Java学习经历。文章以作者做的思维导图作为目录,展示了整个讲解过程。 ... [详细]
  • 阿,里,云,物,联网,net,core,客户端,czgl,aliiotclient, ... [详细]
  • JavaSE笔试题-接口、抽象类、多态等问题解答
    本文解答了JavaSE笔试题中关于接口、抽象类、多态等问题。包括Math类的取整数方法、接口是否可继承、抽象类是否可实现接口、抽象类是否可继承具体类、抽象类中是否可以有静态main方法等问题。同时介绍了面向对象的特征,以及Java中实现多态的机制。 ... [详细]
  • Spring特性实现接口多类的动态调用详解
    本文详细介绍了如何使用Spring特性实现接口多类的动态调用。通过对Spring IoC容器的基础类BeanFactory和ApplicationContext的介绍,以及getBeansOfType方法的应用,解决了在实际工作中遇到的接口及多个实现类的问题。同时,文章还提到了SPI使用的不便之处,并介绍了借助ApplicationContext实现需求的方法。阅读本文,你将了解到Spring特性的实现原理和实际应用方式。 ... [详细]
  • 本文详细介绍了在ASP.NET中获取插入记录的ID的几种方法,包括使用SCOPE_IDENTITY()和IDENT_CURRENT()函数,以及通过ExecuteReader方法执行SQL语句获取ID的步骤。同时,还提供了使用这些方法的示例代码和注意事项。对于需要获取表中最后一个插入操作所产生的ID或马上使用刚插入的新记录ID的开发者来说,本文提供了一些有用的技巧和建议。 ... [详细]
  • IjustinheritedsomewebpageswhichusesMooTools.IneverusedMooTools.NowIneedtoaddsomef ... [详细]
  • iOS Swift中如何实现自动登录?
    本文介绍了在iOS Swift中如何实现自动登录的方法,包括使用故事板、SWRevealViewController等技术,以及解决用户注销后重新登录自动跳转到主页的问题。 ... [详细]
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社区 版权所有