計算機視覺 OpenCV Android | 影象操作之 統計排序濾波、邊緣保留濾波
1.統計排序濾波
上節筆記中提到的 均值模糊、高斯模糊
兩種影象模糊操作都屬於 影象的線性濾波
,
本文則首先將筆記OpenCV中存在的幾種 基於統計排序的濾波器
,
-
即
中值濾波
、最大值
與最小值濾波
, -
這幾種濾波器在特定場合與應用場景下,也經常用來(
劃重點,對應濾波的作用!!!
)消除影象噪聲
(中值濾波
可以抑制椒鹽噪聲;
最大值濾波
可以填充閉合區域;
最小值濾波
可以去除小的影象噪聲或者影象元素物件的大小絲黏連)
;或者
抑制影象畫素極小值與極大值
(最大值
與最小值濾波
)。
1.1.中值濾波
-
中值濾波同樣也需要一個
卷積核
,與卷積濾波不同的是,它
不會用卷積核的每個係數與對應的畫素值做算術計算
,而是把對應的畫素值做
排序
,取中間值
作為輸出。
- 具體說明如圖所示:
-
線性濾波
是一個自帶有/設定有
係數的“實”模板
; -
中值濾波
是有一個只有濾波特性,沒有設定係數
的“空”模板
; - 運算邏輯順序概況:
“空”模板
移動,套/撈
與模板重合的N×N個畫素值上來,
對套上來的值排序,取中值;
置回模板核中心格子下重合的畫素塊;
中值濾波
的相關API函式處於 Imgproc包
中,完整的說明如下:
-
medianBlur(Mat src, Mat dst, int ksize)
src
:表示輸入影象,當
ksize
為3、5
的時候輸入影象可以為浮點數
或者整數型別
,當
ksize大於5
的時候,則只能為位元組型別影象
,即CV_8UC
。dst
:表示中值濾波以後輸出的影象
,其型別與輸入影象保持一致
。ksize
:表示上圖中模板的大小,常見為
3、5
,注意模板大小
必須為奇數
而且必須大於1
。
呼叫此函式實現中值濾波的相關程式碼如下:
Mat src = Imgcodecs.imread(fileUri.getPath()); if(src.empty()){ return; } Mat dst = new Mat(); Imgproc.medianBlur(src, dst, 5);
劃重點!!!
- 中值濾波對影象的
椒鹽噪聲
有很明顯的抑制作用
,是一個很好的影象降噪的濾波函式
。
!!!
1.2.最大值與最小值濾波
-
最大值與最小值濾波和中值濾波極其相似,
唯一不同的
就是對於排序
之後的畫素陣列,前兩者分別
用最大值或者最小值
來取代中心畫素點
作為輸出
;
- 具體說明如圖所示(與上面中值濾波的解釋類似):
-
OpenCV沒有以max或min單詞開頭來命名的最大或者最小值濾波函式,
而是通過兩個
形態學操作函式
來替代實現最大值與最小值濾波
。它們分別是
dilate
與erode
。
對於這兩個函式的說明具體如下:
-
dilate(Mat src, Mat dst, Mat kernel) //膨脹(最大值濾波)用最大值替換中心畫素
src
:表示輸入影象。dst
:表示輸出影象。kernel
:表示結構元素或者卷積核,注意它可以是任意形狀。 -
erode(Mat src, Mat dst, Mat kernel) //腐蝕(最小值濾波)用最小值替換中心畫素
src
:表示輸入影象。dst
:表示輸出影象。kernel
:表示結構元素或者卷積核,注意它可以是任意形狀。
其中 結構元素/卷積核
的獲取程式碼如下:
Mat kernel = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(3, 3));
上述程式碼將會生成一個 3×3大小的矩形結構元素
。
使用該 結構元素
實現最大值或者最小值濾波的程式碼如下:
Mat src = Imgcodecs.imread(fileUri.getPath()); if(src.empty()){ return; } Mat dst = new Mat(); Mat kernel = Imgproc.getStructuringElement( Imgproc.MORPH_RECT, new Size(3, 3)); // Imgproc.dilate(src, dst, kernel); Imgproc.erode(src, dst, kernel);
-
統計排序濾波器
是最簡單的非線性濾波器
,它可以幫助我們
抑制影象中特定型別的噪聲
,是
非常有用的影象濾波器
。
2. 邊緣保留濾波
-
除了上面提到的
統計排序濾波器
,還有一類濾波器也是
非線性濾波
,它們的實現演算法各有不同,但作用卻是驚人的相似,
這類濾波通常稱為
影象邊緣保留濾波
。
OpenCV中已經實現的邊緣保留濾波有 高斯雙邊濾波、金字塔均值遷移濾波
,
它們無一例外都擁有類似於 人臉美化或者影象美化
的效果,是很好的 影象邊緣保留濾波(EPF)方法
。
下面筆記這兩種濾波方法的基本原理以及與它們對應的函式。
2.1. 高斯雙邊濾波
在開始讀書筆記之前,這裡先做一個總結,
概況一下 高斯濾波
以及 高斯雙邊濾波
,分析其區別:
(高斯濾波部分內容與上一篇筆記重複)
- 正態分佈與高斯分佈?
正態分佈(Normal distribution),也稱“常態分佈”,又名 高斯分佈 (Gaussian distribution),最早由A.棣莫弗在求 二項分佈 的漸近公式中得到。C.F.高斯在研究測量誤差時從另一個角度匯出了它。P.S.拉普拉斯和高斯研究了它的性質。是一個在 數學 、物理及工程等領域都非常重要的 概率 分佈,在統計學的許多方面有著重大的影響力。 - 關於高斯分佈的知乎參考
- 高斯濾波(高斯模糊)
高斯濾波是一種線性平滑濾波,適用於消除高斯噪聲,廣泛應用於影象處理的減噪過程。
通俗的講,
高斯濾波就是對整幅影象進行加權平均的過程
,每一個畫素點的值,都由其本身和鄰域內的其他畫素值經過加權平均後得到
。
高斯濾波的具體操作
是:用一個模板(或稱卷積、掩模)掃描影象中的每一個畫素,用模板確定的鄰域內畫素的加權平均灰度值去替代模板中心畫素點的值。
-好處
高斯平滑濾波器對於抑制服從正態分佈(高斯分佈)的噪聲
非常有效。
-缺憾
對於高頻細節的保護效果並不明顯
,沒有做邊緣保護。 - 高斯雙邊濾波(百度百科解釋)
雙邊濾波(Bilateral filter)
是一種非線性的濾波方法
,
是結合圖像的空間鄰近度和畫素值相似度
的一種折衷處理
,
同時考慮空域資訊和灰度相似性
,
達到保邊去噪
的目的。
具有簡單、非迭代、區域性
的特點。
-好處
可以做邊緣儲存(edge preserving)
,
一般過去用的維納濾波或者高斯濾波
去降噪,都會較明顯地模糊邊緣,對於高頻細節的保護效果並不明顯
。
雙邊濾波器顧名思義比 高斯濾波 多了一個高斯方差sigma-d
,
它是基於空間分佈的高斯濾波函式,
所以在邊緣附近,離的較遠的畫素不會太多影響到邊緣上的畫素值
,這樣就保證了邊緣附近畫素值的儲存
。
-缺憾
由於儲存了過多的高頻資訊,
對於彩色影象裡的高頻噪聲
,
雙邊濾波器不能夠乾淨的濾掉
,只能夠對於低頻資訊進行較好的濾波
。
(下面切回讀書筆記)
-
高斯雙邊濾波是在高斯濾波的基礎上進一步拓展與延伸出來的影象濾波方法,
blur操作
是影象均值模糊
,會導致影象出現輪廓與邊緣消失
的現象,而
高斯模糊
則會產生類似於毛玻璃
的效果,導致邊緣擴充套件效應明顯、影象邊緣細節丟失
的問題。 -
雙邊濾波器(Bilateral Filter)
可以在很好地保留邊緣
的同時,抑制平坦區域影象的噪聲
。雙邊濾波器能做到這些,
(劃重點!!****************************************************************************************)
原因在於
它不像普通的高斯/卷積低通濾波,其不僅考慮了
位置對中心畫素的影響
,還考慮了
卷積核中畫素與中心畫素之間相似程度的影響
,據說,
Adobe Photoshop的高斯磨皮
功能就是應用了此技術。

