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

结果

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


推荐阅读
  • HBase Java API 进阶:过滤器详解与应用实例
    本文详细探讨了HBase 1.2.6版本中Java API的高级应用,重点介绍了过滤器的使用方法和实际案例。首先,文章对几种常见的HBase过滤器进行了概述,包括列前缀过滤器(ColumnPrefixFilter)和时间戳过滤器(TimestampsFilter)。此外,还详细讲解了分页过滤器(PageFilter)的实现原理及其在大数据查询中的应用场景。通过具体的代码示例,读者可以更好地理解和掌握这些过滤器的使用技巧,从而提高数据处理的效率和灵活性。 ... [详细]
  • 在C#中开发MP3播放器时,我正在考虑如何高效存储元数据以便快速检索。选择合适的数据结构,如字典或数组,对于优化性能至关重要。字典能够提供快速的键值对查找,而数组则在连续存储和遍历方面表现优异。根据具体需求,合理选择数据结构将显著提升应用的响应速度和用户体验。 ... [详细]
  • 如何高效启动大数据应用之旅?
    在前一篇文章中,我探讨了大数据的定义及其与数据挖掘的区别。本文将重点介绍如何高效启动大数据应用项目,涵盖关键步骤和最佳实践,帮助读者快速踏上大数据之旅。 ... [详细]
  • 在PHP的设计中,预定义了9个超级全局变量、8个魔术变量和13个魔术函数,这些变量和函数无需声明即可在脚本的任意位置使用。这些特性在PHP开发中极为常见,能够显著提升开发效率和代码的灵活性。相比之下,Java并没有类似的内置机制,但通过其他方式如上下文对象和反射机制,也可以实现类似的功能。本文将详细探讨这两种语言中这些特殊变量和函数的使用方法及其应用场景。 ... [详细]
  • 《精通 jQuery》第六章:深入解析与实战应用
    《精通 jQuery》第六章:深入解析与实战应用本章详细探讨了 Ajax 技术的核心机制及其实际应用。Ajax 通过 XMLHttpRequest 对象实现客户端与服务器之间的异步数据交换,从而在不重新加载整个页面的情况下更新部分内容。这种技术不仅提升了用户体验,还提高了应用的响应速度和效率。此外,本章还介绍了如何利用 jQuery 简化 Ajax 操作,并提供了多个实战案例,帮助读者更好地理解和掌握这一重要技术。 ... [详细]
  • MongoDB Aggregates.group() 方法详解与编程实例 ... [详细]
  • PHP中函数名、常量名和变量名大小写转换及规范详解
    在PHP编程中,初学者常常会遇到关于函数名、常量名和变量名大小写的问题。本文详细解析了PHP中这些名称的大小写敏感性及其命名规范,帮助开发者更好地理解和使用PHP。具体而言,文章探讨了PHP中的常量名是否区分大小写,自定义函数名的大小写敏感性,以及类名的大小写规则。此外,还提供了实用的代码示例和最佳实践,以确保代码的可读性和一致性。 ... [详细]
  • 本文深入解析了 JavaScript 中字符串截取的多种方法,并通过实例详细介绍了 `substring()` 和 `slice()` 函数的使用技巧。这些方法在实际开发中非常实用,能够帮助开发者高效地处理字符串数据。此外,文章还探讨了其他相关函数如 `substr()` 的应用场景,为读者提供了全面的参考。 ... [详细]
  • Java 模式原型在游戏服务器架构中的应用与优化 ... [详细]
  • 在循环读取文本文件时,经常会遇到一些常见的错误,如日期格式不正确、文件路径错误等。本文详细分析了这些问题,并提供了具体的解决方法,包括如何正确处理日期字符串和确保文件路径的准确性。通过这些方法,可以有效提高数据读取的稳定性和可靠性。 ... [详细]
  • 利用Java开发功能完备的电话簿应用程序,支持添加、查询与删除操作
    本研究基于Java语言开发了一款功能全面的电话簿应用程序,实现了与数据库的高效连接。该应用不仅支持添加、查询和删除联系人信息,还具备输出最大和最小ID号的功能,并能够对用户输入的ID号进行有效性验证,确保数据的准确性和完整性。详细实现方法可参阅相关文档。 ... [详细]
  • 循环结构与零钱问题:多题型综合解析与应用
    循环结构与零钱问题:多题型综合解析与应用 ... [详细]
  • 本文深入探讨了在使用 Spring Cloud Feign 时遇到的 `java.lang.IllegalStateException` 异常,具体表现为方法体参数过多的问题。通过详细分析异常原因和代码结构,提出了有效的解决方案,帮助开发者更好地理解和处理这一常见问题。 ... [详细]
  • 深入解析 Vue.js 的设计与实现:第三章详解
    在《深入解析 Vue.js 的设计与实现》第三章中,详细探讨了 Vue.js 渲染器与虚拟 DOM 的机制。通过 JavaScript 对象来模拟实际的 DOM 结构,例如,`const vNode = { tag: 'div', props: { ... } }`,这种方式不仅提高了性能,还增强了组件的可维护性和灵活性。本章进一步分析了虚拟 DOM 的创建、更新及优化策略,为开发者提供了深入了解 Vue.js 内核工作的视角。 ... [详细]
  • 优化后的标题:PHP分布式高并发秒杀系统设计与实现
    PHPSeckill是一个基于PHP、Lua和Redis构建的高效分布式秒杀系统。该项目利用php_apcu扩展优化性能,实现了高并发环境下的秒杀功能。系统设计充分考虑了分布式架构的可扩展性和稳定性,适用于大规模用户同时访问的场景。项目代码已开源,可在Gitee平台上获取。 ... [详细]
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社区 版权所有