當前位置:
首頁 > 最新 > 33.製作你自己的線性過濾器!-OpenCV從零開始到圖像

33.製作你自己的線性過濾器!-OpenCV從零開始到圖像

本文作者:小嗷

微信公眾號:aoxiaoji

簡書鏈接:https://www.jianshu.com/u/45da1fbce7d0

小嗷再問一次自己,什麼是線性濾波?

首先圖像和核卷積是必須的。

均值的話,卷積以後的總數除以核的大小(如3*3=9,9個數相加後總數/9=所求的像素值)

高斯的話,先進行高斯函數的運算,然後把算出來的核核圖像進行卷積。再加起來。

即: 核與圖像卷積 + 核內數相加(不懂的話,自行看推薦文章。)

圖像、相加、卷積、都是固定不變。自定義線性濾波,只能改變核(核也稱元素結構),呵呵噠

大家可以參考第28篇代碼有自定義核的內容

在本篇中,您將學習:

使用OpenCV函數filter2D()創建自己的線性過濾器。

本文你會找到以下問題的答案:

filter2D()

imgcodecs

char **argv是什麼用法啊?argv[0] 什麼意思啊?

2.1 理論

下面的解釋屬於Bradski和Kaehler的《學習OpenCV》一書(英文書)

2.1.1 相關性

在一般意義上,相關性是圖像的每個部分和操作符(內核)之間的操作。

2.1.2 什麼是內核?

內核本質上是一個固定大小的數值係數數組,以及該數組中通常位於中心的錨點。

(其實小嗷都不想寫,這玩意說的N遍)

2.1.3 與內核的關聯是如何工作的?

假設您希望知道映像(圖像)中某個特定位置的結果值。相關值的計算方法如下:

將內核錨點放在一個確定的像素上,其餘的內核將在圖像中覆蓋相應的本地像素。

將核係數乘以相應的圖像像素值,並對結果進行求和。

將結果放置到輸入圖像中錨點的位置。

通過掃描整個圖像的內核,對所有像素重複這個過程。

不得不說,相比小嗷的介紹,鬼佬的解釋更專業更能裝逼

用方程的形式表示上述過程,我們將得到:

看不懂公式正常,請點擊第24篇自定義中值濾波處理的代碼。

I(XXX)代表就是錨點附近的值,K(i,j)代表核

幸運的是,OpenCV為您提供了函數filter2D(),因此您不必編寫所有這些操作。

2.1.4 這個程序做什麼?

載入一個圖像

執行規範化的框過濾器。例如,對於大小為3的內核,內核為:

該程序將使用3、5、7、9和11大小的內核執行篩選操作。

過濾器輸出(與每個內核一起)將在500毫秒內顯示

3.1 filter2D

將圖像與內核卷積。

該函數對圖像應用任意線性濾波器。就地操作支持。當孔徑位於圖像外部,根據指定的邊框模式插入離群像素值。該函數根據指定的邊界模式插入離群點像素值。

這個函數實際上計算的是相關性,而不是卷積:

也就是說kernel並不是中心點的鏡像,如果需要一個正真的卷積,使用函數flip()並將中心點設置為(kernel.cols - anchor.x - 1, kernel.rows - anchor.y -1).

該函數在大核(11x11或更大)的情況下使用基於DFT的演算法,而在小核情況下使用直接演算法(使用createLinearFilter()檢索得到).

參數詳情:

src:輸入圖像

dst:輸出圖像的大小和數量與src相同。

ddepth:目標圖像深度,如果沒寫將生成與原圖像深度相同的圖像。原圖像和目標圖像支持的圖像深度如下:

當ddepth輸入值為-1時,目標圖像和原圖像深度保持一致。

kernel:卷積核(或者是相關核),一個單通道浮點型矩陣。如果想在圖像不同的通道使用不同的kernel,可以先使用split()函數將圖像通道事先分開。

anchor:內核的基準點(anchor),其默認值為(-1,-1)說明位於kernel的中心位置。基準點即kernel中與進行處理的像素點重合的點。

delta:在儲存目標圖像前可選的添加到像素的值,默認值為0

borderType:像素向外逼近的方法,默認值是BORDER_DEFAULT,即對全部邊界進行計算。

3.2 imgcodecs

用於圖片的讀寫。//2.4里沒有這塊(2.49)

OpenCV3開始圖片、視頻編解碼從highgui模塊分離出來,組成了imgcodecs和videoio。Linux環境下需要注意一下,其他沒啥。

3.3 char **argv是什麼用法啊?argv[0] 什麼意思啊?

本篇文章的代碼如下所示。

源圖:

效果圖:(就是均值濾波(不停的擴大核的大小))

解釋一下:

讓我們來看看這個項目的總體結構:

載入一個圖像

初始化參數

循環

執行一個無限循環更新內核大小,並對輸入圖像應用線性過濾器。讓我們更詳細地分析一下:

首先我們定義過濾器將要使用的內核。這裡是:

第一行是將kernel_size更新為範圍內的奇數值:[3,11]。第二行實際上構建了內核。通過設置它的值與1′s矩陣填充和正常化把它除以元素的個數。

設置內核後,我們可以使用函數filter2D()生成過濾器:

我們的程序將會實現一個while循環,每個500 ms的內核大小的過濾器將會在指定的範圍內更新。

在編譯上面的代碼之後,您可以執行它,將圖像的路徑作為參數。結果應該是一個窗口,該窗口顯示被規範化過濾器模糊的圖像。內核大小每0.5秒就會發生變化。

喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 小嗷的日常 的精彩文章:

TAG:小嗷的日常 |