OpenCV學習筆記(六) 濾波器 形態學操作(腐蝕、膨脹等)


轉自:OpenCV 教程 

另附:計算機視覺:算法與應用(2012),Learning OpenCV(2009)

平滑圖像:濾波器

平滑 也稱 模糊, 是一項簡單且使用頻率很高的圖像處理方法。平滑處理的用途有很多, 但是在本教程中我們僅僅關注它減少噪聲的功用 (其他用途在以后的教程中會接觸到)。平滑處理時需要用到一個 濾波器 。最常用的濾波器是 線性 濾波器。不妨把 濾波器 想象成一個包含加權系數的窗口,當使用這個濾波器平滑處理圖像時,就把這個窗口滑過圖像。

歸一化濾波器 (Normalized Box Filter)

最簡單的濾波器,輸出像素值是核窗口內像素值的 均值 ( 所有像素加權系數相等)。

blur( src, dst, Size( i, i ), Point(-1,-1) );
  • src: 輸入圖像
  • dst: 輸出圖像
  • Size( w,h ): 定義內核大小( w 像素寬度, h 像素高度)
  • Point(-1, -1): 指定錨點位置(被平滑點), 如果是負值,取核的中心為錨點。

高斯濾波器 (Gaussian Filter)

最有用的濾波器 (盡管不是最快的)。 高斯濾波是將輸入數組的每一個像素點與 高斯內核 卷積將卷積和當作輸出像素值。

GaussianBlur( src, dst, Size( i, i ), 0, 0 );
  • src: 輸入圖像
  • dst: 輸出圖像
  • Size(w, h): 定義內核的大小(需要考慮的鄰域范圍)。 w 和 h 必須是正奇數,否則將使用 \sigma_{x} 和 \sigma_{y} 參數來計算內核大小。
  • \sigma_{x}: x 方向標准方差, 如果是 0 則 \sigma_{x} 使用內核大小計算得到。
  • \sigma_{y}: y 方向標准方差, 如果是 0 則 \sigma_{y} 使用內核大小計算得到。.

中值濾波器 (Median Filter)

中值濾波將圖像的每個像素用鄰域 (以當前像素為中心的正方形區域)像素的 中值 代替 。

medianBlur ( src, dst, i );
  • src: 輸入圖像
  • dst: 輸出圖像, 必須與 src 相同類型
  • i: 內核大小 (只需一個值,因為我們使用正方形窗口),必須為奇數。

雙邊濾波 (Bilateral Filter)

目前我們了解的濾波器都是為了 平滑 圖像, 問題是有些時候這些濾波器不僅僅削弱了噪聲, 連帶着把邊緣也給磨掉了。為避免這樣的情形 (至少在一定程度上 ), 我們可以使用雙邊濾波。類似於高斯濾波器,雙邊濾波器也給每一個鄰域像素分配一個加權系數。 這些加權系數包含兩個部分, 第一部分加權方式與高斯濾波一樣,第二部分的權重則取決於該鄰域像素與當前像素的灰度差值。

詳細的解釋可以查看 鏈接

bilateralFilter ( src, dst, i, i*2, i/2 );
  • src: 輸入圖像
  • dst: 輸出圖像
  • d: 像素的鄰域直徑
  • \sigma_{Color}: 顏色空間的標准方差
  • \sigma_{Space}: 坐標空間的標准方差(像素單位)

利用掩碼(kernel mask)簡單濾波:filter2D

矩陣的掩碼操作很簡單。其思想是:根據掩碼矩陣(也稱作核)重新計算圖像中每個像素的值。掩碼矩陣中的值表示近鄰像素值(包括該像素自身的值)對新像素值有多大影響。從數學觀點看,我們用自己設置的權值,對像素鄰域內的值做了個加權平均。

以下是利用filter2D函數實現Laplace filter來加強圖像對比度的實例(samples\cpp\tutorial_code\core\mat_mask_operations):

Mat kern = (Mat_<char>(3,3) <<  0, -1,  0,
                               -1,  5, -1,
                                0, -1,  0);
filter2D(I, K, I.depth(), kern );

