理论

参考此处原文
注意,里面的 \(\xi, x\) 都是二维向量。
只考虑空间距离:

\[h(x) = k_d^{-1} \int_{-\infty}^\infty \int_{-\infty}^\infty f(\xi)c(\xi - x) d\xi \]

\[k_d = \int_{-\infty}^\infty \int_{-\infty}^\infty c(\xi) d\xi \]

只考虑颜色差异:

\[h(x) = k_r^{-1} \int_{-\infty}^\infty \int_{-\infty}^\infty f(\xi)s(f(\xi) - f(x)) d\xi \]

\[k_r = \int_{-\infty}^\infty \int_{-\infty}^\infty s(f(\xi) - f(x)) d\xi \]

组合空间距离与颜色差异:

\[h(x) = k^{-1} \int_{-\infty}^\infty \int_{-\infty}^\infty f(\xi)c(\xi - x)s(f(\xi) - f(x)) d\xi \]

\[k = \int_{-\infty}^\infty \int_{-\infty}^\infty c(\xi - x)s(f(\xi) - f(x)) d\xi \]

距离公式通常用高斯函数:

\[c(\xi - x) = e^{-\frac{\lVert \xi-x \rVert^2}{2\sigma_d^2}} \]

\[s(f(\xi)- f(x)) = e^{-\frac{\lVert f(\xi)-f(x) \rVert^2}{2\sigma_r^2}} \]

实践

Python实现双边滤波

此算法比较复杂,文末有免费视频讲解链接。

import numpy as np
import matplotlib.pyplot as plt
import cv2 as cv

def show(img):
    if img.ndim == 2:
        plt.imshow(img, cmap='gray')
    else:
        plt.imshow(cv.cvtColor(img, cv.COLOR_BGR2RGB))
    plt.show()

def get_C(sigmad, n):
    C = np.zeros((n,n))
    
    # 0, 1, 2
    x = np.array([n//2, n//2])
    for i in range(n):
        for j in range(n):
            ksi = np.array([i, j])
            C[i,j] = np.exp(-0.5 * (np.linalg.norm(ksi - x) / sigmad)**2)
            
    C /= C.sum()
    return C

def get_S(f, sigmar, n):
    f = np.float64(f)
    
    S = np.exp(-0.5 * ((f - f[n//2, n//2]) / sigmar)**2)
            
    S /= S.sum()
    return S

img = cv.imread('pic/beer.jpg', 0)
sigmar = 50
sigmad = 3
n = 11

h, w = img.shape
img2 = np.zeros_like(img)


C = get_C(sigmad, n)

for i in range(h-n):
    for j in range(w-n):
        f = img[i:i+n, j:j+n]
        S = get_S(f, sigmar, n)
        K = C * S
        K /= K.sum()
        img2[i,j] = (f * K).sum()

show(img)
show(img2)

效果


说明:

  1. 未经许可,谢绝转载。
  2. 本教程为《数字图像处理Python OpenCV实战》的配套代码相关内容。
    免费视频教程为0-6章(标题号≤6),可在此处点击观看。
    所有课件及源代码可在此处下载:
    链接:https://pan.baidu.com/s/198PySe_vebO3e06idHSQ6g
    提取码:11o4
    有问题可在QQ群(1079300899)指出,进群答案:数字图像处理。在本文评论指出可能导致回复很晚。