天天看點

OpenCV2馬拉松第5圈——線性濾波

這裡的很多内容其實在我的中都有講過

相關和卷積工作原理

邊界處理

濾波器的工作原理

會使用均值濾波,高斯濾波

使用自己創造的核函數進行雙線性濾波

可分離的濾波(加速)

相關: g=f?h

卷積: g=f?h 

OpenCV2馬拉松第5圈——線性濾波

暫時不考慮邊緣,是以8*8的圖形進行相關或卷積操作後就得到6*6的圖形

因為我們的h(有時叫做核函數)是中心對稱的,是以相關和卷積得到的結果是一樣的

那不一樣呢?看下面的例子,用個一維的例子,{x,y}是核函數,{a,b,c,d,e}是資料

這裡構造核 

OpenCV2馬拉松第5圈——線性濾波

 與資料清單的卷積.

out[1]=

OpenCV2馬拉松第5圈——線性濾波

這裡構造相關.

out[2]=

OpenCV2馬拉松第5圈——線性濾波

padding(border effects)

之前提到過,8*8的圖像用3*3的核處理會成6*6,那麼邊界要怎麼處理呢?

OpenCV2馬拉松第5圈——線性濾波

0填充,很簡單的處理方式

常數填充

夾取填塞(clamp),不斷地複制邊緣像素的值

重疊填塞(wrap),以環狀形态環繞圖像進行循環

鏡像填塞(mirror),像素環繞圖像邊界進行鏡像反射

延長(extend),通過在邊緣像素值中減去鏡像信号的方式延長信号

下面是來自opencv的例子,邊界處理沒有cvaa上面那麼豐富

濾波器

今天講的高斯低通濾波器,均值濾波器,雙線性濾波器都是起到模糊的作用

低通濾波器抑制了圖像的高頻部分,使得低頻分量暢通

今天是4月28日,在coursera上有數字信号處理這門課開課,還有在網易公開課有斯坦福的傅立葉變換

如果你想非常深入了解,可以去學一下這兩門課

濾波函數有時候又叫核函數,也可以叫算子

OpenCV2馬拉松第5圈——線性濾波

均值濾波

<dl></dl>

<dt></dt>

c++: void blur(inputarray src,

outputarray dst, size ksize, point anchor=point(-1,-1), int bordertype=border_default )

<dd></dd>

<col>

src – 原始圖像

dst – 輸出圖像

ksize – 核函數大小

anchor – 錨點,一般情況下預設為(-1,-1),意味着在中心進行卷積

bordertype – 邊界類型

the function smoothes an image using the kernel:

OpenCV2馬拉松第5圈——線性濾波

高斯濾波,對去除正态分布的噪聲很有用

c++: void gaussianblur(inputarray src,

outputarray dst, size ksize, double sigmax, double sigmay=0, int bordertype=border_default )

src – 輸入圖像

ksize – 核大小

sigmax – 控制幅度的參數(大家應該都學過或看過高斯函數吧,比如在正态分布中),如何sigmax,sigmay都為0,則由核的高度寬度自己計算

sigmay – 二維高斯函數有兩個方向可以控制幅度,或這個不設定則和x一樣

用自己的核函數進行濾波

c++: void filter2d(inputarray src,

outputarray dst, int ddepth, inputarray kernel, point anchor=point(-1,-1), double delta=0, intbordertype=border_default )

src – 輸入圖像.

dst – 輸出圖像.

depth – ddepth=-1,輸出圖像具有和輸入圖像一樣的depth

kernel – 核函數,單通道浮點矩陣

anchor – 同之前

delta – 可選,直接加到輸出圖像

使用均值濾波

OpenCV2馬拉松第5圈——線性濾波

使用高斯濾波

OpenCV2馬拉松第5圈——線性濾波

使用自定義線性濾波

OpenCV2馬拉松第5圈——線性濾波

可分離的濾波

二維高斯函數卷積可以分兩步來進行,首先将圖像與一維高斯函數進行卷積,然後将卷積結果與方向垂直的相同一維高斯函數卷積.是以,二維高斯濾波的計算量随濾波模闆寬度成線性增長而不是成平方增長。

二維卷積運算,更新一個像素點肯定需要k2 次運算(k是核函數的大小)

文中提出了一種加速的方法,先用一維行向量進行卷積,再用一維列向量進行卷積,如果一個卷積核可以采用這種方法計算,就是可分離的。(這樣子就隻有2k次操作,很神奇吧)

k =vht  

将卷積核k拆分成列向量v和行向量h

當然,并不是所有k都能被拆分,我在上面的圖檔中的3個例子都是可以拆分的,一維向量已經列在二維下面

最簡單的平均濾波,[1,1,1......,1]*[1,1,1......,1]t   = k

再看第3個高斯核,[1,4,6,4,1]*[1,4,6,4,1]t = k

那麼如何判斷核函數是不是可分離的呢?cvaa說用奇異值分解的辦法

我的想法是,必須要滿足中心對稱,比如高斯函數,sigmax和sigmay相等的時候就可以分解

opencv幫我們實作了

c++: void sepfilter2d(inputarray src,

outputarray dst, int ddepth, inputarray kernelx, inputarray kernely, point anchor=point(-1,-1), doubledelta=0, int bordertype=border_default )

src – source image.

dst – destination image of the same size and the same number of channels as src .

ddepth –

<dt>destination image depth. the following combination of src.depth() and ddepth are</dt>

supported:

src.depth() = cv_8u, ddepth =

-1/cv_16s/cv_32f/cv_64f

src.depth() = cv_16u/cv_16s, ddepth =

-1/cv_32f/cv_64f

src.depth() = cv_32f, ddepth =

src.depth() = cv_64f, ddepth =

-1/cv_64f

when ddepth=-1, the destination image will have the same depth

as the source.

kernelx – coefficients for filtering each row.

kernely – coefficients for filtering each column.

anchor – anchor position within the kernel. the default value 

OpenCV2馬拉松第5圈——線性濾波

 means

that the anchor is at the kernel center.

delta – value added to the filtered results before storing them.

bordertype – pixel extrapolation method. see  for

details.

參數基本沒什麼好講,都是一樣的,下面我們用這個函數來進行高斯卷積(濾波)

因為效果和之前高斯濾波是一樣的,就不貼圖了,但是要注意雖然效果一樣,但是速度可是大大提升!!

計算機視覺讨論群162501053

轉載請注明:http://blog.csdn.net/abcd1992719g

繼續閱讀