天天看點

Halcon邊緣檢測和線條檢測(1),文章含自适應/動态二值化等算子

先看代碼實踐

dev_update_off ()
dev_close_window ()
 
*讀圖
read_image (Image, 'D:/1.bmp')
get_image_size (Image, Width, Height)
 
*測試提取邊緣
edges_image(Image,Amp,Dir,'lanser2',0.5,'none',-1,-1)
hysteresis_threshold(Amp,Margin,20,30,30)
 
*彩色轉灰階圖
count_channels (Image, Channels)
if (Channels == 3)
    rgb1_to_gray (Image, GrayImage)
*真彩色轉灰階圖
elseif (Channels == 4)
    decompose4 (Image, ImageR, ImageG, ImageB, ImageA)
    compose3 (ImageR, ImageG, ImageB, MultiChannelImage)
    rgb1_to_gray (MultiChannelImage, GrayImage)
endif
 
*顯示圖
dev_open_window_fit_image (Image, 0, 0, -1, -1, WindowHandle)
set_display_font (WindowHandle, 16, 'mono', 'true', 'false')
dev_display (Image)
 
*自适應二值化
median_image (Image, Median, 'circle', 3, 'mirrored')
auto_threshold(Median, Regions, 2)
 
*動态二值化
D := 100
mean_image(Image, Mean, D*2+1, D*2+1)
dyn_threshold(Image, Mean, Seg, 5, 'light')
regiongrowing (Image, Regions, 1, 1, 6, 1)
gen_contour_region_xld (Regions, Contours, 'border')
 
*threshold_sub_pix隻能取外輪廓
threshold_sub_pix(Image, Border, 128)
derivate_gauss(Image,Laplace,3,'laplace')
zero_crossing_sub_pix(Laplace,ZeroCrossings)
 
*測試soble
sobel_amp (Image, EdgeAmplitude1, 'thin_max_abs', 5)
sobel_amp (GrayImage, EdgeAmplitude2, 'thin_max_abs', 5)
 
*圖像的“邊緣”指的是:圖像中灰階有明顯跳變的地方。如果在圖中畫一條“有一定寬度的線”,那麼線的兩側應該都可以提取到邊緣。
*而線條提取的算子(例如lines_gauss)提取的是這條“有一定寬度的線”的“骨架線”,它一般隻有一根。
*提取骨架線條
MaxLineWidth := 10
Contrast := 20
calculate_lines_gauss_parameters (MaxLineWidth, Contrast, Sigma, Low, High)
lines_gauss (GrayImage, Lines, Sigma, Low, High, 'dark', 'true', 'parabolic', 'true')
count_obj (Lines, Number)
* lines_gauss (GrayImage, Lines, 2.3, 0.0, 0.7, 'dark', 'true', 'parabolic', 'true')
*亞像素提取邊緣
*Alpha數值越大,輪廓越圓滑
edges_sub_pix (GrayImage, Edges1, 'canny', 1, 3, 5)
*edges_sub_pix (GrayImage, Edges2, 'canny_junctions', 1, 5, 10)
*edges_sub_pix (GrayImage, Edges3, 'lanser1', 0.5, 20, 40)
*edges_sub_pix (GrayImage, Edges4, 'lanser2', 0.5, 20, 40)
*edges_sub_pix (GrayImage, Edges5, 'deriche1', 0.5, 20, 40)
*edges_sub_pix (GrayImage, Edges6, 'deriche2', 0.5, 20, 40)
*edges_sub_pix (GrayImage, Edges7, 'shen', 0.5, 20, 40)
*edges_sub_pix (GrayImage, Edges8, 'mshen', 0.5, 20, 40)
*edges_sub_pix (GrayImage, Edges9, 'sobel', 0.5, 20, 40)
 
*合并鄰近的XLD,使得細小線段拼接起來
*select_contours_xld (Edges1, SelectedContours, 'contour_length', 5, 99999, -0.5, 0.5)
union_adjacent_contours_xld (Edges1, UnionContours, 5, 1, 'attr_keep')
*根據輪廓特征選擇XLD
*這個算子用到的輪廓特征如下:contour-length輪廓長度,direction輪廓回歸線方向,用參數min1,max1;
*curvature曲率,輪廓XLD到回歸線的平均距離和标準差各有範圍選擇,平均距離使用參數min1,max1;
*标準差使用min2,max2,條件是在兩參數的大小範圍之内。
select_contours_xld (UnionContours, SelectedContours, 'contour_length', 10, 99999, -0.5, 0.5)
*close_contours_xld(SelectedContours, ClosedContours)
count_obj(SelectedContours, NumberContours)
stop()
for i := 1 to NumberContours by 1
    select_obj (SelectedContours, ObjectSelected, i)
    length_xld (ObjectSelected, Length)
    *計算xld的面積以及中心位置
    area_center_xld(ObjectSelected, area, row, column, PointOrder)
    get_contour_xld (ObjectSelected, row, col)
endfor
 
dev_set_color ('green')
dev_display (Image)
dev_display (Lines)
dev_display (Edges1)
stop()
 
*測試彩色
edges_color_sub_pix (Image, EdgesColor, 'canny', 1, 5, 10)
dev_display (Image)
dev_set_color ('blue')
dev_display (EdgesColor)
 
