天天看點

OpenCV--Python 圖像平滑之中值平滑、雙邊濾波、聯合雙邊濾波、導向濾波

文章目錄

    • 1. 中值平滑
        • 原理詳解
        • Python實作
        • OpenCV函數
        • 總結
    • 2. 雙邊濾波
        • 原理詳解
        • Python實作
        • OpenCV函數
        • 總結
    • 3. 聯合雙邊濾波
        • 原理詳解
        • Python實作
        • OpenCV函數
        • 總結
    • 4. 導向濾波
        • 原理詳解
        • Python實作
        • OpenCV函數
    • 總結

1. 中值平滑

原理詳解

  中值平滑,類似于卷積,也是一種鄰域運算,但計算的不是權重求和,而是對鄰域中的像素點按灰階值進行排序,然後選擇該組中的中值作為輸出的灰階值。

OpenCV--Python 圖像平滑之中值平滑、雙邊濾波、聯合雙邊濾波、導向濾波

  比如,取以圖像的位置 (1,1)為中心的 3X3 的鄰域,對鄰域中的像素點灰階值按從大到小進行排序, [ 11 , 21 , 31 , 125 , 141 , 165 , 190 , 234 , 234 ] [11,21,31,125,141,165,190,234,234] [11,21,31,125,141,165,190,234,234] 可知,141是該組灰階值的中值,那麼輸出圖像在位置(1,1)的值便為141,以此類推,得到輸出圖像的所有像素點的灰階值。對邊界的處理可采用多種政策,而對邊界進行鏡像補充是較為理想的一種選擇。

  中值濾波最重要的能力是去除椒鹽噪聲。椒鹽噪聲是指在圖像傳輸系統中由于解碼誤差等原因,導緻圖像中出現孤立的白點或者黑點。

Python實作

  對于python實作的中值平滑,首先利用指令 n d a r r a y [ r 1 : r 2 + 1 , c 1 : c 2 + 1 ] \mathrm{ndarray}[r_1:r_2 + 1, c_1:c_2+1] ndarray[r1​:r2​+1,c1​:c2​+1] 得到 n d a r r a y \mathrm{ndarray} ndarray 從左上角至右下角的矩形區域,然後利用 N u m p y \mathrm{Numpy} Numpy提供的函數

median

取該區域的中位數。

# -*- coding: utf-8 -*-
import random
import cv2 as cv
import numpy as np

def medianBlur(image, winSize):
    # 圖像的高寬
    rows, cols = image.shape
    # 視窗的高寬均為奇數
    winH, winW = winSize
    halfWinH = (winH - 1) // 2
    halfWinW = (winW - 1) // 2
    # 中值濾波後的輸出圖像
    medianBlurImage = np.zeros(image.shape, image.dtype)
    for r in range(rows):
        for c in range(cols):
            # 判斷邊界
            rTop = 0 if r - halfWinH < 0 else r - halfWinH
            rBottom = rows - 1 if r + halfWinH > rows - 1 else r + halfWinH
            cLeft = 0 if c - halfWinW < 0 else c - halfWinW
            cRight = cols - 1 if c + halfWinW > cols - 1 else c + halfWinW
            # 取鄰線
            region = image[rTop:rBottom+1, cLeft:cRight+1]
            # 求中值
            medianBlurImage[r][c] = np.median(region)
    return medianBlurImage

if __name__ == '__main__':
    image = cv.imread('img6.jpg', 0)
    cv.imshow('src', image)
    # 中值濾波
    medianBlurImage1 = medianBlur(image, (3,3))
    cv.imshow('3x3', medianBlurImage1)
    medianBlurImage2 = medianBlur(image, (15, 15))
    cv.imshow('15x15', medianBlurImage2)
    medianBlurImage3 = medianBlur(image, (25, 25))
    cv.imshow('25x25', medianBlurImage3)
    cv.waitKey(0)
    cv.destroyAllWindows()
           

  下圖分别為添加了椒鹽噪聲的圖像,3x3中值濾波後的圖像,15x15中值濾波後的圖像,25x25中值濾波後的圖像。通過中值濾波去除了圖像中的黑色孤立點,幾乎看不到椒鹽噪聲的影響,并且随着中值平滑視窗的增加,椒鹽噪聲會完全消除。而且中值平滑後的效果并沒有降低邊緣的銳利程度,具有一定的保邊作用。

