卡尺工具进阶指南
文章目录
- 🎯 卡尺工具联合使用实战指南(Halcon视觉入门进阶)
- 💡 一、使用场景举例
- 🧭 二、典型流程图
- 🔧 三、实战示例:模板匹配+直线卡尺测量边缘位置
- 📋 场景:测量某一区域直线数量
- 👇 步骤如下:
- 🔵 四、圆形卡尺的配合使用示例
- 🧠 五、小技巧与建议
- 📌 六、总结
🎯 卡尺工具联合使用实战指南(Halcon视觉入门进阶)
在实际的工业视觉项目中,我们常常遇到这样的需求:
先精准找到一个物体的位置,然后对其关键特征(如边缘、孔、圆等)进行精密测量。
如果你只用卡尺工具,有时候无法知道测量区域的精确位置;
如果你只用模板匹配,也无法完成尺寸测量或对边缘精度的检测。
这时候就可以将 模板匹配 + 卡尺工具(直线/圆形) 组合使用,达到“先定位,再测量”的效果。
💡 一、使用场景举例
| 应用 | 描述 |
|---|---|
| 插座PIN脚检测 | 模板匹配定位插座,再用直线卡尺测量PIN脚高度 |
| 螺丝孔位测量 | 模板匹配定位螺丝轮廓,再用圆形卡尺检测孔径 |
| 电池极耳宽度测量 | 定位电池边缘,再用直线卡尺测量极耳的宽度 |
| 齿轮内孔测量 | 先定位齿轮,再用圆形卡尺量内圆或中心位置 |
🧭 二、典型流程图
1. 模板创建 → 2. 模板匹配 → 3. 坐标系建立 →
4. 卡尺工具构建(直线/圆) → 5. 亚像素边缘测量 → 6. 结果显示与判断
🔧 三、实战示例:模板匹配+直线卡尺测量边缘位置
📋 场景:测量某一区域直线数量
👇 步骤如下:
dev_update_off ()
dev_close_window ()
read_image (Image, 'C:/Users/25972/MVS/Data/Image_20250707163712868.jpg')
dev_open_window_fit_image (Image, 0, 0, -1, -1, WindowHandle)
dev_set_line_width (3)
set_display_font (WindowHandle, 16, 'mono', 'true', 'false')
dev_display (Image)
*
* Search parameters
AngleExtent := 90
AngleExtentTracking := 20
MinScore := 0.4
MinScoreTracking := 0.3
TrackingRadius := 80
ScaleROffset := 0.01
ScaleCOffset := 0.0
Metric := 'use_polarity'gen_rectangle1 (ModelRegion, 1887.08, 1021.38, 2348.88, 1348.56)
gen_rectangle1 (Circle, 1859.66, 1105.21, 1924.35, 1240.74)area_center (ModelRegion, Area, Row, Column)
reduce_domain (Image, ModelRegion, ImageReduced)
create_planar_uncalib_deformable_model (ImageReduced, 'auto', [], [], 'auto', 1, [], 'auto', 1, [], 'auto', 'none', Metric, 'auto', 'auto', [], [], ModelID)
set_deformable_model_origin (ModelID, -Row, -Column)
get_deformable_model_contours (Contours, ModelID, 1)
dev_display (Image)
dev_set_color ('green')
dev_set_draw ('margin')
dev_display (Contours)
disp_message (WindowHandle, 'Model created', 'window', 12, 12, 'black', 'true')
disp_continue_message (WindowHandle, 'black', 'true')
stop ()
*
Score := []
select_obj (Contours, ObjectSelected, 1)
get_contour_xld (ObjectSelected, RowOrig, ColOrig)
NotFound := []
TrackingFailed := []
list_files('E:/anglePicture/lew/term', 'files', Files)
tuple_regexp_select (Files, ['.*(bmp|jpg)','ignore_case'], Files)
NumImages := 100tuple_regexp_select (Files, ['\\.(tif|tiff|gif|bmp|jpg|jpeg|jp2|png|pcx|pgm|ppm|pbm|xwd|ima)$','ignore_case'], ImageFiles)
for Index := 0 to |ImageFiles| - 1 by 1read_image (Image, ImageFiles[Index])wait_seconds (0.05)TrackingTime := 0* Either it is the first image, and one needs to perform full search,* or else the algorithm lost track of the object, and needs to start* all over again
* if (|Score| > 0)* Keep track of the object: project the image with the pose that the object had* in the previous image. The assumption is that the pose does not change much* from image to image (see parameter AngleExtentTracking). Update the pose after* successful searchtrycount_seconds (S1)find_planar_uncalib_deformable_model (Image, ModelID, rad(-AngleExtentTracking / 2), rad(AngleExtentTracking), 1, 1 + ScaleROffset, 1, 1 + ScaleCOffset, MinScoreTracking, 1, 1, 0, 0.9, [], [], HomMat2DTrack, Score)hom_mat2d_invert (HomMat2DTrack, HomMat2DInvert)projective_trans_image (Image, TransImage, HomMat2DInvert, 'bilinear', 'false', 'false')reduce_domain (TransImage, Circle, ImageReduced)crop_domain(ImageReduced, ImagePart)count_seconds (S2)dev_set_color ('green')catch (Exception)TrackingTime := S2 - S1TrackingFailed := [TrackingFailed,Index]endtry
* endif
endforget_image_size (ImagePart, Width, Height)* Measure 03: Code generated by Measure 03* Measure 03: Prepare measurementAmplitudeThreshold := 40RoiWidthLen2 := 5set_system ('int_zooming', 'true')* Measure 03: Coordinates for line Measure 03 [0]LineRowStart_Measure_03_0 :=Height/2LineColumnStart_Measure_03_0 := 0LineRowEnd_Measure_03_0 := Height/2LineColumnEnd_Measure_03_0 := Width* Measure 03: Convert coordinates to rectangle2 typeTmpCtrl_Row := 0.5*(LineRowStart_Measure_03_0+LineRowEnd_Measure_03_0)TmpCtrl_Column := 0.5*(LineColumnStart_Measure_03_0+LineColumnEnd_Measure_03_0)TmpCtrl_Dr := LineRowStart_Measure_03_0-LineRowEnd_Measure_03_0TmpCtrl_Dc := LineColumnEnd_Measure_03_0-LineColumnStart_Measure_03_0TmpCtrl_Phi := atan2(TmpCtrl_Dr, TmpCtrl_Dc)TmpCtrl_Len1 := 0.5*sqrt(TmpCtrl_Dr*TmpCtrl_Dr + TmpCtrl_Dc*TmpCtrl_Dc)TmpCtrl_Len2 := RoiWidthLen2* Measure 03: Create measure for line Measure 03 [0]* Measure 03: Attention: This assumes all images have the same size!gen_measure_rectangle2 (TmpCtrl_Row, TmpCtrl_Column, TmpCtrl_Phi, TmpCtrl_Len1, TmpCtrl_Len2, Width, Height, 'nearest_neighbor', MsrHandle_Measure_03_0)* Measure 03: **************************************************************** Measure 03: * The code which follows is to be executed once / measurement ** Measure 03: **************************************************************** Measure 03: The image is assumed to be made available in the* Measure 03: variable last displayed in the graphics windowcopy_obj (ImagePart, Image, 1, 1)* Measure 03: Execute measurementsmeasure_pos (Image, MsrHandle_Measure_03_0, 1, AmplitudeThreshold, 'all', 'all', Row_Measure_03_0, Column_Measure_03_0, Amplitude_Measure_03_0, Distance_Measure_03_0)
🔵 四、圆形卡尺的配合使用示例
对于圆孔或螺丝孔等特征,可以使用 gen_measure_circle 配合 measure_pos 或 measure_arc 实现:
* 创建圆形卡尺
gen_measure_circle(Row, Column, Radius,Width, Height, 'bilinear', MeasureHandle)* 查找圆边缘
measure_pos(Image, MeasureHandle, Sigma, Threshold,'all', 'all', RowEdge, ColumnEdge, Amplitude, Distance)
然后拟合圆或计算半径、圆心位置等。
🧠 五、小技巧与建议
| 目的 | 技巧 |
|---|---|
| 提高鲁棒性 | 在模板匹配中使用多个角度范围 |
| 测量稳定性 | 卡尺区域设置要略大于边缘区域,避免误检 |
| 多产品适应 | 支持多个模板,根据匹配结果选择不同测量路径 |
| 数据输出 | 可导出为 CSV 或画到 UI 中进行展示、判断 |
📌 六、总结
将 模板匹配 和 卡尺工具(直线 / 圆形) 联合使用,是视觉开发中非常经典、实用的组合方式。它能帮我们:
- 精准定位产品特征(模板匹配)
- 稳定提取亚像素边缘(卡尺工具)
- 实现高精度测量、判断、反馈控制
📌 无论你是做尺寸测量、孔位校验、偏差检测,都建议你掌握这种组合方式。它将极大提升你在 Halcon 项目中的开发能力与鲁棒性。