ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

Halcon圆形查找从原理到实战的完整指南

Halcon圆形查找从原理到实战的完整指南 做机器视觉项目的人十个里有八个都绕不过“halcon 查找圆形”这道坎。定位螺丝孔、检测药瓶瓶口、测量轴承外圈、找芯片上的焊盘点说白了都是在跟圆打交道。Halcon在这块的优势不用我多吹工业界用了这么多年稳定性和精度都是被验证过的。这篇东西我就拿实际项目里的经验把圆形查找从原理到算子选型、从代码到调试排错完完整整捋一遍。不管你是刚接触Halcon的新手还是已经在用但总被边缘、阈值折腾得头疼的工程师这篇文章应该都能给你些实在的东西。1. 从需求到方案圆形查找的两种典型路径1.1 先想清楚你要找什么样的圆很多人拿到图就急着调算子这是最容易翻车的做法。圆形查找这件事第一步不是写代码而是把需求问清楚你要找的是完整的圆还是圆弧圆的亮度跟背景相比是亮的还是暗的现场光照稳不稳定精度要求是像素级还是亚像素级这几个问题直接决定你后面选哪条技术路线。举个例子如果是一个完整的、边界清晰的圆形零件用边缘提取加圆拟合的经典流程就够了但如果圆的边缘有一部分被遮挡或者你只需要测量某个圆弧的半径那就得考虑基于轮廓的拟合方式再如果现场有很多个圆还要区分大小、筛选位置那通常要配合区域处理或者模板匹配来做。1.2 两条主流技术路线怎么选Halcon里查找圆形的手段归纳下来无非三类传统图像处理路线预处理 亚像素边缘提取edges_sub_pix 圆拟合fit_circle_contour_xld。灵活度高适合各种复杂情况但对参数调试经验有要求。测量模型路线用metrology测量模型create_metrology_model add_metrology_object_circle_measure。Halcon把边缘提取、拟合、输出结果封装成了一套流程内部细节可控性强适合测量精度要求高的场景。模板匹配路线先创建形状模板create_shape_model再在图像里找模板。适合圆的形状特征明显、目标在图像里相对完整的情况能找到圆心和角度但输出半径的精度不算它的强项。直接说结论做测量类项目优先考虑metrology模型做定位抓取类项目模板匹配更稳做复杂的异形圆检测或者圆弧拟合用边缘提取 拟合这条老路线最灵活。后面我会结合案例把前两条路线的代码写清楚因为这两条是实际项目里最常用的。2. 核心算子拆解从边缘提取到圆拟合的完整链路2.1 为什么图像预处理这一步不能跳过很多新手喜欢拿到图直接edges_sub_pix结果边缘出来一堆毛刺拟合出的圆半径忽大忽小这时候才想起预处理的重要性。Halcon里的预处理核心目标就两个降噪和增强对比度。降噪最常用的是中值滤波median_image和高斯滤波smooth_image。中值滤波对椒盐噪声特别有效而且能比较好地保留边缘的锐度高斯滤波平滑噪声的同时也会让边缘变钝所以用在圆形查找上我通常优先选中值滤波或者用很小的高斯核3x3、5x5。增强对比度这块常用的是灰度值拉伸算子。比如图像偏暗、对比度低的时候可以用scale_image_max直接把灰度范围拉伸到0到255会让边缘明显清晰很多。Halcon里关于灰度值拉伸的算子有好几个像scale_image、scale_image_max实际项目里先跑一下scale_image_max看效果如果还不行再用灰度直方图均衡化equ_histo_image来处理。注意预处理不是越狠越好。我见过有人把图反复滤波结果边缘被磨平了亚像素精度反而下降。原则是“够用就行”只要能稳定提取边缘处理步骤越少越好。2.2 亚像素边缘提取edges_sub_pix 到底做了什么edges_sub_pix是Halcon里最经典的亚像素边缘提取算子它基于Canny边缘检测算法但输出的是亚像素精度的轮廓XLD contour。它的核心逻辑分三步高斯滤波平滑、计算梯度幅值和方向、非极大值抑制加双阈值滞后连接。这里有个关键概念亚像素精度。普通像素级边缘精度只能到1个像素亚像素边缘通过灰度插值能把边缘定位精度做到0.1到0.5个像素。在工业测量场景一个像素对应的物理尺寸可能只有0.01毫米0.5像素的误差就是5微米这对精密检测来说就是天壤之别。edges_sub_pix的参数里最影响结果的是Sigma高斯平滑系数和阈值Low、High。Sigma越大边缘越平滑但定位精度越低阈值高低直接影响边缘的连续性。实际调试时我习惯先把Sigma设到1左右Low和High分别设成10和30然后看效果慢慢调。如果边缘出现大量断裂就把High往下降如果边缘粗糙、有毛刺就适当加大Sigma。2.3 圆拟合fit_circle_contour_xld 的数学原理与参数选择拿到亚像素边缘轮廓之后第二步就是拟合成圆。fit_circle_contour_xld支持多种拟合算法最常用的是“algebraic”和“geometric”。Geometric拟合基于最小二乘原理使轮廓上所有点到拟合圆的几何距离平方和最小精度最高但计算量稍大Algebraic拟合算得快但精度略逊。这里必须提一个非常关键的参数ClippingFactor。这个参数的本质是离群点剔除。实际图像里边缘轮廓上难免有一些噪声点或者不属于圆边界的干扰点如果不剔除拟合出来的圆会被这些点带偏。ClippingFactor默认值是2.0表示剔除距离超过中值误差2倍标准差的点。如果你发现拟合的圆明显偏离了实际边缘重点检查这个参数的设置。另外一个容易被忽略的点是MaxNumPoints参数。当轮廓点数量特别多时比如一万个点参与拟合的计算量会很大。我一般会限制参与拟合的点的最大数目比如设成1000既保证精度又加快速度。2.4 metrology测量模型为什么推荐用于高精度测量metrology模型的本质是把“在圆周围放置测量卡尺、提取边缘点、拟合圆、输出结果”这个流程封装起来。它的核心优势有两个一是测量区域可控二是参数调节直观。具体来说add_metrology_object_circle_measure会让你指定初始圆心和半径然后系统会在圆周方向等间距生成多个测量卡尺measure每个卡尺沿着法线方向搜索边缘点最后把这些边缘点拟合成精确的圆。测量卡尺的长度和宽度由MeasureLength1和MeasureLength2控制卡尺数量由NumMeasures控制边缘极性由MeasureSelect控制。用metrology模型做圆形查找最大的好处是抗干扰能力强。因为每个卡尺只在局部小范围内搜索边缘周围的干扰物不会影响整体拟合。而且它输出的是测量结果对象你可以用get_metrology_object_measures拿到每个卡尺提取到的边缘点可视化检查哪些点被算法接受、哪些被丢弃调试起来非常直观。这个特性在工业项目里特别实用因为客户永远会拿各种奇形怪状的样品来考验你的算法。3. 实战案例用Halcon查找圆形并输出圆心半径3.1 方案一边缘提取加圆拟合法适合灵活场景我直接给一段实际跑通的HDevelop代码场景是检测一张图里的轴承外圈圆形并输出圆心坐标和半径。* 读取图像并转为灰度 read_image (Image, bearing.png) rgb1_to_gray (Image, GrayImage) * 预处理中值滤波去噪 灰度拉伸增强对比度 median_image (GrayImage, ImageMedian, circle, 3, mirrored) scale_image_max (ImageMedian, ImageScaled) * 提取亚像素边缘 edges_sub_pix (ImageScaled, Edges, canny, 1.5, 20, 40) * 分割边缘轮廓挑出圆弧段 segment_contours_xld (Edges, ContoursSplit, lines_circles, 5, 4, 2) * 筛选轮廓只保留接近圆形的轮廓 select_shape_xld (ContoursSplit, SelectedContours, circularity, and, 0.8, 1.0) * 拟合成圆输出圆心和半径 fit_circle_contour_xld (SelectedContours, geometric, -1, 0, 0, 3, 2, Row, Column, Radius, StartPhi, EndPhi, PointOrder)这里重点解释几个细节segment_contours_xld的第三个参数我用的是lines_circles意思是把轮廓分段成直线和圆弧。这样即使图像里还有其他干扰轮廓也能先把圆弧段分离出来。select_shape_xld的circularity是轮廓的圆度取值范围0到11表示完美圆形。我设的0.8意思是只保留圆度超过0.8的轮廓。按照实际图像调整这个值能够滤掉大部分非圆的干扰物。fit_circle_contour_xld里MaxNumPoints填-1表示使用全部点ClippingEndPoints填0表示不使用端点裁剪Iterations填3表示迭代3次剔除离群点ClippingFactor填2是离群点剔除的强度。跑完这个流程之后Row、Column和Radius就分别是拟合圆的圆心行坐标、列坐标和半径单位是像素。后面如果要转换成物理单位就得做标定。3.2 方案二metrology测量模型适合批量高精度检测方案一虽然灵活但如果现场的圆比较多或者每个圆的边缘附近有干扰用metrology模型会更省心。下面是一段用metrology模型测量螺栓头部圆形的代码。* 读取图像 read_image (Image, bolt_head.png) rgb1_to_gray (Image, GrayImage) * 创建测量模型 create_metrology_model (MetrologyHandle) * 设置图像尺寸 get_image_size (GrayImage, Width, Height) set_metrology_model_image_size (MetrologyHandle, Width, Height) * 假设粗定位得到的圆心在Column0, Row0半径大约Radius0 * 实际项目里这两个值可以通过模板匹配或者用户交互得到 Column0 : 320 Row0 : 240 Radius0 : 80 * 添加圆形测量目标 add_metrology_object_circle_measure (MetrologyHandle, Row0, Column0, Radius0, 20, 15, 1, 30, [measure_transition], [negative], MetrologyCircleIndices) * 设置参数卡尺数量、测量方向、边缘极性 set_metrology_object_param (MetrologyHandle, MetrologyCircleIndices, num_measures, 60) set_metrology_object_param (MetrologyHandle, MetrologyCircleIndices, measure_select, first) set_metrology_object_param (MetrologyHandle, MetrologyCircleIndices, min_score, 0.6) * 执行测量 apply_metrology_model (MetrologyHandle, GrayImage) * 获取测量结果 get_metrology_object_result (MetrologyHandle, MetrologyCircleIndices, result_type, all_param, Parameter) * 输出圆心和半径 MeasuredRow : Parameter[0] MeasuredCol : Parameter[1] MeasuredRadius : Parameter[2] * 获取每个卡尺实际提取到的边缘点用于调试 get_metrology_object_measures (MetrologyHandle, MetrologyCircleIndices, all, RowMeasures, ColumnMeasures, MeasureCrossRegions) * 清理测量模型 clear_metrology_model (MetrologyHandle)这段代码里最需要注意的是add_metrology_object_circle_measure那一行的参数。它的Signature基本是这样的圆心的初始位置、初始半径、卡尺长度沿径向的总长度、卡尺宽度、边缘极性、测量阈值。这里我传的卡尺长度是20个像素、宽度15个像素、阈值30。卡尺长度需要根据你预估的半径误差来定误差越大卡尺就要越长否则边缘点会搜不到。实际项目里初始圆心和半径往往不是硬编码的而是通过模板匹配或者上一帧的结果来动态传入。3.3 参数选择与计算过程一个真实调参案例拿一个检测药瓶瓶口圆的案例来讲。图像分辨率是1280x960瓶口实际直径是24毫米在图像里约占180个像素那么一个像素对应的物理尺寸就是24/180约0.133毫米。我先用模板匹配粗定位瓶口圆心粗定位误差在5像素以内。预估半径是90像素那么add_metrology_object_circle_measure里的卡尺长度至少要大于粗定位误差我设为15像素半径容差就留足了余量。卡尺数量设为60也就是每隔6度一个卡尺能覆盖整个圆周。边缘极性设置成negative因为瓶口在图像里是暗色背景上的亮圆环过渡方向是从亮到暗。跑完apply_metrology_model之后测量出的半径是89.8像素折合物理尺寸是11.97毫米和实际直径24毫米的一半很接近。再通过标定板做完整标定把像素坐标换成物理坐标最终的直径测量结果稳定在24.013毫米重复性精度好于0.01毫米。这个精度水平对药瓶检漏检伤的应用来说完全够用了。3.4 在C#或Qt工程里怎么调用Halcon热词里经常看到“qt怎么调用halcon”、“c#直接调用halcon”这确实是工程落地的关键环节。Halcon提供了HDevEngine可以让你把HDevelop脚本封装成独立的.hdev文件然后在C#或C里通过引擎调用。在C#里调用的方式大概是先用HDevEngine加载.hdev脚本然后设置输入图像变量执行脚本最后取出输出结果。在QtC里也是类似的流程核心类就是HDevEngine、HDevProgram、HDevProcedure。这套方式的好处是算法逻辑都留在HDevelop里调试写好之后C#和C只负责调接口算法和界面彻底解耦。另外一点如果项目里已经用了OpenCV想同时用Halcon两者之间传图像就涉及图像格式转换。Halcon的HImage和OpenCV的Mat可以通过内存拷贝的方式互转核心是灰度图像的通道数、位数、步长要对应上。我自己在C#项目里就是这么干的OpenCV负责读流和预处理Halcon负责高精度测量各干各擅长的。4. 常见问题与排查技巧实录4.1 圆的边缘不闭合、有遮挡怎么办现实图像里圆的边缘经常不完整。比如工件上有字符、有反光、有夹爪遮挡导致边缘轮廓断裂成好几段。碰到这种情况第一反应不应该是提高阈值强行连边而是改变思路不需要完整的圆轮廓也能拟合出圆。解决手段有两个。一个是用segment_contours_xld把轮廓分解成圆弧段然后只拿长度足够的一段或几段圆弧来拟合。另一个是用metrology模型因为它天然只依赖局部测量卡尺某个卡尺区域被遮挡影响的只是被遮挡的那几个测量点其余卡尺仍然能正常工作拟合结果依然可靠。这是metrology模型在抗遮挡上的核心优势实际项目中尤其好用。4.2 光照变化导致边缘提取不稳定现场光照波动是视觉项目里最常见的噩梦。早上下午光线不一样产品的批次不同颜色深浅不一样都会让边缘提取失效。解决办法有两个层面。算法层面预处理阶段尽量用灰度拉伸增强对比度把边缘强度统一到相近水平参数层面edges_sub_pix的双阈值不要卡太死留出波动余量。更稳妥的办法是在现场打一个相对均匀的光源比如同轴光或者环形光让相机视野内的亮度稳定下来。我做过一个项目加了光源之后同样的算法从白天到黑夜、从晴天到雨天都没再出过问题。视觉项目里七分靠打光三分靠算法这句话真不是白说的。4.3 多个圆同时出现怎么筛选目标一张图里十几个圆的情况也很常见比如电池盖板上的多个定位孔。这时候需要做的是先分割出候选圆形区域再根据大小、位置、灰度信息做筛选。我常用的流程是先用threshold或者Blob分析把亮圆或暗圆区域提取出来然后通过select_shape筛选出面积、圆度符合要求的区域再对每个区域单独做边缘提取和圆拟合。筛选条件不局限在圆度、面积还可以加灰度均值、区域位置范围多条件组合起来基本能把干扰排除干净。4.4 像素坐标怎么转换成物理坐标这是项目交付时绕不开的一步。Halcon里做像素到物理单位的转换正规做法是使用标定板如Halcon自带的calibration plate标定相机得到相机内参和外参然后通过image_points_to_world_plane将像素坐标映射到世界坐标平面。如果项目精度要求不高也可以用简单的比例法已知某个标准工件的实际尺寸在图像里量出对应的像素距离算出每个像素代表的物理长度。但这个方法忽略了镜头畸变和透视误差只适合粗糙测量精密测量还是要老老实实做标定。Halcon里标定的详细流程建议直接看官方文档里的Calibration示例程序照着跑一遍就能上手。为了节省大家排查问题的时间我把常见的几个问题和调试思路整理成了表格现象常见原因排查方向拟合圆明显偏离实际边缘有离群点干扰ClippingFactor太大或太小把拟合轮廓和边缘点可视化检查离群点分布调整Iterations和ClippingFactor边缘断裂严重圆弧不连续阈值设得太高或者Sigma过大导致边缘被磨平降低阈值High或Low适当减小Sigma测到的半径忽大忽小边缘定位精度不够可能有噪声检查光照是否稳定预处理降噪是否到位卡尺数量是否足够圆周边有干扰拟合结果被带偏metrology卡尺覆盖范围太大把干扰边缘也收进来了缩短横向卡尺长度卡尺长度或者增加纵向卡尺数量卡尺宽度收紧测量范围图像偏暗导致边缘提取困难阈值和灰度拉伸未适配低亮度图先用scale_image_max增强对比度再调节阈值多目标检测时有漏检筛选条件太严格或者边缘提取参数不合适把中间结果显示出来逐步骤检查分割结果和筛选结果5. 工具选型与扩展方向什么时候用Halcon什么时候用别的5.1 Halcon深度学习工具能做圆形查找吗近两年Halcon的深度学习模块越来越受关注很多人会问圆形查找是不是也可以用深度学习来做答案是可以但要有取舍。Halcon的深度学习工具可以训练目标检测模型比如用矩形框标注出圆形目标的位置模型学会之后能直接输出圆心的外接框中心和尺寸。这种方式对遮挡、形变、背景复杂的场景鲁棒性更好但它的输出精度是像素级的达不到测量场景的亚像素要求。所以我的建议是二者结合要求高精度测量时用深度学习先粗定位出圆形目标的大致位置和半径然后把结果传给metrology模型做精确测量。两个阶段一前一后既解决了复杂背景下的定位问题又保证了最终测量精度。这种“深度粗定位 传统精测量”的组合现在正逐渐成为工业视觉项目的主流方案特别是针对之前用传统算法怎么调都调不过来的场景。5.2 和OpenCV的HoughCircles相比怎么选OpenCV里找圆最常用的是HoughCircles简单粗暴代码量少很多初学者都是从它入门的。但它的问题在于参数多、调参玄学尤其是累加器阈值和最小距离这两个参数换一张光照不同的图可能就得重新调一遍。而且HoughCircles输出的圆心和半径是像素级的精度做不到亚像素。Halcon的优势在于三点一是亚像素精度这是工业测量最核心的差异二是参数体系完整预处理、边缘提取、拟合每一步都暴露给你调试空间大三是测量模型封装得好抗干扰能力强。价格当然也差很多OpenCV免费开源Halcon商业授权费用不低。所以小成本项目或者原型验证阶段OpenCV够用的话就先上OpenCV真到了要做高精度工业检测、要稳定交付给客户的时候用Halcon省心太多了。5.3 什么样的项目适合用圆形查找圆形查找的应用比想象中广得多。3C行业里手机摄像头模组的镜片定位、耳机孔的圆心测量汽车行业里轮毂螺栓孔的位置度检测、刹车盘的圆度测量医药行业里药瓶瓶口的圆度缺陷检测、胶囊的圆度分拣新能源行业里锂电池极片的圆形极耳定位、电池盖板焊接圆度检测。这还只是我接触过的领域实际项目只会更多。判断一个项目适不适合用圆形查找核心是看目标在图像里是否呈现圆形边缘特征。只要满足这个前提都能用上面讲的方法建模。与其担心这个方法有没有局限性不如先跑一个demo用几张现场图验证一下边缘提取的稳定性再决定怎么深入。Halcon的优势就在于demo阶段出效果快往往一天时间就能评估出方案的可行性。说在最后回头看看其实圆形查找的整套流程并不复杂预处理让边缘清晰边缘提取拿到亚像素轮廓拟合输出圆心半径metrology模型把控高精度场景。真正拉开差距的是对参数背后原理的理解以及现场的调试经验。我个人在实际调试中还有一个特别想说的小技巧不要盯着控制台看数字一定要把中间过程可视化出来。把提取到的轮廓、拟合的圆、metrology的卡尺和边缘点都叠加显示在原图上一看便知道问题出在哪个环节。很多时候算法的bug不是逻辑烧脑而是你压根没看到它到底在图像上看到了什么。调试Halcon视觉反馈比任何文档都管用。这是我在无数个项目里踩出来的体会分享给看到这里的你。
返回列表