halcon視覺缺陷檢測之頻域和空間域轉換的方法詳解

理論基礎

一、頻率特徵是圖像的灰度變化特徵,低頻特徵是灰度變化不明顯,例如圖像整體輪廓,高頻特徵是圖像灰度變化劇烈,如圖像邊緣和噪聲。一個重要的經驗結論:低頻代表圖像整體輪廓,高頻代表了圖像噪聲,中頻代表圖像邊緣、紋理等細節。什麼時候使用傅里葉變換進行頻域分析?

  1. 具有一定紋理特徵的圖像,紋理可以理解爲條紋,如布匹、木板、紙張等材質容易出現。 
  2. 需要提取對比度低或者信噪比低的特徵。 
  3. 圖像尺寸較大或者需要與大尺寸濾波器進行計算,此時轉換至頻域計算,具有速度優勢。因爲空間域濾波爲卷積過程(加權求和),頻域計算直接相乘。

二、在halcon中,使用頻域進行檢測,有兩個步驟是比較關鍵的:

  1. 一個是生成合適的濾波器;
  2. 一個是空間域和頻域之間的轉換。

生成濾波器主要有如下算子:

gen_std_bandpass,
gen_sin_bandpass,
gen_gauss_filter,

gen_mean_filter, 
gen_derivative_filter,
gen_bandpass, 
gen_bandfilter, 
gen_highpass, 
gen_lowpass

空間域和頻域之間的轉換,主要有如下兩個關鍵算子:

rft_generic

fft_generic

這兩個算子的共同點:

  1. 這兩個算子都是進行快速傅里葉變換的算子

  2. 這兩個算子都可以進行空間域-》頻域和頻域-》空間域的變換,只需要針對參數Direction分別進行選擇,'to_freq'是進行的是空間域-》頻域的變換,'from_freq'是頻域-》空間域的變換。

  3. 針對參數ResultType,如果是'to_freq',那麼ResultType一般選擇'complex';如果是'from_freq',ResultType一般選擇'byte'(灰度圖像)。

這兩個算子的不同點:

  1.  rft_generic算子的輸入圖像是實值函數,fft_generic的輸入圖像是複數函數;從輸出的結果來看,rft_generic只需要計算和存儲了左半邊的複數圖像信息就可以了,因爲右半邊是共軛對稱的。因此從最終的輸出我們可以看到,只有左上和左下有DC成分。而fft_generic如果設定的是原點在左上角,那麼就會在四個角上有DC成分。

  2. fft_generic算子可以通過參數Mode設置原點的位置:如果設置的是'dc_edge',那麼原點在左上角;如果設置的是'dc_center',那麼就會將原點平移到中心位置。fft_generic算子一般會設置爲'dc_center'。對於rft_generic算子,因爲沒有設置項,所以默認原點位置爲左上角。

針對同一個圖像,進行空間域-》頻域、頻域-》空間域的轉換的時候,如果使用的是rft_generic算子,那麼兩個轉換就都使用該算子;如果使用的是fft_generic算子,那麼兩個轉換也都使用該算子,在對同一個圖像進行空間域和頻域的相互轉換時,不要交叉使用這兩個算子。

當然,從空間域到頻域的轉換,也可以使用算子fft_image,這個算子也是快速傅里葉變換,其實際效果相當於:

fft_generic(Image,ImageFFT,'to_freq',-1,'sqrt','dc_center','complex')

 

舉例說明

1、檢測布料表面劃痕

*《Halcon機器視覺算法原理與編程實戰》16-1
*清空當前窗口
dev_close_window ()
*讀取測試圖像
read_image (Image, 'data/cloth1')
*獲取圖像的寬
get_image_size (Image, Width, Height)
*創建顯示窗口,並設置窗口及繪製參數
dev_open_window_fit_size (0, 0, Width, Height, -1, -1, WindowHandle)
dev_display (Image)
dev_set_draw ('margin')
dev_set_line_width (3)
dev_set_color ('red')
*創建一個高斯濾波器,用於將傅里葉轉換後的圖像進行濾波
gen_gauss_filter (GaussFilter, 3.0, 3.0, 0.0, 'none', 'rft', Width, Height)
*開始檢測
*將測試圖像轉化爲單通道的灰度圖像
rgb1_to_gray (Image, ImageGray)
*對灰度圖像進行顏色反轉
invert_image (ImageGray, ImageInvert)
*對反轉後的圖像進行傅里葉變換
rft_generic (ImageInvert, ImageFFT, 'to_freq', 'none', 'complex', Width)
*對傅里葉圖像做卷積,使用之前創建的高斯濾波器作爲卷積核
convol_fft (ImageFFT, GaussFilter, ImageConvol)
*將卷積後的傅里葉圖像還原爲空間域圖像。可見圖像的突變部分得到了增強
rft_generic (ImageConvol, ImageFiltered, 'from_freq', 'n', 'real', Width)
*設置提取線條的參數
calculate_lines_gauss_parameters (17, [25,3], Sigma, Low, High)
*將圖像中的有灰度差異的線條提取出來
lines_gauss (ImageFiltered, Lines, Sigma, Low, High, 'dark', 'true', 'gaussian', 'true')
*將提取出的結果顯示出來
dev_display (Image)
dev_display (Lines)