高斯雙邊濾波的函式為:
-
bilateralFilter(Mat src, Mat dst, int d, double sigmaColor, double sigmaSpace)
src
:表示輸入影象。dst
:表示輸出影象。d
:表示用來過濾的卷積核直徑大小,一般取0,意思是從sigmaColor引數自動計算。
sigmaColor
:顏色權重計算
時候需要的引數。sigmaSpace
:空間權重計算
時候需要的引數。 -
通常情況下,
sigmaColor
的取值範圍在100~150
左右,sigmaSpace
的取值範圍在10~25
之間的時候,雙邊濾波的
效果比較好
,呼叫
函式時的速度
也會比較快
。 -
使用該函式實現影象雙邊濾波的程式碼如下:
Mat src = Imgcodecs.imread(fileUri.getPath()); if(src.empty()){ return; } Mat dst = new Mat(); Imgproc.bilateralFilter(src, dst, 0, 150, 15);
2.2 均值遷移濾波
-
均值遷移濾波
主要是通過概率密度估算
與中心遷移
的方式來實現影象邊緣保留濾波
,其
基本原理
是通過建立
大小指定的卷積核視窗,搜尋並計算
該視窗中心畫素P(x,y)範圍內所有滿足條件的畫素,計算
它們的中心位置
,然後基於新中心位置
再次計算更新
,直到中心位置
不再變化
或者兩次變化的中心的距離
滿足指定的收斂精度值
為止。
一個更直觀的圖示如下所示:

