Halcon編程-基於紋理的mara檢測


      表面瑕疵檢測是機器視覺領域非常重要的一個應用。機器視覺是集光學、機電和計算機三個領域的一門不算新的技術。但目前表面瑕疵檢測在學界主要是計算機專業或者控制專業瞄准圖像處理方向在做,而視覺光學系統這一塊主要是光學工程專業在做。很少有研究者把這三塊都結合的很好,而國內做這機器視覺(注意是機器視覺 不是計算機視覺)基本上都是小公司。

    軟件這一塊就不說了,國內的整體軟件環境不好。據我所知,日本、德國和美國在機器視覺方面有很多相對成熟的軟件。中國農業大學的陳兵旗教授在留日期間弄過很多機器視覺方面的農業機器人,同時他也寫過一本書介紹視覺圖像處理,后面還附錄了他們自己主推的軟件。德國的軟件就是下面要介紹的halcon。提到halcon就有必要和開源的opencv進行對比,opencv在圖像處理方面也是小有名氣,但是其成型的圖像模塊函數並不多,而且由於是開源,並沒有專門對各種圖像處理領域方面的檢測需求進行擴展,還是那句話,畢竟是開源。

    halcon是商業軟件,國內主要是大恆公司在代理,其在圖像處理方面,特別是檢測測量方面有很多優勢。下面我以一個例子在介紹halcon圖像算法開發過程。

      啟動軟件,ctrl+E彈出例程,選擇表面檢測中的detect_mura_defects_texture 。這個是液晶面板上的mura 損傷 。附錄上張存在損傷的圖像     

   在雜亂的紋理上出現的黑色區域就是損傷。如何檢測呢?

代碼如下:

 * this example shows how to detect mura defects

* in highly textured images
*
dev_close_window ()
dev_update_off ()
Path := 'lcd/mura_defects_texture_'
read_image (Image, Path+'01')
get_image_size (Image, Width, Height)
dev_open_window (0, 0, 640, 480, 'black', WindowHandle)
set_display_font (WindowHandle, 14, 'courier', 'true', 'false')
dev_set_draw ('margin')
dev_set_line_width (3)
dev_set_color ('red')
for f := 1 to 2 by 1
read_image (Image, Path+f$'.2i')
decompose3 (Image, R, G, B)
* defects are characterized by dark patches. Hence, by substracting the
* estimated background illumination from the original image the
* defects become more apparent
estimate_background_illumination (B, ImageFFT1)
sub_image (B, ImageFFT1, ImageSub, 2, 100)
* median filter smooths out the fine texture, simplifying the following
* segmentation and final detection of defects
median_image (ImageSub, ImageMedian, 'circle', 9, 'mirrored')
watersheds_threshold (ImageMedian, Basins, 20)
* dark patches corresponding to defects have a very low energy
cooc_feature_image (Basins, ImageMedian, 6, 0, Energy, Correlation, Homogeneity, Contrast)
tuple_find (sgn(Energy-0.05), -1, Indices)
select_obj (Basins, Defects, Indices+1)
*
dev_display (Image)
dev_display (Defects)
count_obj (Defects, NDefects)
disp_message (WindowHandle, NDefects+' \'mura\' defects detected', 'window', -1, -1, 'red', 'true')
if (f < 2)
disp_continue_message (WindowHandle, 'black', 'true')
stop ()
endif
endfor

 

    1對彩色圖像進行R G B分解,選取B作為后續圖像。這個原因是通過實驗處理的,在B圖像下黑色斑和背景差異最大吧。

    2 生成背景模板,將圖像傅里葉變換到頻域中,通過高斯濾波,然后傅里葉反變換回來,得到的圖像就是背景模板

     3 背景差分。采用以下函數,增強兩幅圖像的差異

sub_image ( ImageMinuend, ImageSubtrahend : ImageSub : Mult, Add : )

ImageSub=(ImageMinuend-ImageSubtrahend)*Mult+Add

     4 分水嶺算法分割,在分割之前采用中值濾波來抑制小斑點或細線。分水嶺后,圖像分割為多個輪廓(region)。

     5 計算多個輪廓region的灰度信息,包括能量。相關度、同一度、對比度,通過灰度共生矩陣。 前面的兩個參數是灰度級和方向,灰度級是2^,方向即灰度共生矩陣方向。

     6 根據能量信息對多個region進行篩選,篩選后的region就是檢測結果。

Halcon::tuple_find ((Energy-0.05).Sgn(), -1, &Indices);
image_opencv_test=m_ip->HImageToIplImage(m_hoImage);
int number=Indices.Num();
for (int i=0;i<number;i++)
{
Halcon::HTuple new_Indices;
new_Indices[0]=Indices[i].I()+1;
Halcon::select_obj (Basins, &Defects, new_Indices);
Hlong x1,x2,y1,y2;
Halcon::smallest_rectangle1(Defects,&y1,&x1,&y2,&x2);
cvRectangle(image_opencv_test,cvPoint(x1,y1),cvPoint(x2,y2),cvScalar(0,0,255),2,8,0);
}

    判斷能量是否大於0.05,通過sgn函數將大於0.05的置1,小於的置-1。通過find

在(Energy-0.05).Sgn()中尋找-1出現的位置,注意這個位置是從0開始的。貌似這個是經過人為排序的,所以indices 中就是前三個 0 1 2
    select_obj (Basins, &Defects, new_Indices);是從Basins提取序號為new_Indices的region 。為什么重新定義一個HTuple 因為HTuple實際上是個數組。find后得到的就是一個indices 數組,里面存在三個數。 
select_obj 的參數必須是HTuple,也就是數組,所以只能重新定義,而且序號從1開始,因此要加1,只能獲取數組中的值加1,

獲取的代碼為new_Indices[0]=Indices[i].I()+1; 也就是說數組中的值可以直接訪問,然后轉化為需要的類型。
這是我弄的比較笨的方法,直接通過halcon轉化c++代碼,只有一句。我覺得還是單個取出來比較靠譜。

貼一個檢測結果吧:

 
        
 



   

 


免責聲明!

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



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