2、傅里葉變換之劃痕檢測

*微信公衆號--機器視覺那些事兒
*檢測-FFT傅里葉變換之劃痕檢測
*對於檢測表面是具有一定紋理的比如:布匹、皮革、塑料等,針對這一類表面的檢測就不能單純依靠幀差或者背景差來完成,
*這種情況下,通過將圖像變換到頻域進行處理,提取缺陷分量後反變換到時域,然後通過Blob分析獲得缺陷的具體位置。

*重點說明:
*頻域處理部分的過程爲:
*1)先生成一個濾波器,此處生成的是正弦形狀的帶通濾波,使用的算子爲gen_sin_bandpass。
*2)然後再進行圖像的傅里葉變換,使用的算子爲rft_generic,此處需要注意參數的使用。
*3)使用之前的濾波器,對圖像在頻域進行卷積計算,從而增強高頻信息。
*4)最後對圖像進行傅里葉反變換,使用的算子依然是rft_generic,注意和第二步中的參數進行區分。在這一步,即得到了我們平時進行Blob分析的圖像。
*之後的處理分爲三部分:
*1)第一部分,先進行Blob分析後,篩選掉一些雜點。然後提取出保留區域所對應的圖像。
*2)第二部分進行亞像素處理,先提取出亞像素輪廓,使用的是lines_gauss算子;然後按照輪廓總長度進行輪廓篩選,從而得到劃痕的亞像素輪廓。至此,已經得到劃痕了。
*3)第三部分進行劃痕區域的處理,先將亞像素輪廓轉爲區域,使用的算子是gen_region_contour_xld;得到劃痕輪廓之後就可以將劃痕標記出來了。

* 首先,創建合適的帶通濾波
* 然後,輸入圖像在頻域中進行傅里葉變換和濾波,以便增強高頻信息
* 最後,再被轉換回空間域,增強的缺陷通過形態學進行之後的處理

dev_update_off ()
dev_close_window ()
* 讀圖像
read_image (Image, '檢測-FFT傅里葉變換之劃痕檢測.png')
*彩色轉灰度圖
count_channels (Image, Channels)
if (Channels == 3 or Channels == 4)
    rgb1_to_gray (Image, Image)
endif
* 翻轉圖像,亮變暗  暗變量
invert_image (Image, ImageInverted)
* 獲取圖像寬高
get_image_size (Image, Width, Height)
* dev_open_window (0, 0, Width, Height, 'black', WindowHandle)
dev_open_window_fit_image (Image, 0, 0, -1, -1, WindowHandle)
set_display_font (WindowHandle, 16, 'mono', 'true', 'false')
dev_display (Image)
* 
* Optimize the speed of the fast fourier transform
* 優化快速傅里葉變換的速度
* Message := 'Optimize the speed of the fast fourier transform.'
* Message[1] := 'Please wait...'
* disp_message (WindowHandle, Message, 'window', 12, 12, 'black', 'true')
* optimize_rft_speed (Width, Height, 'standard')
* disp_continue_message (WindowHandle, 'black', 'true')
* stop ()
* 
* Enhance the scratches by filtering in the frequency domain
* 通過在頻域中濾波來增強劃痕

* 生成具有正弦形狀的帶通濾波器
gen_sin_bandpass (ImageBandpass, 0.4, 'none', 'rft', Width, Height)
* 對一幅圖片的實部進行快速傅里葉變換的計算,將圖像轉爲傅里葉圖像
* 參數爲'to_freq',輸出圖像爲複數形式
* ImageInverted:輸入的圖片(輸入圖像需要爲背景爲暗,前景爲亮的圖像,一般需要先要將原始圖像反轉)
* ImageFFT:傅里葉變換後輸出的圖片
* 'to_freq':變換方向,傅里葉變換
* 'none':變換因子的規範
* 'complex':輸出圖片的數據類型,輸出圖像爲複數形式
* Width: 圖像的寬
rft_generic (ImageInverted, ImageFFT, 'to_freq', 'none', 'complex', Width)
* 對圖片用濾波器在頻域進行卷積運算
* ImageFFT: 輸入的圖片
* ImageBandpass:頻域濾波器
* ImageConvol:計算後的輸出圖像
convol_fft (ImageFFT, ImageBandpass, ImageConvol)
* 對濾波後的圖片進行傅里葉反變換
* 參數爲'from_freq',輸入圖像爲複數形式
rft_generic (ImageConvol, Lines, 'from_freq', 'n', 'byte', Width)
* 
* Segment the scratches by using morphology
* 使用形態分割劃痕