*測試HSV
decompose3(Image, r, g, b)
trans_from_rgb(b, g, r, h, s, v, 'hsv')
Sigma := 4
auto_threshold (h, Region1, Sigma)
auto_threshold (s, Region2, Sigma)
auto_threshold (v, Region3, Sigma)
edges_sub_pix (r, Edge1, 'canny', 1, 2, 5)
edges_sub_pix (g, Edge2, 'canny', 1, 2, 5)
edges_sub_pix (b, Edge3, 'canny', 1, 2, 5)
edges_sub_pix (h, Edge4, 'canny', 1, 2, 5)
edges_sub_pix (s, Edge5, 'canny', 1, 2, 5)
edges_sub_pix (v, Edge6, 'canny', 1, 2, 5)
stop ()

      

再看理論知識:

一、邊緣提取

1、設定ROI興趣區域

2、快速二值化,并連接配接相鄰區域。

這樣做的目的是進一步減少目标區域,通過二值化将目标區域大概輪廓提取出來

3、提取最接近目标區域的輪廓

常用函數有boundary,gen_contour_region_xld

4、根據自己的需求提取需要的初步輪廓

5、将初步提取的初步輪廓進行膨脹操作

6、将膨脹後的區域和原圖進行減操作(在這步之前有可能需要對原圖進行高斯濾波)。這樣就能得到隻有邊緣的真實圖像

7、用canny或其他算子(根據需要)提取亞像素輪廓,一般使用edges_sub_pix函數

8、處理和計算

得到真實的邊緣XLD後你可能需要進一步處理得到你想要的線、弧等。

你可能用到的函數segment_contours_xld(分割)  union_collinear_contours_xld(聯合相鄰或相同角度直線)select_contours_xld(提取想要的輪廓) union_cocircular_contours_xld(聯合相同圓)等等

得到輪廓後如果你不知道怎麼處理後得到你想要的東西(線、弧、圓、角、矩形)你都可以将輪廓轉化為點,然後用點集合來拟合任何你想要的東西。

二、BLOB分析檢測(前面一篇有詳細講解,本騙隻講思路)

(1)應用ROI,可以使Blob分析加速。

(2)比對ROI區域或圖像,詳将GUIDEIIB以形狀為基礎的比對。

(3)校正圖像<經常用來去除鏡頭畸變或把圖像轉換到參考點視角,如雙目視覺時的圖像校正>

(4)圖像前處理

(5)引用分割參數

(6)分割圖像

(7)區域處理

(8)特征提取

(9)把提取的結果轉換到世界坐标中

(10)結果可視化。

   相機的标定和矯正不在本篇的學習之中。直接講提取BLOB

1、一般先使用均值濾波去噪

2、利用去噪圖像與平滑圖像的OFFSET提取區域邊緣,常見函數dyn_threshold

3、提取連通域dyn_threshold

4、根據形狀或是灰階等特征來提取你想要的blob。

另一種方法就是分水嶺算法

watersheds (ImageGauss, Basins, Watersheds)/

1、對圖像進行高斯濾波

還有的圖形更簡單直接二值化就可以啦

bin_threshold (Fin, Dark) //分割圖像,輸出Dark區域,Fin已經被處理為區域//

difference (Fin, Dark, Background) //計算Fin與Dark兩個區域的補集//

還有個函數應該說是讓你高興還是沮喪呢,以為一個函數就可以直接提取你想要的,但是參數很難調整

lines_gauss(Image, Lines, 6, 0.3, 0.5, 'light', 'true', 'gaussian', 'true')

三、贓物檢測

1、得到兩個不同高斯标準差的高斯積卷

2、對原始圖像進行傅裡葉變換'to_fre'

3、用之前的積卷對圖像做積卷濾波

4、傅裡葉反變換‘from_fre’

二值化算子與例程

auto_threshold

dyn_threshold

var_threshold

binary_threshold

fast_threshold

fast_threshold_vs_threshold

histo_to_thresh

local_threshold

threshold

threshold_sub_pix

C:\Users\Public\Documents\MVTec\HALCON-19.11-Progress\examples\hdevelop\Segmentation\Threshold

Halcon中實作Otsu 算法

https://blog.csdn.net/IntegralforLove/article/details/100102105

Halcon算子學習:圖像門檻值分割-threshold、binary_threshold、dyn_threshold算子

https://blog.csdn.net/Vichael_Chan/article/details/102576060

1.threshold-全局固定門檻值分割

2.Binary Threshold-自動全局門檻值分割

3.dyn_threshold-局部動态門檻值分割

4.var_threshold算子-均值和标準偏差局部門檻值分割

5.dual_threshold-雙重門檻值分割(有符号圖像的門檻值算子)

6.auto_threshold-自動全局門檻值分割

7.fast_threshold-快速全局門檻值分割

8.watersheds-分水嶺算法分割

---

參考文章:

提取線條的lines_color、lines_facet、 lines_gauss算子

halcon之共線連接配接union_collinear_contours_xld

用halcon提取衣服徽章

官方自帶的例子:

measure_grid.hdev

lines_gauss.hdev

edge_segments.hdev

rim_simple.hdev

sort_contours_xld.hdev

繼續閱讀