OpenCV--Python 圖像平滑之中值平滑、雙邊濾波、聯合雙邊濾波、導向濾波

OpenCV函數

dst = cv.medianBlur(src, ksize[, dst])

參數解釋如下:

參數 解釋
src 輸入矩陣
dst 輸出矩陣,其大小和資料類型與src相同
ksize 若為大于1的奇數,則視窗大小為kszie x ksize

Python示例代碼

總結

中值濾波适用于椒鹽噪聲,具有保邊作用。

調用函數:dst = cv.medianBlur(src, ksize[, dst])

2. 雙邊濾波

原理詳解

  均值平滑和高斯平滑本質上是計算每個位置的鄰域權重和作為該位置的輸出,隻是這種運算可以用卷積實作,權重系數模版是通過卷積核逆時針翻轉 18 0 ∘ 180^\circ 180∘ 得到的。雙邊濾波則是根據每個位置的鄰域,對該位置建構不同的權重模闆,詳細過程如下:

  首先,建構 w i n H ∗ w i n W \mathrm{winH * winW} winH∗winW 的空間距離權重模闆,與建構高斯卷積核的過程類似, w i n H \mathrm{winH} winH 和 w i n W \mathrm{winW} winW 均為奇數。

c l o s e n e s s W e i g h t ( h , w ) = exp ⁡ ( − ( h − w i n H − 1 2 ) 2 + ( w − w i n W − 1 2 ) 2 2 σ 1 2 ) \mathbf{closenessWeight}(h,w) = \exp(-\frac{(h-\frac{\mathrm{winH - 1}}{2})^2 + (w-\frac{\mathrm{winW - 1}}{2})^2}{2\sigma^2_1}) closenessWeight(h,w)=exp(−2σ12​(h−2winH−1​)2+(w−2winW−1​)2​)

其中 0 ≤ h < w i n H , 0 ≤ w < w i n W 0 \leq h < \mathrm{winH}, 0 \leq w < \mathrm{winW} 0≤h<winH,0≤w<winW ,且每個位置的空間距離權重模闆是相同的。

  然後,建構 w i n H ∗ w i n W \mathrm{winH * winW} winH∗winW 的相似性權重模闆,是通過 ( r , c ) (r,c) (r,c) 處的值與其鄰域值的內插補點的指數衡量的。