* 二值化
threshold (Lines, Region, 5, 255)
* 獲得連通域
connection (Region, ConnectedRegions)
* 特徵直方圖,按照面積特徵選擇區域
select_shape (ConnectedRegions, SelectedRegions, 'area', 'and', 5, 5000)
* 膨脹
dilation_circle (SelectedRegions, RegionDilation, 5.5)
* 區域聯合成一個區域
union1 (RegionDilation, RegionUnion)
* 摳圖
reduce_domain (Image, RegionUnion, ImageReduced)
* 檢測線條及其寬度
* 輸出亞像素直線輪廓
lines_gauss (ImageReduced, LinesXLD, 0.8, 3, 5, 'dark', 'false', 'bar-shaped', 'false')
* 聯合直線亞像素輪廓
union_collinear_contours_xld (LinesXLD, UnionContours, 40, 3, 3, 0.2, 'attr_keep')
* 按照輪廓的總長度來選擇亞像素輪廓
select_shape_xld (UnionContours, SelectedXLD, 'contlength', 'and', 15, 1000)
* 由亞像素輪廓生成區域
gen_region_contour_xld (SelectedXLD, RegionXLD, 'filled')
* 區域聯合
union1 (RegionXLD, RegionUnion)
* 膨脹
dilation_circle (RegionUnion, RegionScratches, 10.5)
* 
* Display the results
* 顯示標記出來的的直線劃痕
dev_set_draw ('margin')
dev_set_line_width (3)
dev_set_colored (12)
dev_display (Image)
dev_display (RegionScratches)

3、木板劃痕檢測

*http://www.ihalcon.com/read-13031-1.html
*缺陷檢測,將木板的劃痕提取出來
dev_update_off ()
dev_close_window ()
read_image (Image, '缺陷檢測木板劃痕提取.jpg')
*彩色轉灰度圖
count_channels (Image, Channels)
if (Channels == 3 or Channels == 4)
    rgb1_to_gray (Image, Image)
endif
get_image_size (Image, Width, Height)
dev_open_window_fit_size (0, 0, Width, Height, -1, -1, WindowHandle)
dev_display (Image)
*傅里葉變換去背景
fft_generic (Image, ImageFFT, 'to_freq', -1, 'sqrt', 'dc_center', 'complex')
gen_rectangle2 (Rectangle1, 308.5, 176.56, rad(-0), 179.4, 7.725)
gen_rectangle2 (Rectangle2, 306.955, 175, rad(-90), 180.765, 4.68)
union2 (Rectangle1, Rectangle2, UnionRectangle)
paint_region (UnionRectangle, ImageFFT, ImageResult, 0, 'fill')
fft_generic (ImageResult, ImageFFT1, 'from_freq', 1, 'sqrt', 'dc_center', 'byte')
*提取劃痕
threshold (ImageFFT1, Regions, 5, 240)
connection (Regions, ConnectedRegions)
select_shape (ConnectedRegions, SelectedRegions, 'area', 'and', 20, 99999)
union1 (SelectedRegions, RegionUnion)
dilation_rectangle1 (RegionUnion, RegionDilation, 5, 5)
connection (RegionDilation, ConnectedRegions1)
select_shape (ConnectedRegions1, SelectedRegions1, ['width','height'], 'and', [30,15], [150,100])
dilation_rectangle1 (SelectedRegions1, RegionDilation1, 11, 11)
union1 (RegionDilation1, RegionUnion1)
skeleton (RegionUnion1, Skeleton)
*顯示
dev_set_color ('red')
dev_display (Image)
dev_display (Skeleton)

 

halcon官方自帶的例子

detect_indent_fft.hdev

detect_mura_defects_texture.hdev

官方例子detect_indent_fft,使用了差分兩個高斯濾波器

detect_indent_fft.hdev
* Optimize the fft speed for the specific image size
optimize_rft_speed (Width, Height, 'standard')
* 
* Construct a suitable filter by combining two gaussian
* filters
Sigma1 := 10.0
Sigma2 := 3.0
gen_gauss_filter (GaussFilter1, Sigma1, Sigma1, 0.0, 'none', 'rft', Width, Height)
gen_gauss_filter (GaussFilter2, Sigma2, Sigma2, 0.0, 'none', 'rft', Width, Height)
sub_image (GaussFilter1, GaussFilter2, Filter, 1, 0)
* 
* Process the images iteratively
NumImages := 11
for Index := 1 to NumImages by 1
    * 
    * Read an image and convert it to gray values
    read_image (Image, 'plastics/plastics_' + Index$'02')
    rgb1_to_gray (Image, Image)
    * Perform the convolution in the frequency domain
    rft_generic (Image, ImageFFT, 'to_freq', 'none', 'complex', Width)
    convol_fft (ImageFFT, Filter, ImageConvol)
    rft_generic (ImageConvol, ImageFiltered, 'from_freq', 'n', 'real', Width)

 

姊妹篇

halcon視覺缺陷檢測常用的6種方法

 

參考文獻

  1. 微信公衆號:機器視覺那些事兒
  2. 《Halcon機器視覺算法原理與編程實戰》楊青

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章