例程:detect_indent_fft.hdev
說明:這個程序展示了如何利用快速傅里葉變換(FFT)對塑料制品的表面進行目標(缺陷)的檢測,大致分為三步:
首先,我們用高斯濾波器構造一個合適的濾波器(將原圖通過高斯濾波器濾波);
然后,將原圖和構造的濾波器進行快速傅里葉變換;
最后,利用形態學算子將缺陷表示在濾波后的圖片上(在缺陷上畫圈)。
注:代碼中綠色部分為個人理解和注釋,其余為例程中原有代碼
*Initialization(初始化) dev_updata_off() //這一句包含如下三個算子: //dev_updata_pc(‘off’) 關閉更新程序計數器 //dev_updata_var(‘off’) 關閉更新變量窗口 //dev_updata_window(‘off’) 關閉更新圖像窗口(即通過命令來顯示想要在圖像窗口顯示的圖片) dev_close_window() //關閉活動的圖像窗口 read_image(Image,’plastics/
plastics_01’) //載入圖片 //參數說明:為讀入圖片命名(Image) // 文件名(’plastics/plastics_01’) get_image_size(Image,Width,height) //獲取圖片的長寬; //參數說明:之前讀入或生成的圖片(Image) // 圖片的寬(Width) // 圖片的高(Height) dev_open_window(0,0,Width,Height,’Black’,WindowHandle) //打開一個新的圖像窗口 //參數說明:起始坐標(0,0) // 大小(Width,Height) // 背景顏色(’Black’) // 窗口句柄(WindowHandle) set_display_font (WindowHandle,14,’mono’,’ture’,’false’)//設置不依賴操作系統的字體 //參數說明:窗口句柄(WindowHandle) // 字體大小(14) // 字體類型(’mono’) // 是否黑體(’ture’) // 是否傾斜(’false’) dev_set_draw(‘Margin’) //定義區域填充模式 //參數說明:填充模式(’Margin’或者’Fill’) dev_set_line_width(3) //設置輸出區域輪廓線的線寬 //可以修改參數來看最后缺陷區域標示的區別 dev_set_color(’red’) //設置一種或者多種輸出顏色
* *Optimize the fft speed for the specific image size(根據指定圖像大小進行fft速度最優化) optimize_rft_speed(Width,Height,’standard’) //對指定大小的圖片的fft速度進行優化 //參數說明:圖片大小(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) //在頻域生成兩個高斯濾波器 //參數說明:生成的高斯濾波器(GaussFilter) // 空域中高斯在主方向上的標准差(Sigma) // 空域中高斯在正交於主方向的方向上的標准差(Sigma) // 濾波器主方向的角度(0.0) // 濾波器的規范(’none’) // 直流項在頻域的位置(’rft’) // 圖片的大小(Width,Height) sub_image(GaussFilter1,GaussFilter2,Filter,1,0) //兩圖片相減(灰度) //sub_image(ImageMinuend, ImageSubtrahend : ImageSub : Mult, Add : ) //g' := (g1 - g2) * Mult + Add //以上為函數原型以及運算公式
* *Process the images iteratively(對圖像進行迭代運算) NumImages := 11 For Index := 1 to NumImages by 1 //for循環從1到NumImages,步長為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)//對計算一幅圖片實部進行快速傅里葉變換 //參數說明:輸入的圖片(Image) // 傅里葉變換后輸出的圖片(ImageFFT) // 變換方向(’to_freq’或’from_freq’) // 變換因子的規范(’none’) // 輸出圖片的數據類型(’complex’) // 圖片的寬(Width) convol_fft(ImageFFT,Filter,ImageConvol) //對圖片用一個濾波器在頻域進行卷積運算 //參數說明:輸入的圖片(ImageFFT) // 頻域濾波器(Filter) // 運算后輸出的結果 rft_generic(ImageConcol,ImageFiltered,’from_freq’,’n’,’real’,Width) //對濾波后的圖片進行傅里葉反變換
* *Process the filtered image gray_range_rect(ImageFiltered,ImageResult,10,10)//用一個矩形掩膜計算像素點的灰度范圍 //參數說明:輸入的圖片(ImageFiltered) // 輸出的灰度范圍圖(ImageResult) // 矩形掩膜大小(10,10) min_max_rect(ImageResult,ImageResult,0,Min,Max,Range)//判斷區域內灰度值的最大和最小值 //參數說明:待分析圖片區域(ImageResult) // 圖片(ImageResult) // 被去除的直方圖兩邊像素點所
// 占總像素數的百分比(0) // 得到的最小值最大值及灰度值范圍(Min,Max,Range) threshold(ImageResult,RegionDynThresh,max([5.55,Max*0.8]),255)//利用全局閾值對圖像進行分割 //參數說明:輸入的圖片(ImageResult) // 分割后得到的區域(RegionDynThresh) // 閾值(max([5.55,Max*0.8]),255) // 公式:MinGray <= g <= MaxGray connection(RegionDynThresh,ConnectedRegions) //計算區域內的連通部分 //參數說明:輸入的圖片(RegionDynThresh) // 得到的連通區域(ConnectedRegions) select_shape (ConnectedRegions,SelectedRegions,’area’,’and’,4,99999)//根據指定的形態特征選擇區域 //參數說明:輸入的圖片(ConnectedRegions) // 滿足條件的區域(SelectedRegions) // 將要計算的形態特征(’area’) // 獨立特征間的連接關系(’and’) // 特征的最小限制(4) // 特征的最大限制(99999) union1(SelectedRegions,RegionUnion) //返回包含所有區域的集合 //參數說明:包含所有區域的待計算區域的圖片(tedRegions) // 所有輸入區域合(RegionUnion) closeing_circle(RegionUnion,RegionClosing,10)//用一個圓圈來封閉一個區域 //參數說明:將要被封閉的區域(RegionUnion) // 被封閉的區域(RegionClosing) // 圓圈的半徑(10) connection(RegionClosing,ConnectedRegions1) select_shape(ConnectedRegions1,SelectedRegions1,’area’,’and’,10,99999)
area_center(SelectedRegions1,Area,Row,Column) //計算區域的面積以及中心位置 //參數說明:待計算的區域(SelectedRegions1) // 區域的面積(Area) // 區域中心的行(Row) // 區域中心的列(Column)
* *Display the results dev_display(Image) //顯示原圖 Number := |Area| //將區域面積賦給Number用於后面檢查是否存在缺陷 if(Number) gen_circle_contour_xld(ContCircle,Row,Column,gen_tuple_const(Number,30),gen_tuple_const(Number,0), gen_tuple_const(Number,rad(360)),’positive’,1)//構造一個與設定的圓弧或圓相一致的邊界 //參數說明:生成的邊界(ContCircle) // 圓弧或圓的中心坐標(Row,Cloumn) // 圓弧或圓的半徑(gen_tuple_const(Number,30)) // 圓弧或圓的起始角度(gen_tuple_const(Number,0)) // 圓弧或圓的結束角度(gen_tuple_const(Number,rad(360))) // 不明白是什么意思 // 相鄰兩點間的距離(1) ResultMessage := [‘Not OK’,Number + ‘defect(s) found’] Color := [‘red’,’black’] dev_display(ContCircle) else ResultMessage := ‘OK’ Color := ‘forest green’ endif disp_message(WindowHandle,ResultMessage,’window’,12,12,Color,’ture’) if(Index#NumImages) disp_continue_message(WindowHandle,’black’,’ture’) stop() endif endfor
算法講解:在實際的表面缺陷檢測系統中,針對的檢測表面很多是具有一定紋理的比如:布匹、皮革、塑料等,針對這一類表面的檢測就不能單純依靠幀差或者背景差來完成,因為背景的紋理不可能和當前圖像的紋理完全相同。因此,本例程的算法通過將圖像變換到頻域進行處理,提取缺陷分量后反變換到時域,獲得缺陷的具體位置。
高斯濾波器:在本算法中,在一開始就構造了兩個高斯濾波器,高斯濾波器是一種線性平滑濾波器,適用於消除高斯噪聲。濾波器的實質是對信號進行濾波,濾除不需要的部分,得到想要的部分。一個低通的濾波器可以濾除高頻信號,對於圖像來說,噪聲和邊緣往往集中在高頻分量,因此低通能夠降噪,但是也能造成圖像的模糊。
本文關鍵:本文的關鍵就是使用兩個低通濾波器,進行相減后構造了一個帶阻濾波器來提取缺陷分量。這就需要保證在實際的待檢測表面中缺陷所處的頻率范圍要和背景以及噪聲有明顯的差異,並且帶阻的頻率選擇要合適。通過帶阻濾波后獲得的頻率成分對背景中的紋理要有明顯的抑制,並且突出缺陷成分,進行傅里葉反變換后重構的圖像就是缺陷圖像,經過簡單的分割就能很容易得到缺陷了。