s i m i l a r i t y W e i g h t ( h , w ) = exp ⁡ ( − ∣ ∣ I ( r , c ) − I ( r + ( h − w i n H − 1 2 ) , c + ( w − w i n W − 1 2 ) ∣ ∣ 2 2 σ 1 2 ) \mathbf{similarityWeight}(h,w) = \exp(-\frac{||I(r,c) - I(r + (h-\frac{\mathrm{winH - 1}}{2}), c + (w-\frac{\mathrm{winW - 1}}{2})||^2}{2\sigma^2_1}) similarityWeight(h,w)=exp(−2σ12​∣∣I(r,c)−I(r+(h−2winH−1​),c+(w−2winW−1​)∣∣2​)

  最後,将 c l o s e n e s s W e i g h t \mathbf{closenessWeight} closenessWeight 和 s i m i l a r i t y W e i g h t \mathbf{similarityWeight} similarityWeight 的對應位置相乘(即點乘),然後進行歸一化,便可得到該位置的權重模闆。将所得到的權重模闆和該位置鄰域的對應位置相乘,然後求和就得到該位置的輸出值,和卷積運算的第二步操作類似。

Python實作

  通過定義函數

bfltGray

實作圖像的雙邊濾波,其中參數 I I I 代表圖像矩陣且灰階值範圍是 [0,1],H,W分别代表權重子產品的高和寬且均為奇數,sigma_g代表空間距離權重模闆的标準差,sigma_d代表相似性權重模闆的标準差,另 sigma_g > 1,sigma_d < 1效果會比較好,傳回值是浮點型矩陣,代碼如下:

import cv2 as cv
import numpy as np
import math

def getClosenessWeight(sigma_g, H, W):
    r, c = np.mgrid[0:H:1, 0:W:1]
    r -= (H - 1) // 2
    c -= (W - 1) // 2
    closeWeight = np.exp(-0.5*np.power(r, 2) + np.power(c, 2) / math.pow(sigma_g, 2))
    return closeWeight

def bfltGray(I, H, W, sigma_g, sigma_d):
    # 建構空間距離權重模闆
    closenessWeight = getClosenessWeight(sigma_g, H, W)
    # 模闆的中心點位置
    cH = (H - 1) // 2
    cW = (W - 1) // 2
    # 圖像矩陣的行數和列數
    rows, cols = I.shape
    # 雙邊濾波後的結果
    bflGrayImage = np.zeros(I.shape, np.float32)
    for r in range(rows):
        for c in range(cols):
            pixel = I[r][c]
            # 判斷邊界
            rTop = 0 if r - cH < 0 else r - cH
            rBottom = rows - 1 if r + cH > rows - 1 else r + cH
            cLeft = 0 if c - cW < 0 else c - cW
            cRight = cols - 1 if c + cW > cols - 1 else c + cW
            # 權重模闆作用的區域
            region = I[rTop:rBottom+1, cLeft:cRight+1]
            # 建構灰階值相似性的權重因子
            similarityWeightTemp = np.exp(-0.5*np.power(region-pixel, 2.0) / math.pow(sigma_d, 2))
            closenessWeightTemp = closenessWeight[rTop-r+cH:rBottom-r+cH+1, cLeft-c+cW:cRight-c+cW+1]
            # 兩個權重模闆相乘
            weightTemp= similarityWeightTemp * closenessWeightTemp
            # 歸一化權重模闆
            weightTemp = weightTemp / np.sum(weightTemp)
            # 權重模闆和對應的鄰域值相乘求和
            bflGrayImage[r][c] = np.sum(region * weightTemp)
    return bflGrayImage


if __name__ == '__main__':
    image = cv.imread('./img1.png', 0)
    print(image.shape)
    # 顯示原圖
    cv.imshow("image", image)
    # 将灰階值歸一化
    image = image / 255
    # 雙邊濾波
    bfltImage = bfltGray(image, 51, 51, 30, 0.2)
    # 顯示雙邊濾波的結果
    cv.imshow("bflt", bfltImage)

    gauImage = cv.GaussianBlur(image, (51, 51), 5)
    cv.imshow("gaussian", gauImage)
    blurImage = cv.blur(image, (51, 51))
    cv.imshow("blur", blurImage)
    cv.waitKey(0)
    cv.destroyAllWindows()
           

  下圖分别為原圖像,雙邊濾波(卷積核大小51x51,距離權重模闆标準差30,相似性權重模闆标準差0.2),高斯濾波(卷積核大小51x51,标準差5),均值濾波(核大小51x51)。顯然,雙邊濾波對原圖平滑的同時保持了物體的邊緣,而高斯濾波和均值濾波雖然對圖像有平滑作用,但是令原圖的邊緣更加模糊。

  與高斯平滑、均值平滑處理相比較,顯然雙邊濾波在平滑作用的基礎上,保持了圖像中目标的邊緣,但是由于每個位置都需要重新計算權重模闆,是以會非常耗時(研究者有提出過雙邊濾波的快速算法)。

OpenCV--Python 圖像平滑之中值平滑、雙邊濾波、聯合雙邊濾波、導向濾波

OpenCV函數

dst=cv.bilateralFilter(src, d, sigmaColor, sigmaSpace[, dst[, borderType]])

參數 解釋
src 原圖像矩陣
d 視窗大小
sigmaColor 相當于空間距離權重模闆的标準差,盡量大
sigmaSpace 相當于相似性權重模闆的标準差,盡量小

總結

  雙邊濾波可以在平滑圖像的同時保證其中物體的邊緣,但是平滑效果沒有高斯濾波好,保持邊緣的效果比中值濾波好,但是非常耗時(比中值濾波要耗時)。

  對有紋理的圖像進行平滑處理時,希望将高斯平滑和雙邊濾波處理後的特性結合起來,即在平滑紋理的同時保留邊緣,下文要介紹的聯合雙邊濾波可以做到這一點。

3. 聯合雙邊濾波

原理詳解

  聯合雙邊濾波與雙邊濾波類似。

  首先,對每個位置的鄰域建構空間距離權重模闆。與上文雙邊濾波建構空間距離權重模闆一樣。

  然後,建構相似性權重模闆。這是與雙邊濾波唯一的不同之處,雙邊濾波是根據原圖,對于每一個位置,通過該位置和其鄰域的灰階值的差的指數來估計相似性;而聯合雙邊濾波是首先對原圖進行高斯平滑,根據平滑的結果,用目前位置及其鄰域的值的差來估計相似性權重模闆。

  接下來,空間距離權重模闆和相似性權重模闆點乘,然後歸一化,作為最後的權重模闆。最後将權重模闆與原圖(注意不是高斯平滑的結果)在該位置的鄰域對應位置積的和作為輸出值。整個過程隻在第二步計算相似度權重模闆時和雙邊濾波不同,但是對圖像平滑的效果,特别是對紋理圖像來說,卻有很大的不同。

Python實作

  通過定義函數

joinBLF

實作聯合雙邊濾波,其中建構空間距離權重模闆的函數

getClosenessWeight

和雙邊濾波是一樣的,參數 I \mathrm{I} I 代表輸入矩陣,注意這裡不需要像雙邊濾波那樣進行灰階值歸一化; H , W \mathrm{H,W} H,W 分别代表權重模闆的高和寬,兩者均為奇數;sigma_g 和 sigma_d 分别代表空間距離權重模闆和相似性權重模闆的标準差,這四個參數和雙邊濾波的定義是一樣的。在雙邊濾波的實作代碼中,并沒有像卷積平滑那樣對邊界進行擴充,需要在代碼中判斷邊界,為了省去判斷邊界的問題,在聯合雙邊濾波的實作中對矩陣進行邊界擴充操作,即參數

borderType

的含義,對于擴充邊界的處理,這一點就類似于 OpenCV 實作的雙邊濾波,代碼如下:

import cv2 as cv
import numpy as np
import math

def getClosenessWeight(sigma_g, H, W):
    r, c = np.mgrid[0:H:1, 0:W:1]
    r -= (H - 1) // 2
    c -= (W - 1) // 2
    closeWeight = np.exp(-0.5*np.power(r, 2) + np.power(c, 2) / math.pow(sigma_g, 2))
    return closeWeight

def joinBLF(I, H, W, sigma_g, sigma_d, borderType=cv.BORDER_DEFAULT):
    # 建構空間距離權重模闆
    closenessWeight = getClosenessWeight(sigma_g, H, W)
    # 對I進行高斯平滑
    Ig = cv.GaussianBlur(I, (H, W), sigma_g)
    # 模闆的中心點位置
    cH = (H - 1) // 2
    cW = (W - 1) // 2
    # 對原圖和高斯平滑的結果擴充邊界
    Ip = cv.copyMakeBorder(I, cH, cH, cW, cW, borderType)
    Igp = cv.copyMakeBorder(Ig, cH, cH, cW, cW, borderType)
    # 圖像矩陣的行和列
    rows, cols = I.shape
    i, j = 0, 0
    # 聯合雙邊濾波的結果
    jblf = np.zeros(I.shape, np.float64)
    for r in range(cH, cH+rows, 1):
        for c in range(cW, cW+cols, 1):
            # 目前位置的值
            pixels = Igp[r][c]
            # 目前位置的鄰域
            rTop, rBottom = r-cH, r+cH
            cLeft, cRight = c-cW, c+cW
            # 從Igp中截取該鄰域,用于建構相似性權重模闆
            region = Igp[rTop:rBottom+1, cLeft:cRight+1]
            # 通過上述鄰域,建構該位置的相似性權重模闆
            similarityWeight = np.exp(-0.5 * np.power(region-pixels, 2.0) / math.pow(sigma_d, 2.0))
            # 相似性權重模闆和空間距離權重模闆相乘
            weight = closenessWeight * similarityWeight
            # 将權重模闆歸一化
            weight = weight / np.sum(weight)
            # 權重模闆和鄰域對應位置相乘并相加
            jblf[i][j] = np.sum(Ip[rTop:rBottom+1, cLeft:cRight+1] * weight)
            j += 1
        j = 0
        i += 1
    return jblf

if __name__ == '__main__':
    img = cv.imread('./img3.jpg', 0)
    cv.imshow('src', img)
    # 将8位圖轉換為浮點型
    fI = img.astype(np.float64)
    # 聯合雙邊濾波,傳回值的資料類型為浮點型
    jblf = joinBLF(img, 27, 27, 80, 5)
    # 轉換為8位圖
    jblf = np.round(jblf)
    jblf = jblf.astype(np.uint8)
    cv.imshow('jblf', jblf)
    cv.waitKey(0)
    cv.destroyAllWindows()
           

  對于函數

copyMakeBorder

的說明可以看 二維離散卷積的same卷積部分 或者 官方文檔

OpenCV函數

dst=cv.ximgproc.jointBilateralFilter(joint, src, d, sigmaColor, sigmaSpace[, dst[, borderType]])

此函數的參數

src

,

d

,

sigmaColor

,

sigmaSpace

都與雙邊濾波一樣,隻介紹一下參數

joint

, 這個參數就對應于原理詳解部分的高斯平滑後的圖像,Python示例如下:

img = cv.imread('./img3.jpg', 0)
cv.imshow('src', img)
# 均值平滑
img_mean = cv.blur(img, (27, 27), borderType=cv.BORDER_DEFAULT)
cv.imshow('mean', img_mean)
# 雙邊濾波
img_bilateral = cv.bilateralFilter(img, 27, 80, 5, borderType=cv.BORDER_DEFAULT)
cv.imshow('bilateral', img_bilateral)
# 聯合雙邊濾波
img_gaussian = cv.GaussianBlur(img, (27, 27), 80, borderType=cv.BORDER_DEFAULT)
img_joint = cv.ximgproc.jointBilateralFilter(img_gaussian, img, 27, 80, 5, borderType=cv.BORDER_DEFAULT)
cv.imshow('joint', img_joint)

cv.waitKey(0)
cv.destroyAllWindows()
           

下圖為原圖,均值平滑,雙邊濾波,聯合雙邊濾波後的圖像。

OpenCV--Python 圖像平滑之中值平滑、雙邊濾波、聯合雙邊濾波、導向濾波

如果出現錯誤

AttributeError: module 'cv2.cv2' has no attribute 'jointBilateralFilter'

,可使用以下指令安裝

opencv-contrib-python

後可使用函數

jointBilateralFilter

,若通過以下指令解決不了問題,可自行查找解決辦法。

pip3 install opencv-contrib-python
           

總結

  基于雙邊濾波和聯合雙邊濾波,又提出了循環導向濾波,雙邊濾波是根據原圖計算相似性權重模闆的,聯合雙邊濾波對其進行了改進,是根據圖像的高斯平滑結果計算相似性權重模闆的,而循環導向濾波,顧名思義,是一種疊代的方法,本質上是一種多次疊代的聯合雙邊濾波,隻是每次計算相似性權重模闆的依據不一樣——利用本次計算的聯合雙邊濾波結果作為下一次聯合雙邊計算相似度權重模闆的依據。下面介紹不依賴于權重模闆的保持邊緣的濾波方法——導向濾波。

4. 導向濾波

原理詳解

  導向濾波是 K a i m i n g    H e \mathrm{Kaiming \;He} KaimingHe 提出的。 導向濾波在平滑圖像的基礎上,有良好的保邊作用,而且在細節增強等方面都有良好的表現,在執行時間上也比雙邊濾波快很多。

   輸入: 導向圖像 I I I ,濾波輸入圖像 p p p ,均值平滑的視窗半徑 r r r,正則化參數 ϵ \epsilon ϵ。利用導向濾波進行圖像的平滑處理時,通常令 p = I p = I p=I。

   輸出: 導向濾波結果 q q q

   m e a n I = f m e a n ( I , r ) mean_I = f_{mean}(I, r) meanI​=fmean​(I,r)

   m e a n p = f m e a n ( p , r ) mean_p = f_{mean}(p, r) meanp​=fmean​(p,r)

   c o r r I = f m e a n ( I . ∗ I , r ) corr_I = f_{mean}(I.* I, r) corrI​=fmean​(I.∗I,r)

   c o r r I p = f m e a n ( I . ∗ p , r ) corr_{Ip} = f_{mean}(I .* p, r) corrIp​=fmean​(I.∗p,r)

   v a r I = c o r r I − m e a n I . ∗ m e a n I var_I = corr_I - mean_{I} .* mean_I varI​=corrI​−meanI​.∗meanI​

   c o v I p = c o r r I p − m e a n I . ∗ m e a n p cov_{Ip} = corr_{Ip} - mean_{I} .* mean_p covIp​=corrIp​−meanI​.∗meanp​

   a = c o v I p . / ( v a r I + ϵ ) a = cov_{Ip} ./(var_I + \epsilon) a=covIp​./(varI​+ϵ)

   b = m e a n p − a . ∗ m e a n I b = mean_p - a .* mean_I b=meanp​−a.∗meanI​

   m e a n a = f m e a n ( a , r ) mean_a = f_{mean}(a, r) meana​=fmean​(a,r)

   m e a n b = f m e a n ( b , r ) mean_b = f_{mean}(b, r) meanb​=fmean​(b,r)

   q = m e a n a . ∗ I + m e a n b q = mean_a .* I + mean_b q=meana​.∗I+meanb​

  其中 f m e a n f_{mean} fmean​ 代表均值平滑; . ∗ .* .∗ 代表兩個圖像矩陣對應值相乘; . / ./ ./ 代表兩個圖像矩陣對應值相除。從僞代碼中可以看出,多次使用了均值平滑。需要注意的是, I I I 和 q q q 均是歸一化的圖像矩陣,結果 q q q 也是灰階值範圍為 [ 0 , 1 ] [0, 1] [0,1] 的圖像矩陣。

Python實作

  通過定義函數

guidedFilter

實作導向濾波,其中參數

I

代表輸入的是灰階值歸一到 [ 0 , 1 ] [0,1] [0,1] 的浮點型矩陣,

winSize

代表均值卷積核視窗尺寸,寬、高為奇數,

eps

代表正則化參數。傳回值為灰階值範圍在 [ 0 , 1 ] [0,1] [0,1] 之間的圖像矩陣,其中均值平滑可以使用Opencv中的函數

blur

或者

boxFilter

import math
import cv2 as cv
import numpy as np

def guidedFilter(I, p, winSize, eps):
    # 輸入圖像的高,寬
    rows, cols = I.shape
    # I的均值平滑
    mean_I = cv.blur(I, winSize, borderType=cv.BORDER_DEFAULT)
    # p的均值平滑
    mean_p = cv.blur(p, winSize, borderType=cv.BORDER_DEFAULT)
    # I .* p 的均值平滑
    Ip = I * p
    mean_Ip = cv.blur(Ip, winSize, borderType=cv.BORDER_DEFAULT)
    # 協方差
    cov_Ip = mean_Ip - mean_I * mean_p
    mean_II = cv.blur(I*I, winSize, borderType=cv.BORDER_DEFAULT)
    # 方差
    var_I = mean_II - mean_I * mean_I
    a = cov_Ip / (var_I + eps)
    b = mean_p - a * mean_I
    # 對a和b進行均值平滑
    mean_a = cv.blur(a, winSize, borderType=cv.BORDER_DEFAULT)
    mean_b = cv.blur(b, winSize, borderType=cv.BORDER_DEFAULT)
    q = mean_a * I + mean_b
    return b

if __name__ == '__main__':
    image = cv.imread('./img7.jpg', 0)
    # 将圖像進行歸一化
    image_0_1 = image / 255.0
    # 顯示原圖
    cv.imshow('image', image)
    # 導向濾波
    result = guidedFilter(image_0_1, image_0_1, (9, 9), math.pow(0.2, 2.0))
    cv.imshow('guidedFilter', result)
	# 細節增強
    result_enhanced = (image_0_1 - result) * 5 + result
    result_enhanced = cv.normalize(result_enhanced, result_enhanced, 1, 0, cv.NORM_MINMAX)
    cv.imshow('result_enhanced', result_enhanced)
    # 儲存導向濾波的結果
    result = result * 255
    result[result > 255] = 255
    result = np.round(result)
    result = result.astype(np.uint8)
    cv.imwrite('guidedFilter.jpg', result)
    
    cv.waitKey(0)
    cv.destroyAllWindows()
           

  在主函數中,需要注意導向濾波傳回的是灰階值範圍在 [ 0 , 1 ] [0,1] [0,1] 之間的圖像矩陣,如果想儲存8位圖,則首先乘以255,然後轉換資料類型就可以了。對于導向濾波,可以利用圖像的幾何變換進行加速。

快速導向濾波

可以通過先縮小圖像,然後再放大圖像,對導向濾波進行加速,提高執行效率。

下圖顯示了原圖、導向濾波後的圖像和通過細節增強後的圖像,細節增強後的圖像可能會比較暗,可以使用伽馬變換或者線性變換增加對比度或亮度。

OpenCV--Python 圖像平滑之中值平滑、雙邊濾波、聯合雙邊濾波、導向濾波

OpenCV函數

dst=cv.ximgproc.guidedFilter(guide, src, radius, eps[, dst[, dDepth]])

附上關于導向濾波的文獻

[1] K. He, J. Sun, and X. Tang. Guided image filtering. In ECCV, pages 1-14. 2010

[2] K. He, J. Sun, and X. Tang. Guided image filtering. TPAMI, 35(6): 1397-1409, 2013

總結

高斯平滑:dst=cv.GaussianBlur(src, ksize, sigmaX[, dst[, sigmaY[, borderType]]])

均值平滑:dst=cv.blur(src, ksize[, dst[, anchor[, borderType]]])

     dst = cv.boxFilter(src, ddepth, ksize[, dst[, anchor[, normalize[, borderType]]])

中值平滑:dst = cv.medianBlur(src, ksize[, dst])

雙邊濾波:dst=cv.bilateralFilter(src, d, sigmaColor, sigmaSpace[, dst[, borderType]])

聯合雙邊濾波:dst=cv.ximgproc.jointBilateralFilter(joint, src, d, sigmaColor, sigmaSpace[, dst[, borderType]])

導向濾波:dst=cv.ximgproc.guidedFilter(guide, src, radius, eps[, dst[, dDepth]])

  至此,圖像平滑的常用方法就介紹完了。圖像平滑的方法多種多樣,在實際應用中還要學會靈活運用,掌握其中的原理,并且和圖像增強的方法結合使用能達到很好的效果。