读取图像,使用高斯滤波器(大小,标准差)来对加了噪声的图片进行降噪处理。
Author: Tian YJ
原图如下:
关于高斯滤波
高斯滤波器是一种可以使图像平滑的滤波器,用于去除噪声。可用于去除噪声的滤波器还有中值滤波器(参见问题十),平滑滤波器(参见问题十一)、LoG滤波器(参见问题十九)。
高斯滤波器将中心像素周围的像素按照高斯分布加权平均进行平滑化。这样的(二维)权值通常被称为卷积核(kernel)或者滤波器(filter)。
但是,由于图像的长宽可能不是滤波器大小的整数倍,因此我们需要在图像的边缘补。这种方法称作Zero Padding。并且权值(卷积核)要进行归一化操作()。
按下面的高斯分布公式计算权值:
具体过程如下图所示,假定中心点坐标为(0,0),当设定卷积核为3时,只需计算距离它最近的8个点,如图中的第一个矩阵所示。以此矩阵中的坐标,带入到公式中,并且取σ=1.5,则半径为1的权重矩阵如图中第二个矩阵所示。因为需要利用该权重矩阵做加权平均,故需要对原始的矩阵做归一化。具体操作方式是求出第二个矩阵的总和为0.4783,然后再将该矩阵的9个值分别除以0.4783,得到最终的卷积核(权重矩阵)。【参考】
通过上述步骤计算出高斯核,基于该高斯核便可进行高斯滤波操作。假设现有9个像素点,灰度值(0-255)如下图中第一个卷积核所示,计算图中中心点的滤波后的值。每个像素点乘以相对应的权重值,得到最终的分布值。将这9个像素的值相加得到的结果,就是中心位置图像滤波后的值。对所有点重复这个过程,就得到了高斯滤波后的图像。如果原图是彩色图片,可以对RGB三个通道分别做高斯滤波。
代码实现
# -*- coding: utf-8 -*-
"""
Created on Wed Apr 8 21:47:58 2020
@author: Tian YJ
"""
import cv2 # 我只用它来做图像读写和绘图,没调用它的其它函数哦
import numpy as np # 进行数值计算
from numpy import random # numpy中的随机函数
# 定义高斯滤波函数
def gaussian_filter(img, K_size=3, K_sigma=1.3):
# 获取图片尺寸
H, W, C = img.shape
# 图像边缘补零
pad = K_size // 2 # 使图像边缘能与滤波器中心对齐
out = np.zeros((H+2*pad, W+2*pad, C), dtype=np.float)
out[pad:pad+H, pad:pad+W] = img.copy().astype(np.float)
# 滤波器系数设置
K = np.zeros((K_size, K_size), dtype=np.float)
for x in range(-pad, -pad+K_size):
for y in range(-pad, -pad+K_size):
K[y + pad, x + pad] = np.exp( -(x ** 2 + y ** 2) / (2 * (K_sigma ** 2)))
K /= (2 * np.pi * K_sigma * K_sigma)
# 归一化
K /= K.sum()
tmp = out.copy()
# 进行滤波
for y in range(H):
for x in range(W):
for c in range(C):
out[pad+y, pad+x, c] = np.sum(K * out[y:y+K_size, x:x+K_size, c])
out = np.clip(out, 0, 255)
out = out[pad: pad + H, pad: pad + W].astype(np.uint8)
return out
# 读取图片
path = 'C:/Users/86187/Desktop/image/'
file_in = path + 'cake.jpg'
file_out = path + 'gaussian_filter.jpg'
img = cv2.imread(file_in)
# 获取图片尺寸
size = img.shape
# 创建一幅同样大小的噪声图加到原图像上
img_noise = 10 * random.standard_normal(size) #乘以10是为了让噪声看起来大一些
img = img + img_noise
cv2.imwrite('cake_noise.jpg', img)
# 调用函数进行高斯滤波
out = gaussian_filter(img, K_size=3, K_sigma=1.3)
# 保存图片
cv2.imwrite(file_out, out)
cv2.imshow("result", out)
cv2.waitKey(0)
cv2.destroyAllWindows()
结果展示
原图 | 加噪声 | 高斯滤波 |
---|---|---|