环境:Python3.8 和 OpenCV
内容:图像的双边滤波 -- 代码实现
双边滤波: 缺点:不适合处理椒盐噪声 优点:保留边缘等高频信息,平滑灰度相近的区域,综合考虑距离和颜色差异两种因素
空间卷积核矩阵:
色彩卷积核矩阵:
import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt
# 封装图片显示函数
def image_show(image):
if image.ndim == 2:
plt.imshow(image, cmap='gray')
else:
image = cv.cvtColor(image, cv.COLOR_BGR2RGB)
plt.imshow(image)
plt.show()
# 定义空间距离权重矩阵
def get_space(sigma_space, kernel):
# 初始化参数
space = np.zeros((kernel, kernel)) # 预配置距离权重空间
x = np.array([kernel//2, kernel//2]) # 得到位置坐标点
# 计算距离权重矩阵
for i in range(kernel):
for j in range(kernel):
k = np.array([i, j])
space[i, j] = np.exp(-0.5 * (np.linalg.norm(k - x) / sigma_space)**2)
# 归一化矩阵
space = space / np.sum(space)
return space
# 定义色彩差异权重矩阵
def get_color(image, sigma_color, kernel):
# 类型转换
image = np.float64(image)
# 计算色彩差异权重矩阵
color = np.exp(-0.5 * ((image - image[kernel // 2, kernel // 2]) / sigma_color) ** 2)
# 归一化矩阵
color = color / np.sum(color)
return color
if __name__ == '__main__':
# 读取灰度图像
img_desk = cv.imread('desk.png', 0)
image_show(img_desk)
# 双边滤波 -- 代码实现
# 参数初始化
para_color = 50 # 颜色差异卷积核参数
para_space = 3 # 距离差异卷积核参数
kernel_size = 11 # 卷积核的大小
[h_img, w_img] = img_desk.shape # 得到图片的长宽
img_bilateral = np.zeros((h_img, w_img)) # 初始化空白图片矩阵
# 得到空间距离矩阵
space_matrix = get_space(para_space, kernel_size)
# 迭代卷积运算
for i in range(h_img - kernel_size):
for j in range(w_img - kernel_size):
# 得到色彩差异矩阵
img_pixel = img_desk[i: i + kernel_size, j: j + kernel_size]
color_matrix = get_color(img_pixel, para_color, kernel_size)
# 计算卷积结果
kernel_out = space_matrix * color_matrix
# 归一化结果
kernel_out = kernel_out / np.sum(kernel_out)
# 得到最终输出图像
img_bilateral[i, j] = np.sum(img_pixel * kernel_out)
# 显示结果
image_show(img_bilateral)