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