Python-OpenCV中的filter2D()函數


使用自定義內核對圖像進行卷積。該功能將任意線性濾波器應用於圖像。支持就地操作。當光圈部分位於圖像外部時,該功能會根據指定的邊框模式插入異常像素值。

 

 

語法

函數原型:

dst=cv.filter2D(src, ddepth, kernel[, dst[, anchor[, delta[, borderType]]]])

參數:

參數 描述
src 原圖像
dst 目標圖像,與原圖像尺寸和通過數相同
ddepth 目標圖像的所需深度
kernel 卷積核(或相當於相關核),單通道浮點矩陣;如果要將不同的內核應用於不同的通道,請使用拆分將圖像拆分為單獨的顏色平面,然后單獨處理它們。
anchor 內核的錨點,指示內核中過濾點的相對位置;錨應位於內核中;默認值(-1,-1)表示錨位於內核中心。
detal 在將它們存儲在dst中之前,將可選值添加到已過濾的像素中。類似於偏置。
borderType 像素外推法,參見BorderTypes

該函數實際計算的是相關性,而不是卷積

$$\texttt{dst} (x,y) = \sum _{ \stackrel{0\leq x' < \texttt{kernel.cols},}{0\leq y' < \texttt{kernel.rows}} } \texttt{kernel} (x',y')* \texttt{src} (x+x'- \texttt{anchor.x} ,y+y'- \texttt{anchor.y} )$$

在內核足夠大(~11x11或者更大)的時候,該函數使用DFT算法,對於小內核則直接計算。

也可見,anchor相當於坐標軸平移。

其中ddepth表示目標圖像的所需深度,它包含有關圖像中存儲的數據類型的信息,可以是unsigned char(CV_8U),signed char(CV_8S),unsigned short(CV_16U)等等...

Input depth (src.depth()) Output 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

 Note:當ddepth=-1時,表示輸出圖像與原圖像有相同的深度。

 

例子

圖像內核是一個小矩陣,用於應用您可能在Photoshop或Gimp中找到的效果,例如模糊,銳化,輪廓或浮雕。它們還用於機器學習中的“特征提取”,這是一種用於確定圖像最重要部分的技術。在這種情況下,該過程更普遍地稱為“卷積”(參見:卷積神經網絡)。

有許多有趣的內核,下面一一介紹:

 1、模糊(blur)

模糊內核消除了相鄰像素值之間的差異。內核如下:

0.0625 0.125 0.0625
0.125 0.25 0.125
0.0625 0.125 0.125

 

 

 

 

 代碼:

import cv2
import numpy as np

def solve():

    src = cv2.imread("./Pictures/car001.jpg")
    if src is None:
        return -1

    kernel = np.array((
        [0.0625, 0.125, 0.0625],
        [0.125, 0.25, 0.125],
        [0.0625, 0.125, 0.0625]), dtype="float32")


    dst = cv2.filter2D(src, -1, kernel)
    htich = np.hstack((src, dst))
    cv2.imwrite("./Pictures/car.jpg", htich)
    cv2.imshow('merged_img', htich)
    cv2.waitKey(0)

    return 0


if __name__ == "__main__":
    solve()

效果:

 

2、索貝爾(sobel)

sobel內核用於僅顯示特定方向上相鄰像素值的差異,分為left sobel、right sobel(檢測梯度的水平變化)、top sobel、buttom sobel(檢測梯度的垂直變化)。

例如,buttom sobel

-1 -2 -1
0 0 0
1 2 1

 

 

 

 

代碼與上面類似,只需修改krenel的值。

3、浮雕(emboss)

通過強調像素的差在給定方向的Givens深度的錯覺。在這種情況下,沿着從左上到右下的直線的方向。

-2 -1 0
-1 1 1
0 1 2

 

 

 

 

效果:

4、大綱(outline)

一個輪廓內核(也稱為“邊緣”的內核)用於突出顯示的像素值大的差異。具有接近相同強度的相鄰像素旁邊的像素在新圖像中將顯示為黑色,而與強烈不同的相鄰像素相鄰的像素將顯示為白色。

-1 -1 -1
-1 8 -1
-1 -1 -1

 

 

 

 

效果:


5、銳化(sharpen)

銳化內核強調在相鄰的像素值的差異。這使圖像看起來更生動。

0 -1 0
-1 5 -1
0 -1 0

 

 

 

 

效果:

 

6、拉普拉斯算子(laplacian operator)

拉普拉斯算子可以用於邊緣檢測,對於檢測圖像中的模糊也非常有用。

0 1 0
1 -4 1
0 1 0

 

 

 

 

 

效果:

 

7、分身(identity)

這個非常簡單,就是原圖(不考慮邊界時),How boring!

0 0 0
0 1 0
0 0 0

 

 

 

 

 

 

拓展部分

正如您在本博文中所收集的那樣,我們必須  手動定義每個內核以應用各種操作,例如平滑,銳化和邊緣檢測。

如何定義內核達到你想要的效果,這並不是一件簡單的事情。

現在有一種神經網絡——CNN,通過應用卷積濾波器,非線性激活函數,匯集和反向傳播,CNN能夠學習過濾器(的權重),可以檢測網絡較低層中的邊緣和類似blob的結構 - 然后使用邊緣和結構作為構建塊,最終在網絡的更深層中檢測更高級別的對象(即,面部,貓,狗,杯等)。這樣就不必手動定義過濾器了。

 

參考鏈接:

1、Depth combination https://docs.opencv.org/master/d4/d86/group__imgproc__filter.html#filter_depths 

2、cv2.filter2d()opencv中ddepth參數的解釋?https://stackoverflow.com/questions/43392956/explanation-for-ddepth-parameter-in-cv2-filter2d-opencv

3、Image-kernels Demo http://setosa.io/ev/image-kernels/


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM