一维测量(也称为一维计量或卡尺)沿着预定义的感兴趣区域定位垂直于感兴趣区域方向边缘。此时,边缘被定义为从暗到亮或从亮到暗的过渡。
根据提取的边缘,可以测量零件尺寸。例如,可通过在其上测量物料图像的感兴趣区域左右两侧来测量部件的宽度。
除测量矩形外,还可以测量圆弧,例如齿轮上的齿宽。测量方法的优点是执行时间短,精度高。或者可以使用HDevelop的Measure Assistant,它运行点击几下鼠标便可执行测量。
1 基本概念
测量由以下几步实现:
1.1 获取图像
获取图像。
1.2 创建测量对象
获取图像后,指定要测量的位置,即描述要测量的直线或圆弧的位置方向等。以上信息即其他参数都包含在测量工具中。通过使用所谓的句柄来访问测量对象。与文件句柄类似,在使用测量工具时需要此句柄。每次执行测量工具时,都会将此句柄作为参数传递。像C++面向对象语言中,可以使用测量工具而不用调用底层逻辑。使用面向对象创建对象和销毁。
1.3 测量
可以通过制定测量对象和调试视觉工具参数进行测量。
2 扩展概念
在许多情况下,测量应用程序较复杂。导致这种情况的原因:噪点或打光不均匀。还需要进行转换从而能够可视化。
2.1标定图像
为实现高精度测量,向具有线性响应函数,即图像中的灰度值应线性依赖于入射光照强度。考虑一些相机硬件没有线性响应功能,Halcon提供了所谓的校正:使用算子radiometric_self_calibration,可以确定相机的逆响应函数,容纳后执行测量之前使用lut_trans将此函数应用与图像中。
2.2 ROI 定位
需要测量的直线或圆弧ROI区域需要跟随图像进行定位。
2.3 图像校正
校正图像以便消除镜头畸变等影响。
2.4 创建测量对象
可以使用draw_rectangle2等操作符交互式的测量线或圆弧,或从文件(read_string)中读取参数。作为一种选择,其定位坐标参数基于其他视觉工具如Blob生成的结果。特别是,测量线或圆弧需要定位某个对象。如果总是测量沿着同一条线或圆弧执行,则可以离线创建测量对象,并可多次使用。
2.5 世界坐标转换
如已经校正视觉系统,则可以使用image_points_to_world_plane轻松地将结果转换位世界坐标。
2.6 可视化结果
可视化边缘位置最佳使用算子gen_contour_polygon_xld创建线段。
3 程序实例
* 测量工具宽度
dev_update_window('off')
dev_close_window()
* step:获取图像
read_image(Image,'D:/Halcon_Study/gongjian.BMP')
get_image_size(Image, Width, Height)
dev_open_window_fit_image(Image,0,0,Width,Height,WindowHandle)
set_display_font(WindowHandle,16, 'mono', 'true', 'false')
dev_set_draw('margin')
dev_set_line_width(3)
dev_display(Image)
set_display_font(WindowHandle, 16, 'mono', 'true', 'false')
disp_continue_message(WindowHandle, 'black', 'true')
stop()
* step:创建测量对象
* -> ROI实例化
Row:=400
Column:=345
Length1:=240
Length2:=50
Angle:=rad(90)
gen_rectangle2(ROI,Row,Column,Angle,Length1,Length2)
* ->创建测量对象
gen_measure_rectangle2(Row,Column,Angle,Length1,Length2,Width,Height,'bicubic',MeasureHandle)
dev_display(ROI)
disp_continue_message(WindowHandle, 'black', 'true')
stop()
* step:测量
measure_pairs(Image,MeasureHandle,0.5,1,'negative','all',RowEdgeFirst,ColumnEdgeFirst,AmplitudeFirst,RowEdgeSecond,ColumnEdgeSecond,AmplitudeSecond,IntraDistance,InterDistance)
disp_continue_message(WindowHandle, 'black', 'true')
stop()
* step:可视化结果
for i:= 0 to |RowEdgeFirst|-1 by 1
gen_contour_polygon_xld (EdgeFirst, [-sin(Angle + rad(90)) * Length2 + RowEdgeFirst[i],-sin(Angle - rad(90)) * Length2 + RowEdgeFirst[i]], [cos(Angle + rad(90)) * Length2 + ColumnEdgeFirst[i],cos(Angle - rad(90)) * Length2 + ColumnEdgeFirst[i]])
gen_contour_polygon_xld (EdgeSecond, [-sin(Angle + rad(90)) * Length2 + RowEdgeSecond[i],-sin(Angle - rad(90)) * Length2 + RowEdgeSecond[i]], [cos(Angle + rad(90)) * Length2 + ColumnEdgeSecond[i],cos(Angle - rad(90)) * Length2 + ColumnEdgeSecond[i]])
dev_set_color ('cyan')
dev_display(EdgeFirst)
dev_set_color('magenta')
dev_display(EdgeSecond)
dev_set_color('blue')
if(i==0)
set_tposition(WindowHandle,RowEdgeFirst[i]+5,ColumnEdgeFirst[i]+20)
else
set_tposition(WindowHandle,RowEdgeFirst[i]-40,ColumnEdgeFirst[i]+20)
endif
write_string (WindowHandle, 'width: ' + IntraDistance[i] + ' pix')
endfor
disp_continue_message(WindowHandle, 'black', 'true')
stop()
* 销毁测量对象
close_measure(MeasureHandle)
dev_update_window('on')
dev_clear_window()
琐碎时间阅读基础知识,详情关注微信公众号“知识代码AI”。