2012年12月22日 星期六

EmguCV Image Process: Filtering the Images part 1

中正大學夕陽
EmguCV Image Process: Filtering the Images

參考OpenCV 2 Computer Vision Application Programming Cookbook第六章

介紹內容如下:

Filtering images using low-pass filters

Eiltering images using a median filter

Applying directional filters to detect edges

Computing the Laplacian of an image


Filtering在信號處理、影像處理中是一種相當基本且重要的課題

Filtering被用來提取影像中某些特定的視覺特徵

而這些特徵則可能傳達了某些重要的資訊

像是一些Filtering可以去除雜訊、擷取視覺感興趣的特徵、或是影像重組等

這裡並不特別去深入研究信號與系統的理論

而是實作一些與影像相關且重要的Filtering

說明Filtering如何在影像中運作

首先就必須先來解釋一下所謂的frequency domain analysis(頻率域的分析)


當我們在看一張影像的時候

會觀察到不同的灰階值(顏色)分布在影像上

一張影像不同於另一張影像主要就是它們之間的灰階值的分布不同

這種直觀的透過灰階值的分佈來分析的方式稱作為:

spatial domain(analysis) 空間域(分析)

而另一種觀點,則是透過影像中灰階值的變化(Gray-level variations)

例如某些影像包含了相當大的區塊的灰階值是幾乎不變的(例如藍天的區塊)

而某些影像可能在灰階值上是呈現快速變化的(例如包含許多物件的複雜影像)

因此,分析影像中這些變化的頻率則稱為:

frequency domain(analysis) 頻率域(分析)


在頻率域分析中,時常會把影像分成:

低頻(low frequencies) 跟 高頻(high frequencies)

低頻對應到的就是影像中灰階值變化較平緩的區域

高頻對應到的就是影像中灰階值變化劇烈的區域

常見的一些頻率域的轉換有:Fourier transform(傅立葉轉換)、Cosine transform(餘弦轉換)等

這些轉換都能夠用來清楚的呈現影像中頻率域的內容


在頻率域的分析中,利用Filtering能夠用來放大、遮蔽、壓縮指定區塊的頻率

像是:low-pass filter就是消除高頻率的部分

而這個章節將會介紹幾種在頻率域上使用的Filter


Filtering images using low-pass filters

一開始就來介紹最基本的low-pass filters

這裡就是試著把影像的變化的幅度降低

簡單說就是將每個pixel的值取為周圍的pixels取平均

這樣就能減低灰階值的變化,使影像變得比較smooth

//Read input image
Image<Bgr, Byte> image = new Image<Bgr, Byte>("image.jpg");
//The kind of filter is also called a box filter
Image<Bgr, Byte> blur = image.SmoothBlur(5, 5);
這裡採用5X5的filter來運作

結果如下:
這裡直接採取周圍的平均值,整個畫面都模糊了!!

其運作的機制就是透過一個5X5的kernek矩陣來計算pixel的值

5X5 kernel

而每一個鄰點的權重值都一樣

所以也就是鄰近25個點的平均值

應用這種線性的filter,不斷的移動kernel到每個pixel來做計算

而每個鄰點都需乘上所對應的權重值然後再加總起來!!

這種運算也稱作:convolution(捲積)


而另外也有透過鄰近的遠近加上權重的計算方式

越靠近基準點的位置的權重就越大

像是著名的:Gaussian function

//It might be desirable to give more importance to the
//closer pixels in the neighborhood of a pixel
Image<Bgr, Byte> gaussian = image.SmoothGaussian(5);
一樣採用5X5的大小去運作

結果如下:

因為加上鄰近的權重值,所以畫面上看起來比較不會這麼模糊!

而關於Gaussian function的計算方式非常複雜

1D Gaussian function:

這個複雜的函式有興趣的可以自己到wiki來學習


而low-pass filter也常用在resize(縮放)的功能上

如果要把一張影像縮成原來的1/2大小

直觀的做法就是消除影像中的偶數列和偶數行

但不幸的是,這樣的作法往往會使影像看起來不那麼好

舉例來說:一條在原始影像中的斜線

可能在縮小之後變成像樓梯一般的鋸齒狀

這種鋸齒狀的失真還會出現在影像中的曲線、紋理上

這種不良的現象稱作為:spatial aliasing

這種現象會發生在試著在過小的影像中包含過多的高頻區塊

而實際上,較小的影像相較於較大的影像

確實就無法表現出較好的紋理或形狀的邊線

這裡就能夠透過low-pass filter來運作

//reduce image size by half
Image<Bgr, Byte> pyrDown = image.PyrDown();
PyrDown會採用5X5的Gaussian filter來對影像做low-pass filter

結果如下:

產生的結果是經過low-pass filter的影像

所以看起來會比較不這麼銳利

PyrDown這個方法在前景物件偵測中相當常用到

能夠透過PyrDown和PyrUp這兩個函式建立image pyramids

這是一個資料結構,包含同一個影像的多種大小

像是在物件偵測中,會利用最小的那份影像來做物件偵測

然後在最大的那份影像上做標記


而另外也有Resize的方法來做縮放

這就是一般的縮放方法

你可以設定長、寬,或是縮放比例

以及縮放的演算法等

//1/2 resizing
Image<Bgr, Byte> resize = image.Resize(0.5, Emgu.CV.CvEnum.INTER.CV_INTER_LINEAR);
縮放0.5倍,採用linear的演算法

結果如下:

可以發現利用resize的結果比較銳利!!

在縮放的函式中沒有哪個方式比較好

而是要找出比較適合所要達到的目的的方式來做!!

下一篇將介紹可解決salt and pepper noise的median filter

沒有留言:

張貼留言