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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM