<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
照例,我們搬一下官網的 API:
void cv::filter2D(InputArray src, OutputArray dst, int ddepth, InputArray kernel, Point anchor=Point(-1, -1), double delta=0, int borderType=BORDER_DEFAULT )
dst=cv.filter2D(src, ddepth, kernel[, dst[, anchor[, delta[, borderType]]]])
這個函數一般是用於影象的折積,但 OpenCV 檔案裡說這個函數不完全等於影象折積。這一點說實話我看到的時候也震驚到了,我一直是拿它當折積來用的。但是仔細考慮後,我認為這一點完全是定義上的差異,日常用的影象折積定義和這個函數的功能實際上是一致的。
直接上手做往往能給人最直觀的感受。因此,最開始這裡我要放一個使用這個函數的最小化程式,可以稱之為該函數的 hello world 程式。這個程式跑通了,就可以很方便地嘗試其他引數的作用了。
# HelloWrold Program of cv.filter2D # by Aling on 2021/1/18 import numpy as np import cv2 as cv def main(): img = cv.imread("你想讀的圖片") # 定義折積核 kernel = np.ones((10, 10)) / 100 # 執行濾波 avg_filtered = cv.filter2D(img, -1, kernel) # 顯示圖片 cv.imshow("Average filtered", avg_filtered) cv.waitKey(0) cv.destroyAllWindows() if __name__ == "__main__": main()
這個程式讀取一張圖片,並將其通過10 x 10 的折積核作均值濾波並顯示結果。
同樣的,這裡把各個引數打一張表:
引數 | 型別 | 是否必須指定(預設值) | 具體含義 |
---|---|---|---|
src | numpy.ndarray | 是 | 原影象 |
ddepth | int | 是 | 目標影象深度(指資料型別) |
kernel | numpy.ndarray | 是 | 折積核 |
anchor | tuple | 否(折積核中心) | 折積錨點 |
delta | 是資料類就行 | 否(0) | 偏移量,折積結果要加上這個數位 |
borderType | int (實際上是 enum 類) | 否(cv.BORDER_DEFALUT ) | 邊緣型別 |
這個引數沒什麼好說的,就是原影象。它可以是任何色彩模式,這就意味著如果你把原本送到這個函數裡的圖片從黑白變成了彩色(單通道變成了 3 通道),你並不需要更改其他引數。本身,對多通道的影象,折積就是以通道為單位進行的。
這個引數有點費解了。大部分情況下不需要管它是幹嘛的,直接把它設成 -1 就沒有任何問題。
引數名 ddepth
,英文是 desired depth,即期望深度。什麼意思呢?我們來看它的可能取值表(來自這裡):
輸入深度(src.depth() ) | 期望深度(ddepth ) |
---|---|
CV_8U | -1/CV_16S/CV_32F/CV_64F |
CV_16U/CV_16S | -1/CV_32F/CV_64F |
CV_32F | -1/CV_32F/CV_64F |
CV_64F | -1/CV_64F |
這個表裡的一大串 CV
打頭的符號到底是什麼意思呢?實際上這些符號的末尾字母對應了資料型別:
U == Unsigned int # 無符號整型 S == Signed int # 有符號整型 F == Float # 浮點型
中間的數位很顯然代表了資料型別所佔用的空間(bit)。所以,所謂深度,其實指的是資料型別。
那就好說了,你會發現這裡其實是規定了輸出資料的型別,包括每個通道的每個畫素佔用多少空間。輸出資料的型別必須根據上面的表格中輸入對應的型別指定。這裡 -1 表示輸出型別和輸入相同。
不過,值得注意的是,似乎有些資料型別無法通過 cv2.imshow
正常顯示,可以用 matplotlib.pyplot.imshow
來代替。
但是,還是注意,沒有關於資料型別的特別要求時,這個功能是不需要的,取 -1 即可。
這兩個引數都是折積相關的,因此放在一節裡面講述。接下來的內容假設你已經瞭解了影象折積。
這裡,kernel
很顯然表示的是折積核,這是一個 numpy.ndarray
型別的矩陣。這個矩陣的生成可以用 numpy
自帶的函數,但是對於複雜一些的折積核,OpenCV 內部的一些函數顯然更合適。如 getStructuringElement
,getGaussianKernel
,前者用於獲取特定形狀的核,後者則是高斯核生生成器(不過要注意生成的是一個向量)。
# 方法一範例 kernel = cv.getStructuringElement(cv.MORPH_RECT, (11, 11)) # 方法二範例 vector = cv.getGaussianKernel(11, -1) kernel = vector @ vector.T
anchor
則表示錨點。什麼叫錨點呢?看下面這張圖:
可以說,錨點 anchor
決定了折積核相對於生成目標點的位置。雖然錨點是相對於折積核來定義的,但是折積的過程更像是通過錨點去尋找折積核。遍歷影象中的每一個畫素,以每一個畫素為錨點,按照相對位置生成折積範圍,和折積核對應元素相乘再求和得到目標影象中對應畫素的值。可以用公式表示成:
這實際上就是一般的影象折積計算方法。OpenCV 檔案裡面敘述的折積定義則是需要將折積核圍繞錨點對稱變換,再用上面的公式計算。這種方法更接近折積原始的定義,但是對影象的折積一般的應用而言(濾波、深度學習)這兩種定義實際上沒有什麼區別。、
錨點用一個元組指定,是相對於折積核左上角的座標,從 0 開始:
# 替換掉 HelloWorld 程式的對應行。 avg_filtered = cv.filter2D(img, -1, kernel, (1, 2))
這個引數的存在其實有些費解,它的效果很簡單,就是把折積的結果加上一個固定的數位。直觀上將,它將整個影象變亮或者變暗了。從應用上來說,它實際上將折積過程擴充套件成了一般的線性運算( ∗ * ∗ 表示折積):
這個線性運算可以將結果限定在某一符合要求的範圍內(比如大於 0),而且不會阻斷梯度的傳遞。
這個引數更改的是 border 的生成方式。這個 border,也就是邊緣,是在靠近邊緣的部分折積時用到的,參考上面那張圖。無論 anchor
是什麼,總有些邊緣上的點對應的折積範圍無法完全落在原圖內,這就需要對原圖進行擴充套件。擴充套件的方法就是我們這裡引數的含義。
這個引數取值是 OpenCV 裡的 cv::BorderTypes
enum 類定義的值,其可能取值及其對於邊緣的作用結果如下圖所示(圖片來自 OpenCV Python 教學):
要注意幾點:
cv.BORDER_WARP
在這個函數裡面是不支援的;cv.BORDER_CONSTANT
會將邊緣取為 0(黑色),而且沒法改,因為原函數並沒有留出相關的介面。影象濾波是一個很常用的功能,對此,OpenCV 也定義了很多函數。這裡介紹的 cv.filter2D
是這些函數中可控性最高的,因為你可以用自定義的核進行折積。但是一些常用的濾波,我們可以不必自己定義相應的核,直接用定義好的函數就可以了。
dst = cv.blur(img, (11, 11)) # 等效於: dst = cv.filter2D(img, -1, np.ones((11, 11))/11**2)
dst = cv.GaussianBlur(img, (11, 11), -1) # 等效於 vector = cv.getGaussianKernel(11, -1) kernel = vector @ vector.T dst = cv.filter2D(img, -1, kernel)
dst = cv.medianBlur(img, 11)
注意中值濾波是取中位數作為目標值,是一個非線性濾波子,因此無法通過線性濾波的 cv.filter2D
來等效實現。
到此這篇關於OpenCV影象折積之cv.filter2D()函數詳解的文章就介紹到這了,更多相關OpenCV影象折積cv.filter2D()函數內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45