Halcon一维测量

Halcon一维测量
[TOC]

1.测量对象

1.1 生成测量对象

  • 矩形、弧形测量对象

    • 矩形

    Halcon中通过gen_measure_rectangle2( : : Row, Column, Phi, Length1, Length2, Width, Height, Interpolation : MeasureHandle)即可生成一个矩形测量对象:

    图1 矩形测量对象
图2 矩形测量参数
* **弧形**

Halcon中通过gen_measure_arc( : : CenterRow, CenterCol, Radius, AngleStart, AngleExtent, AnnulusRadius, Width, Height, Interpolation : MeasureHandle)即可生成一个矩形测量对象:

图3 弧形测量对象
图4 弧形测量参数

1.2 测量过程步骤

  1. 沿着测量对象的起始位置将其分割成宽度为1pixel高度与测量对象相等的的切片;
  2. 计算每个切片内的所有像素的灰度均值,并将均值投影到Pfofile Line上(如果需要知道所有的投影值,可以通过measure_projection算子获取),这里需要注意的是:如果这个投影不是水平方向上的或者是垂直方向,那么在计算每个切片内的灰度均值时,需要进行插值,插值类型的选择根据实际情况而定;
  3. 对Profile Line上的投影值进行高斯滤波(高斯滤波对边缘保留效果比较好);
  4. 计算滤波后Profile Line上的值的一阶导数,并且对这些导数值要乘上系数\(\sqrt{2\pi}·Sigma\)(因为高斯滤波的关系才需要乘上这个系数的吗,没弄明白);
  5. 判断一阶导数值是否在阈值范围内;

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的直线的位置的,所以测量对象不适合被用作测量弯曲结构的边缘点的位置,否则将有可能导致错误的结果。

  • 在检测边缘对时,如果遇到连续的极性相同的边缘该怎么处理

    img

    图中由于阴影的缘故,当使用Transition = “negative”,在遇到连续的极性相同的边缘时,Halcon会选择第一条边缘,如果使用Transition = “negative_strongest",会选择连续的极性相同的边缘中梯度值最大的那条边缘,从而得到了想要的边缘对。

  • 当测量对象超过图像范围时,Profile Line该怎么计算

    当垂直与Profile Line的切片存在图像外部分时,那么在计算灰度均值时,切片中处于对象外部分的值被看作0,只计算其图像内包含像素部分的均值。

    img

    img

  • 测量对象的高度(垂直于Profile Line方向)

    • 如果Profile Line近乎垂直于被测直线边缘,那么测量对象的高度应尽量地往大了设置,这样Profile Line相对的噪点就比较少

    img

    narrow_perpendicular_ROI

img

wide_perpendiculr_ROI
  • 反之,如果Profile Line与被测直线边缘越不垂直,应尽量减小测量对象的高度(右边粗线为灰度值曲线,细线为一阶导数值曲线)

    img

narrow_slanted_ROI
![img](https://img2022.cnblogs.com/blog/1994536/202204/1994536-20220408133151533-1923875824.png)
wide_slanted_ROI
---

2.模糊测量

模糊测量就是根据检测得到的边缘点或者边缘对,根据某种边缘或者边缘对特征建立函数来进行筛选,最终得到想要的边缘对的过程。

2.1模糊测量的步骤

  1. 创建测量对象gen_measure_rectangle2

  2. 选取特征并创建筛选函数

    *创建筛选函数
    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,由这两组值最终生成一个分段函数。

    img

  3. 执行模糊测量

    执行模糊测量的算子有fuzzy_meaure_pairsfuzzy_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_pairsfuzzy_measure_pairing之间的区别在于后者能够检测到相互包含或者交错的边缘对,而前者不能。

      • fuzzy_measure_pairs

        img

      • fuzzy_measure_pairing

        img

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为特征值种类数。

posted @ 2022-04-14 17:09  木乔ni  阅读(1504)  评论(0编辑  收藏  举报