filter2D(src, dst, ddepth , kernel, anchor, delta, BORDER_DEFAULT );
  • src: 源圖像
  • dst: 目標圖像
  • ddepthdst 的深度。若為負值(如 -1),則表示其深度與源圖像相等。
  • kernel: 用來遍歷圖像的核
  • anchor: 核的錨點的相對位置,其中心點默認為 (-1, -1) 。
  • delta: 在卷積過程中,該值會加到每個像素上。默認情況下,這個值為 0 。
  • BORDER_DEFAULT: 這里我們保持其默認值,更多細節將在其他教程中詳解

形態學操作之:腐蝕膨脹(Eroding and Dilating)

形態學操作就是基於形狀的一系列圖像處理操作。通過將 結構元素 作用於輸入圖像來產生輸出圖像。最基本的形態學操作有二:腐蝕與膨脹(Erosion 與 Dilation)。 他們的運用有:

  • 消除噪聲
  • 分割(isolate)獨立的圖像元素,以及連接(join)相鄰的元素。
  • 尋找圖像中的明顯的極大值區域或極小值區域。

膨脹dilate

將圖像 A 與任意形狀的內核 (B),通常為正方形或圓形,進行卷積。內核 B 有一個可定義的 錨點, 通常定義為內核中心點。將內核 B 划過圖像,將內核 B 覆蓋區域的最大相素值提取,並代替錨點位置的相素。顯然,這一最大化操作將會導致圖像中的亮區開始”擴展” (因此有了術語膨脹 dilation )。

腐蝕erode

將內核 B 划過圖像,將內核 B 覆蓋區域的最小相素值提取,並代替錨點位置的相素。相應地,暗區會開始“腐蝕”。

Mat element = getStructuringElement( dilation_type,
                                      Size( 2*dilation_size + 1, 2*dilation_size+1 ),
                                      Point( dilation_size, dilation_size ) );

dilate( src, dilation_dst, element );
erode( src, erosion_dst, element );

dilate和erode參數相同:

  • src: 原圖像
  • erosion_dst: 輸出圖像
  • element: 腐蝕操作的內核。如果不指定,默認為一個簡單的 3x3 矩陣。否則,我們就要明確指定它的形狀,可以使用函數getStructuringElement

getStructuringElement的參數:

  • dilation_type = 矩形: MORPH_RECT 或者 交叉形: MORPH_CROSS  或者  橢圓形 MORPH_ELLIPSE
  • 內核大小
  • 錨點位置(若不指定,則默認為中心位置)

更多形態學變換

更直觀的圖參見此處

開運算 (Opening)

通過先對圖像腐蝕再膨脹實現的。能夠排除小團塊物體(假設物體較背景明亮)。

dst = open( src, element) = dilate( erode( src, element ) )

閉運算(Closing)

通過先對圖像膨脹再腐蝕實現的。能夠排除小型黑洞(黑色區域)。

dst = close( src, element ) = erode( dilate( src, element ) )

形態梯度(Morphological Gradient)

膨脹圖與腐蝕圖之差,能夠保留物體的邊緣輪廓。

頂帽(Top Hat)與黑帽(Black Hat)

頂帽:原圖像與開運算結果圖之差

dst = tophat( src, element ) = src - open( src, element )

黑帽:閉運算結果圖與原圖像之差

dst = blackhat( src, element ) = close( src, element ) - src

調用函數:morphologyEx

Mat element = getStructuringElement( morph_elem, Size( 2*morph_size + 1, 2*morph_size+1 ), Point( morph_size, morph_size ) );

/// 運行指定形態學操作
morphologyEx( src, dst, operation, element );

參數列表:

  • src : 原 (輸入) 圖像
  • dst: 輸出圖像
  • operation: 需要運行的形態學操作。 我們有5個選項(注意:取值范圍為2~6):
    • Opening: MORPH_OPEN : 2
    • Closing: MORPH_CLOSE: 3
    • Gradient: MORPH_GRADIENT: 4
    • Top Hat: MORPH_TOPHAT: 5
    • Black Hat: MORPH_BLACKHAT: 6
  • element: 內核,可以使用函數:get_structuring_element:getStructuringElement <> 自定義。

 


免責聲明!

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



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