Halcon一维测量
1.测量对象
1.1 生成测量对象
-
矩形、弧形测量对象
- 矩形
Halcon中通过
gen_measure_rectangle2( : : Row, Column, Phi, Length1, Length2, Width, Height, Interpolation : MeasureHandle)
即可生成一个矩形测量对象:图1 矩形测量对象
Halcon中通过gen_measure_arc( : : CenterRow, CenterCol, Radius, AngleStart, AngleExtent, AnnulusRadius, Width, Height, Interpolation : MeasureHandle)
即可生成一个矩形测量对象:
1.2 测量过程步骤
- 沿着测量对象的起始位置将其分割成宽度为1pixel高度与测量对象相等的的切片;
- 计算每个切片内的所有像素的灰度均值,并将均值投影到Pfofile Line上(如果需要知道所有的投影值,可以通过
measure_projection
算子获取),这里需要注意的是:如果这个投影不是水平方向上的或者是垂直方向,那么在计算每个切片内的灰度均值时,需要进行插值,插值类型的选择根据实际情况而定; - 对Profile Line上的投影值进行高斯滤波(高斯滤波对边缘保留效果比较好);
- 计算滤波后Profile Line上的值的一阶导数,并且对这些导数值要乘上系数\(\sqrt{2\pi}·Sigma\)(因为高斯滤波的关系才需要乘上这个系数的吗,没弄明白);
- 判断一阶导数值是否在阈值范围内;
1.3 测量方式
-
边缘测量
measure_pos(Image : : MeasureHandle, Sigma, Threshold, Transition, Select : RowEdge, ColumnEdge, Amplitude, Distance)
:measure_pos用以检测所有的边缘点,其中Transition可选”all"、”positive“、”negative",如果选择”positive",那么能检测的只能是从暗到亮的边缘点,即一阶导数值为正值,如果为“positive”,那么检测的是从亮到暗的边缘点,即一阶导数为负,选择“all”的话那么所有阈值范围内的边缘点都会被检测出来; -
边缘对测量
measure_pairs(Image : : MeasureHandle, Sigma, Threshold, Transition, Select : RowEdgeFirst, ColumnEdgeFirst, AmplitudeFirst, RowEdgeSecond, ColumnEdgeSecond, AmplitudeSecond, IntraDistance, InterDistance)
:边缘对测量出的边缘点都是成对出现的,并且这些边缘对的顺序是从Profile的Start指向End的;-
Transition = ”positive"
dev_set_line_width (1) dev_set_draw ('margin') gen_image_const (Image, 'byte', 512, 512) gen_rectangle2 (Rectangle, 256, 256,rad(30), 200, 40) paint_region (Rectangle, Image, ImageResult, 255, 'fill') *创建测量对象 measure_row := 256 measure_col := 256 measure_phi := rad(30) measure_len1 := 230 measure_len2 := 20 gen_measure_rectangle2 (measure_row, measure_col,measure_phi, measure_len1, measure_len2, 512, 512, 'nearest_neighbor', MeasureHandle) *测量边缘对 measure_pairs (ImageResult, MeasureHandle, 1, 30, 'positive', 'all', RowEdgeFirst, ColumnEdgeFirst, AmplitudeFirst,\ RowEdgeSecond, ColumnEdgeSecond, AmplitudeSecond, IntraDistance, InterDistance) *绘制测量对象 gen_rectangle2_contour_xld (Rectangle1, measure_row, measure_col,measure_phi, measure_len1, measure_len2) *绘制Profile Line arrow_row1 := measure_row + measure_len1*sin(measure_phi) arrow_col1 := measure_col - measure_len1*cos(measure_phi) arrow_row2 := measure_row - measure_len1*sin(measure_phi) arrow_col2 := measure_row + measure_len1*cos(measure_phi) dev_set_color ('blue') gen_arrow_contour_xld (Arrow, arrow_row1, arrow_col1, arrow_row2, arrow_col2, 5, 5) dev_set_color ('red') gen_cross_contour_xld (Cross1, RowEdgeFirst, ColumnEdgeFirst, 26, 0.785398) gen_cross_contour_xld (Cross2, RowEdgeSecond, ColumnEdgeSecond, 26, 0.785398)
-
Transition = "negative"(将上述代码measure_pairs算子Transition参数修改为“negative")
-
1.4 注意事项
-
测量对象的使用场景
测量对象是用来检测垂直于其Profile Line的直线的位置的,所以测量对象不适合被用作测量弯曲结构的边缘点的位置,否则将有可能导致错误的结果。
-
在检测边缘对时,如果遇到连续的极性相同的边缘该怎么处理
图中由于阴影的缘故,当使用Transition = “negative”,在遇到连续的极性相同的边缘时,Halcon会选择第一条边缘,如果使用Transition = “negative_strongest",会选择连续的极性相同的边缘中梯度值最大的那条边缘,从而得到了想要的边缘对。
-
当测量对象超过图像范围时,Profile Line该怎么计算
当垂直与Profile Line的切片存在图像外部分时,那么在计算灰度均值时,切片中处于对象外部分的值被看作0,只计算其图像内包含像素部分的均值。
-
测量对象的高度(垂直于Profile Line方向)
- 如果Profile Line近乎垂直于被测直线边缘,那么测量对象的高度应尽量地往大了设置,这样Profile Line相对的噪点就比较少
narrow_perpendicular_ROI
-
反之,如果Profile Line与被测直线边缘越不垂直,应尽量减小测量对象的高度(右边粗线为灰度值曲线,细线为一阶导数值曲线)
2.模糊测量
模糊测量就是根据检测得到的边缘点或者边缘对,根据某种边缘或者边缘对特征建立函数来进行筛选,最终得到想要的边缘对的过程。
2.1模糊测量的步骤
-
创建测量对象
gen_measure_rectangle2
-
选取特征并创建筛选函数
*创建筛选函数 create_funct_1d_pairs ([7,9,11], [0,1,0], \ FuzzyMembershipFunctionPairSize10) *为这个筛选函数指定筛选特征 set_fuzzy_measure (MeasureHandle, 'size', FuzzyMembershipFunctionPairSize10)
create_funct_1d_pairs
需要为其提供一组递增的值XValuse以及范围在0到1之间的值YValues,这里面XValue对应特征值,YValue对应Fuzzy_Score,由这两组值最终生成一个分段函数。 -
执行模糊测量
执行模糊测量的算子有
fuzzy_meaure_pairs
和fuzzy_measure_pairing
,参数上这两个算子基本都和measure_pairs很相似,算子内部的工作我觉得可以分为以下几步。
1)检测边缘点或者边缘对;
2) 计算边缘点或者边缘对的特征值,如size(当然这里可选的特征值有很多,contrast、size、gray等);
3)将计算出来的特征值代入分段函数中,并得到对应的YValue;
4)判断YValue是否大于模糊阈值Fuzzy_Threshold,如果大于,则保留,如:检测得到边缘对的宽度为8,设置的Fuzzy_Threshold为0.6,那么将8带入上述图中分段函数得Fuzzy_Score = 0.5,小于设置的Fuzzy_Threshold,则该边缘对不会被保留;
-
fuzzy_measure_pairs
和fuzzy_measure_pairing
之间的区别在于后者能够检测到相互包含或者交错的边缘对,而前者不能。-
fuzzy_measure_pairs
-
fuzzy_measure_pairing
-
-
2.2 注意事项
-
多特征模糊测量
当我们希望根据多个特征建立多个分段函数时应该怎么做,如:希望根据gray和size来判断
*创建测量对象 gen_measure_rectangle2 (Row,Column,Phi,Len1,Len2,Width,Height,'nearest_neighbor', MeasureHandle) *创建分段函数 create_funct_1d_pairs ([50,100,150], [0.0,1.0,0.0], GrayFunction) create_funct_1d_pairs ([7,9,11], [0.0,1.0,0.0], SizeFunction) *设置关联特征 set_fuzzy_measure (MeasureHandle, 'gray', GrayFunction) set_fuzzy_measure (MeasureHandle, 'size', SizeFunction)
通过检测到边缘对的”gray“、”size“特征值输入到分段函数能够分别得到一个分数值\(FuzzyScore(gray)\)和\(FuzzyScore(size)\),但是在执行模糊测量的时候只有一个阈值Fuzzy_Threshold,所以需要将这两个分数转换为一个分数,Halcon内定义了一个几何平均数公式用以转换:
\[G(a_1,.......,a_n) = (\prod_{i=1}^{n}a_i)^{1/n} \]
其中\(a_1,........,a_n\)分别代表特征值,n为特征值种类数。