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

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

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

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

歸一化濾波器 (Normalized Box Filter)
最簡單的濾波器,輸出像素值是核窗口內像素值的 均值 ( 所有像素加權係數相等)。

1
blur( src, dst, Size( i, i ), Point(-1,-1) );
src: 輸入圖像
dst: 輸出圖像
Size( w,h ): 定義內核大小( w 像素寬度, h 像素高度)
Point(-1, -1): 指定錨點位置(被平滑點), 如果是負值,取核的中心爲錨點。
高斯濾波器 (Gaussian Filter)
最有用的濾波器 (儘管不是最快的)。 高斯濾波是將輸入數組的每一個像素點與 高斯內核 卷積將卷積和當作輸出像素值。

1
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)
中值濾波將圖像的每個像素用鄰域 (以當前像素爲中心的正方形區域)像素的 中值 代替 。

1
medianBlur ( src, dst, i );
src: 輸入圖像
dst: 輸出圖像, 必須與 src 相同類型
i: 內核大小 (只需一個值,因爲我們使用正方形窗口),必須爲奇數。
雙邊濾波 (Bilateral Filter)
目前我們瞭解的濾波器都是爲了 平滑 圖像, 問題是有些時候這些濾波器不僅僅削弱了噪聲, 連帶着把邊緣也給磨掉了。爲避免這樣的情形 (至少在一定程度上 ), 我們可以使用雙邊濾波。類似於高斯濾波器,雙邊濾波器也給每一個鄰域像素分配一個加權係數。 這些加權係數包含兩個部分, 第一部分加權方式與高斯濾波一樣,第二部分的權重則取決於該鄰域像素與當前像素的灰度差值。

詳細的解釋可以查看 鏈接。
1
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):

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

1
filter2D(src, dst, ddepth , kernel, anchor, delta, BORDER_DEFAULT );
src: 源圖像
dst: 目標圖像
ddepth: dst 的深度。若爲負值(如 -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 覆蓋區域的最小相素值提取,並代替錨點位置的相素。相應地,暗區會開始“腐蝕”。

1
2
3
4
5
6
Mat element = getStructuringElement( dilation_type,
Size( 2dilation_size + 1, 2dilation_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
1
2
3
4
Mat element = getStructuringElement( morph_elem, Size( 2morph_size + 1, 2morph_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 <> 自定義。

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