1. 程式人生 > 其它 >Halcon一維測量2

Halcon一維測量2

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的直線的位置的,所以測量物件不適合被用作測量彎曲結構的邊緣點的位置,否則將有可能導致錯誤的結果。

  • 在檢測邊緣對時,如果遇到連續的極性相同的邊緣該怎麼處理

    圖中由於陰影的緣故,當使用Transition = “negative”,在遇到連續的極性相同的邊緣時,Halcon會選擇第一條邊緣,如果使用Transition = “negative_strongest",會選擇連續的極性相同的邊緣中梯度值最大的那條邊緣,從而得到了想要的邊緣對。

  • 當測量物件超過影象範圍時,Profile Line該怎麼計算

    當垂直與Profile Line的切片存在影象外部分時,那麼在計算灰度均值時,切片中處於物件外部分的值被看作0,只計算其影象內包含畫素部分的均值。

  • 測量物件的高度(垂直於Profile Line方向)

    • 如果Profile Line近乎垂直於被測直線邊緣,那麼測量物件的高度應儘量地往大了設定,這樣Profile Line相對的噪點就比較少
    narrow_perpendicular_ROI
wide_perpendiculr_ROI
  • 反之,如果Profile Line與被測直線邊緣越不垂直,應儘量減小測量物件的高度(右邊粗線為灰度值曲線,細線為一階導數值曲線)

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,由這兩組值最終生成一個分段函式。

  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

      • 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為特徵值種類數。