上圖中的 虛線圓
是前一個 迭代
的視窗位置與中心,
實線圓
是 當前
的視窗與中心,
可以看出隨著迭代 計算中心
的不斷遷移,重心位置越來越趨近 高密度區域
,
直到 穩定
為止。
OpenCV中均值遷移濾波函式處於 Imgproc
模組中,
其還可以被用作 影象自動分割
方法之一,
解釋具體如下:
pyrMeanShiftFiltering(Mat src, Mat dst, double sp, double sr, int maxLevel, TermCriteria termcrit)
src
:輸入影象。
dst
:輸出影象。
sp
:影象色彩空間,也是視窗大小。
sr
:影象色彩畫素值範圍,也是畫素差值範圍。
maxLevel
:表示 金字塔
的層數,當maxLevel大於0的時候,金字塔層數為Level+1。
termcrit
:表示迴圈或者迭代停止條件。
通常 最後兩個引數
使用 預設值
即可,無須再次顯式宣告。
使用該函式的程式碼:
Imgproc.pyrMeanShiftFiltering(src, dst, 10, 50);
- 補充:關於maxLevel的
金字塔
的層數的意義以及termcrit
的解釋等,
可以 點選這裡 去官網終究查個明白; - 下面是官網上對應的截圖(先後是原版英文版以及谷歌翻譯中文版):
-
除了OpenCV實現的這兩種常用的邊緣保留濾波方法之外,
常見的邊緣保留濾波方法
還包括影象各向異性濾波、區域性均方差濾波、導向濾波
等,感興趣的小夥伴可以閱讀相關的資料。
參考資料
- 《OpenCV Android 開發實戰》(賈志剛 著)
- 關於本書作者的GitHub專案
- 基於作者GitHub維護的APP