一维测量
像点到点的距离,边缘对的距离等沿着一维方向的测量都属于1D测量范畴。Halocn的一维测量首先构建矩形或者扇形的ROI测量对象,然后在ROI内画出等距离的、长度与ROI宽度一致的、垂直于ROI的轮廓线(profile line)的等距线。如下图所示。
测量ROI的轮廓线尽量与被测边缘垂直,宽度适当宽些,等距线的密集度考虑速度与精度综合选择,这样可以减少噪声。
然后,沿着垂直轮廓线的方向,计算出每一条等距线的平均灰度值,可以得出轮廓线的灰度直方图,同时可以选择使用高斯滤波器平滑灰度直方图。如下图所示。Halcon算子measure_pairs的参数Sigma指定了高斯滤波器的标准差。
最后,求出平滑灰度直方图的一阶导数,一阶导数的极值点作为边缘的亚像素精度候选点,只有一阶导数极值点的绝对值大于预先设定的阈值(测量算子的参数Threshold)边缘候选点才被选作为边缘中心点。Halcon测量算子最后得到每一条边缘与轮廓线的交点。
一维测量流程
一维测量相关算子
gen_measure_rectangle2( : : Row, Column, Phi, Length1, Length2, Width, Height, Interpolation : MeasureHandle)
名字:生成仿射矩形区域测量句柄
描述:用于提取垂直于仿射矩形的直边
参数:
Row:仿射矩形中心行坐标
Column:仿射矩形中心列坐标
Phi:仿射矩形的纵轴水平角,单位弧度 ,注意:测量矩形的测量方向的选择
Length1:仿射矩形宽度的一半
Length2:仿射矩形高度的一半
Width:图像的宽度
Height:图像的高度
Interpolation :插值类型
MeasureHandle:测量对象句柄
gen_measure_arc( : : CenterRow, CenterCol, Radius, AngleStart, AngleExtent, AnnulusRadius, Width, Height, Interpolation : MeasureHandle)
名字:生成环形区域测量句柄
描述:用于提取垂直环形圆弧的直边缘。
参数:
CenterRow:圆弧中心行坐标
CenterCol:圆弧中心列坐标
Radius:圆弧半径
AngleStart:圆弧起始角度
AngleExtent:圆弧角度范围
AnnulusRadius:环形带的半径(宽度的一半)
Width:图像的宽度
Height:图像的高度
Interpolation :插值类型
MeasureHandle:测量对象句柄
measure_pairs(Image : : MeasureHandle, Sigma, Threshold, Transition, Select : RowEdgeFirst, ColumnEdgeFirst, AmplitudeFirst, RowEdgeSecond, ColumnEdgeSecond, AmplitudeSecond, IntraDistance, InterDistance)
名字:测量边缘对
描述:提取垂直于仿射矩形或环形圆弧的直边缘对。
参数:
Image:输入图像
MeasureHandle:测量对象句柄
Sigma:高斯平滑参数
Threshold:最小边缘幅度
Transition:边缘对极性,第一个与第二个相反
Select :选择边缘对
RowEdgeFirst:边缘点对的第一个边缘的行坐标
ColumnEdgeFirst:边缘点对的第一个边缘的列坐标
AmplitudeFirst:第一个边缘的幅度
RowEdgeSecond:第二个边缘行坐标
ColumnEdgeSecond:第二个边缘列坐标
AmplitudeSecond:第二个边缘幅度
IntraDistance:两个边缘对之间的距离
InterDistance:相邻边缘对之间的距离
注意:halcon中的坐标系与opencv中不一样
halcon坐标系如下图所示
opencv的坐标系如下
因此需要注意RowEdgeFirst返回的是y轴。
measure_pos(Image : : MeasureHandle, Sigma, Threshold, Transition, Select : RowEdge, ColumnEdge, Amplitude, Distance)
名字:测量边缘对
描述:提取垂直于仿射矩形或圆弧的直边缘。
参数:
Image:输入图像
MeasureHandle:测量对象句柄
Sigma:高斯平滑系数
Threshold:最小边缘幅度
Transition:极性
*Select:边缘选择
RowEdge:找到的边缘中心的行坐标
ColumnEdge:找到的边缘中心列坐标
Amplitude:边缘幅度
Distance:相邻边缘之间的距离
measure_pairs与measure_pos的区别:一般,measure_pos函数会寻找所有满足条件的单个关键点,属于独立作战,而带pairs的函数是需要找到满足条件的一对点,如果只能找到一个点,没有另外一个点与之配对,则该点会被弃掉。幅度是指边缘处明暗灰度各自的均值差
translate_measure( : : MeasureHandle, Row, Column )(选用)
名字:转换一个度量对象
描述:一般用于一个程序中有很多测量矩形的情况,当使用第二个测量矩形时,不需要重新 gen_measure_rectangle2生成,将第二个测量矩形的中心坐标放到该算子的第二、三个参数当中即可,其第一个参数得到的句柄就相当于使用gen_measure_rectangle2算子正常生成的测量矩形句柄。然后使用measure_pos对该句柄进行正常计算。
参数:
MeasureHandle:测量句柄
Row:新参考点的行坐标
Column :新参考点的列坐标
案例
接下来以halcon一维测量自带的引脚间距和高度测量案例进行实操
打开halcon帮助文档,找到一维测量然后下拉到最后点击measure_pin.hdev
一、引脚间距测量
* Pin Measurement: Example for the application of the measure package
* including a lot of visualization operators
* 关闭窗口
dev_close_window ()
*读取自带的引脚图片
read_image (Image, 'ic_pin')
*获取图片的宽度和高度
get_image_size (Image, Width, Height)
*打开窗口,尺寸为图片宽高的1/2
dev_open_window (0, 0, Width / 2, Height / 2, 'black', WindowHandle)
*设置窗口显示字体
set_display_font (WindowHandle, 14, 'mono', 'true', 'false')
*把图片放到窗口
dev_display (Image)
*在屏幕显示暂停层序按F5继续操作的信息
disp_continue_message (WindowHandle, 'black', 'true')
stop ()
* draw_rectangle2 (WindowHandle, Row, Column, Phi, Length1, Length2)
*创建一个带角度的矩形,这里固定矩形框大小
Row := 47
Column := 485
Phi := 0
Length1 := 420
Length2 := 10
*设置颜色
dev_set_color ('green')
*设置绘制方式:这里绘制边框不填充
dev_set_draw ('margin')
*设置线条
dev_set_line_width (3)
*绘制矩形
gen_rectangle2 (Rectangle, Row, Column, Phi, Length1, Length2)
*根据上面的矩形生成测量的roi区域
gen_measure_rectangle2 (Row, Column, Phi, Length1, Length2, Width, Height, 'nearest_neighbor', MeasureHandle)
disp_continue_message (WindowHandle, 'black', 'true')
stop ()
*关闭自动把图像更新到窗口
dev_update_pc ('off')
dev_update_var ('off')
n := 1
*计算时间
count_seconds (Seconds1)
*提取垂直于仿射矩形的直边缘对
measure_pairs (Image, MeasureHandle, 1.5, 30, 'negative', 'all', RowEdgeFirst, ColumnEdgeFirst, AmplitudeFirst, RowEdgeSecond, ColumnEdgeSecond, AmplitudeSecond, PinWidth, PinDistance)
count_seconds (Seconds2)
Time := Seconds2 - Seconds1
disp_continue_message (WindowHandle, 'black', 'true')
stop ()
dev_set_color ('red')
*绘制边缘对,输入为边缘点的行列坐标
disp_line (WindowHandle, RowEdgeFirst, ColumnEdgeFirst, RowEdgeSecond, ColumnEdgeSecond)
*计算每个边缘对的平均值
avgPinWidth := sum(PinWidth) / |PinWidth|
*计算相邻边缘对的平均值
avgPinDistance := sum(PinDistance) / |PinDistance|
numPins := |PinWidth|
dev_set_color ('yellow')
disp_message (WindowHandle, 'Number of pins: ' + numPins, 'image', 200, 100, 'yellow', 'false')
disp_message (WindowHandle, 'Average Pin Width: ' + avgPinWidth, 'image', 260, 100, 'yellow', 'false')
disp_message (WindowHandle, 'Average Pin Distance: ' + avgPinDistance, 'image', 320, 100, 'yellow', 'false')
* dump_window (WindowHandle, 'tiff_rgb', 'C:\\Temp\\pins_result')
disp_continue_message (WindowHandle, 'black', 'true')
stop ()
运行结果
二、引脚高度测量
Row := 508
Column := 200
Phi := -1.5708
Length1 := 482
Length2 := 35
gen_rectangle2 (Rectangle, Row, Column, Phi, Length1, Length2)
gen_measure_rectangle2 (Row, Column, Phi, Length1, Length2, Width, Height, 'nearest_neighbor', MeasureHandle)
stop ()
这里同样创建一个矩形用于确定测量的roi区域,生成结果如下
接着测量边缘并绘制
*测量边缘对
measure_pos (Image, MeasureHandle, 1.5, 30, 'all', 'all', RowEdge, ColumnEdge, Amplitude, Distance)
*计算第一对边缘的高度
PinHeight1 := RowEdge[1] - RowEdge[0]
*计算第二对边缘的高度
PinHeight2 := RowEdge[3] - RowEdge[2]
dev_set_color ('red')
disp_line (WindowHandle, RowEdge, ColumnEdge - Length2, RowEdge, ColumnEdge + Length2)
disp_message (WindowHandle, 'Pin Height: ' + PinHeight1, 'image', RowEdge[1] + 40, ColumnEdge[1] + 100, 'yellow', 'false')
disp_message (WindowHandle, 'Pin Height: ' + PinHeight2, 'image', RowEdge[3] - 120, ColumnEdge[3] + 100, 'yellow', 'false')
运行结果
需要注意的是measure_pos返回的RowEdge, ColumnEdge指的是四条边缘的中点坐标,如下图的所示: