滤波的应用
高斯噪声和椒盐噪声 两者在视觉上的区别就是,高斯噪声是和原来图像像素值相关的噪声,而椒盐噪声则是很多的黑白像素点
高斯噪声 是一种加性噪声,即噪声直接加到原图像上,因此可以用线性滤波器滤除
椒盐噪声 又称为脉冲噪声,它是一种随机出现的白点(盐噪声)或者黑点(椒噪声),类似把椒盐撒在图像上,因此得名,如电视里的雪花噪声等。
椒盐噪声可以认为是一种逻辑噪声,用线性滤波器滤除的结果不好,一般采用中值滤波器滤波可以得到较好的结果
滤波操作
自适应中值滤波
高斯滤波
双边滤波
导向滤波
自适应中值滤波算法
图片没用部分的噪声
import cv2
import numpy as np
from matplotlib import pyplot as plt
# for gray image
# S_max mast be grather 3
def auto_median_filter(img, S_max):
output = img.copy()
def class_B(z_xy, z_med, z_max, z_min):
if (z_min < z_xy) & (z_xy < z_max):
return z_xy
else:
#z_xy 是个噪声,消除它: 使用z_med替换
return z_med
S_ori = 3
# cv2.copyMakeBorder() 函数是用来在图像周围添加边框的
# 增加边框,兼容边界的像素点
# 可以在开始的时候增加S_max厚度的边框,后面就不用动态增加了
# S_ori // 2 取整
copy = cv2.copyMakeBorder(img, *[S_ori // 2] * 4, borderType=cv2.BORDER_DEFAULT) # 补零
for i in range(img.shape[0]):
for j in range(img.shape[1]):
def class_A(copy, S_ori=3):
board = S_ori // 2
z_med = np.median(copy[i:i + board, j:j + board])
z_max = np.max(copy[i:i + board, j:j + board])
z_min = np.min(copy[i:i + board, j:j + board])
if (z_min < z_med) & (z_med < z_max):
# z_med 不是噪声
output[i, j] = class_B(copy[i, j], z_med, z_max, z_min)
else:
# next_size = S_ori + 2
# # z_med 是个噪声,增大滤波窗口,寻找下一个不是噪声的中值
next_size = cv2.copyMakeBorder(copy, *[1] * 4, borderType=cv2.BORDER_DEFAULT) # 增尺寸
S_ori = S_ori + 2
if S_ori <= S_max:
#
return class_A(next_size, S_ori)
else:
#到达最大窗口,没有找到"不是噪声的中值",直接中值滤波
output[i, j] = z_med
class_A(copy, 3)
return output.astype(np.uint8)
def label_def(): # 定义坐标数字字体及大小
plt.xticks(fontproperties='Times New Roman', size=8)
plt.yticks(fontproperties='Times New Roman', size=8)
if __name__ == '__main__':
img = cv2.imread('D://pictures//Fig0335(a)(ckt_board_saltpep_prob_pt05).tif', 0)
img_median = cv2.medianBlur(img, 7)
out = auto_median_filter(img, 7)
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False
plt.subplot(131), plt.imshow(img, "gray"), plt.title('椒盐噪声', fontsize='small'), label_def()
plt.subplot(132), plt.imshow(img_median, "gray"), plt.title('中值滤波', fontsize='small'), label_def()
plt.subplot(133), plt.imshow(out, "gray"), plt.title('自适应中值滤波', fontsize='small'), label_def()
plt.show()
高斯滤波
opencv函数 cv2.GaussianBlur(img,(3,3),1.3) 实现高斯滤波
其中(3,3)为滤波器的大小;1.3为滤波器的标准差,如果标准差这个参数设置为0,则程序会根据滤波器大小自动计算得到标准差。
图片内容里面噪声
import cv2
img=cv2.imread('../001.jpg')
#(3, 3)表示高斯滤波器的长和宽都为3,1.3表示滤波器的标准差
out=cv2.GaussianBlur(img,(3,3),1.3)
cv2.imwrite('out.jpg',out)
双边滤波
双边滤波是一种非线性滤波方法,是结合了图像的邻近度和像素值相似度的一种折中,在滤除噪声的同时可以保留原图的边缘信息。整个双边滤波是由两个函数构成:一个函数是由空间距离决定的滤波器系数,另外一个诗由像素差值决定的滤波器系数。
保全图像中的边缘信息,能在保持边界清晰的情况下有效的去除噪音
https://homepages.inf.ed.ac.uk/rbf/CVonline/LOCAL_COPIES/MANDUCHI1/Bilateral_Filtering.html
API形如:cv2.bilateralFilter(img, d, sigmaColor, sigmaSpace)
#API形如:cv2.bilateralFilter(img, d, sigmaColor, sigmaSpace)
import cv2
img = cv2.imread('11.png')
# 双边滤波
# params:img,处理半径 d=-1则自动计算,sigmaColor(灰度差权重),sigmaSpace(邻域距离权重)
# 灰度差越大(边缘),权重越小
# 邻域距离越大,权重越小
img01 = cv2.bilateralFilter(img, 51, 10, 10)
cv2.imshow("bilateralFilter01", img01)
https://zhuanlan.zhihu.com/p/522225954?utm_id=0
导向滤波
介绍-百度 http://www.taodudu.cc/news/show-5704877.html?action=onClick
在滤波效果上,引导滤波和双边滤波差不多,然后在一些细节上,引导滤波较好(在PS的磨皮美白中,经过亲生实践,效果更好)。
引导滤波最大的优势:可以写出时间复杂度与窗口大小无关的算法,因此在使用大窗口处理图片时,其效率更高。
import argparse # 导包
import cv2
import matplotlib.pyplot as plt
import skimage
#cv2.guidedFilter(guide, src, dst, radius, eps[, dDepth])
#guide: nparrayguided image (or array of images) with up to 3 channels,if it have more then 3 channels then only first 3 channels will be used.
#src: nparrayfiltering image with any numbers of channels.
#radius: intradius of Guided Filter.
#eps: floatregularization term of Guided Filter.{eps}^2 is similar to the sigma in the color space into bilateralFilter().
#dDepth: intoptional depth of the output image. 一般取-1
img=cv2.imread('../001.jpg')
guide=cv2.cvtColor(img,cv2.COLOR_RGB2GRAY) #用灰度图作为引导
dst1=cv2.ximgproc.guidedFilter(guide=guide,src=img,radius=8,eps=50,dDepth=-1)
dst2=cv2.ximgproc.guidedFilter(guide=guide,src=img,radius=8,eps=200,dDepth=-1)
dst3=cv2.ximgproc.guidedFilter(guide=guide,src=img,radius=8,eps=500,dDepth=-1)
cv2.imshow("Img",img)
cv2.imshow("dst1",dst1)
cv2.imshow("dst2",dst2)
cv2.imshow("dst3",dst3)