一、滤波方法
- 均值滤波normalized box filter(blur 线性,不同位置权值相同)
- 高斯滤波Gaussian filter(GaussianBlur,线性,不同位置权重不同)
- 中值滤波(medianBlur 非线性,保留边缘信息。中值滤波去除椒盐噪声和斑块噪声时,效果非常明显。
中值滤波对消除孤立点和线段的干扰十分有效,尤其是二值噪声,对高斯噪声效果不佳
方形和圆形:外轮廓线较长的物体图像。十字形:有尖角状。)
滤波器的尺寸越大,平滑效果越明显,图像也变得更模糊 - 双边滤波。在平滑图像时能够很好的保留边缘特性,但是其运算速度比较慢
二、噪声
1. 椒盐噪声:随机一个位置的像素值用0或255代替
椒盐噪声效果
import numpy as np
import cv2
from matplotlib import pyplot as plt
def generate_pepper(img,percentage):
img = img
num = int(img.shape[0]*img.shape[1]*percentage)
for i in range(num):
value = np.random.randint(0,2)# 产生0或1的随机值
random_x = np.random.randint(0,img.shape[0]-1)#生成随机位置
random_y = np.random.randint(0,img.shape[1]-1)
if value:#value 决定生成白点还是黑点
img[random_x,random_y] = 255
else:
img[random_x,random_y] = 0
return img
img = cv2.imread('../liu.jpg')
img1 = cv2.cvtColor(img,cv2.COLOR_BGR2RGB)
img2 = generate_pepper(img,0.1)
img2 = cv2.cvtColor(img,cv2.COLOR_BGR2RGB)
fig, axis = plt.subplots(1, 2, figsize=(10, 8))
axis[0].imshow(img1)
axis[0].axis('off')
axis[0].set_title('Source picture')
axis[1].imshow(img2)
axis[1].axis('off')
axis[1].set_title('Pepper noise')
# plt.imsave('pepper.jpg',img2)
plt.show()
2. 高斯噪声: 随机一个位置的像素值加上生成的高斯值,二者和大于255取255,小于0取0
高斯噪声效果
import random
import numpy as np
import cv2
from matplotlib import pyplot as plt
img_path = '../liu.jpg'
def generate_gauss(img1, mean, sigma, percentage):
img = img1
img = img.astype(float)# 类型转换。img是np.unit8类型,不能与高斯噪声直接相加,需转成float
num = int(img.shape[0] * img.shape[1] * percentage)
for i in range(num):# 生成随机位置
random_x = np.random.randint(0, img.shape[0] - 1)
random_y = np.random.randint(0, img.shape[1] - 1)
random_z = np.random.randint(0, img.shape[2] - 1)
value = np.array(random.gauss(mean, sigma))#产生高斯随机值
img[random_x, random_y] += value#叠加高斯随机值
img[random_x, random_y] += value
if img[random_x, random_y, random_z] > 255:# >255 和 <0的数据做处理
img[random_x, random_y, random_z] = 255
if img[random_x, random_y, random_z] < 0:
img[random_x, random_y, random_z] = 0
img = img.astype(np.uint8)# 计算完后,将数据格式转成opencv的格式
return img
img = cv2.imread(img_path)
img1 = cv2.cvtColor(img,cv2.COLOR_BGR2RGB)#画图方便
img2 = generate_gauss(img,0,1,0.8)
img2 = cv2.cvtColor(img2,cv2.COLOR_BGR2RGB)
fig, axis = plt.subplots(1, 2, figsize=(10, 8))
axis[0].imshow(img1)
axis[0].axis('off')
axis[0].set_title('Source picture')
axis[1].imshow(img2)
axis[1].axis('off')
axis[1].set_title('Gaussian noise')
plt.show()
三、滤波效果
高斯噪声下,不同滤波器产生的滤波效果
高斯噪声高斯滤波效果
中值滤波效果
kernal = 3时,不同滤波方法效果对比。中值滤波的效果要比另外两种好。
椒盐滤波滤波效果对比很明显,中值滤波能明显过滤掉椒盐噪声。
滤波代码
import cv2
from matplotlib import pyplot as plt
img = cv2.imread('pepper.jpg')
src = cv2.cvtColor(img,cv2.COLOR_BGR2RGB)
ksize = [3,5,7,9]
k = 3
mean_blur = cv2.blur(src, (k, k))
gaussian_blur = cv2.GaussianBlur(src, (k, k), 0) # blur 高斯滤波
median_blur = cv2.medianBlur(src, k) # blur 高斯滤波
fig, axis = plt.subplots(2, 2, figsize=(10, 8))
fig.suptitle('kernal size = 3')
axis[0,0].imshow(src)
axis[0,0].set_title('pepper picture')
axis[0,0].axis('off')
axis[0,1].imshow(mean_blur)
axis[0,1].set_title('mean_blur')
axis[0,1].axis('off')
axis[1,0].imshow(gaussian_blur)
axis[1,0].set_title('gaussian_blur')
axis[1,0].axis('off')
axis[1,1].imshow(median_blur)
axis[1,1].set_title('median_blur')
axis[1,1].axis('off')
plt.subplots_adjust(wspace=0.1, hspace=0.3)
plt.show()
def mean_filter(img,ksize):
img = cv2.imread('gauss.jpg')
src = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
ksize = [3, 5, 7, 9]
fig, axis = plt.subplots(len(ksize), 2, figsize=(10, 8))
fig.suptitle('mean filter')
for i, k in enumerate(ksize):
de_noise = cv2.blur(src, (k, k)) # blur 均值滤波
axis[i, 0].imshow(src)
axis[i, 0].set_title('Gauss noise')
axis[i, 0].axis('off')
axis[i, 1].imshow(de_noise)
axis[i, 1].set_title('ksize=%d' % k)
axis[i, 1].axis('off')
plt.subplots_adjust(wspace=0.1, hspace=0.3)
plt.show()
def Gaussian_filter(img,ksize):
fig, axis = plt.subplots(len(ksize), 2, figsize=(1, 8))
fig.suptitle('Gaussian filter')
for i, k in enumerate(ksize):
de_noise = cv2.GaussianBlur(src, (k, k), 0) # blur 高斯滤波
axis[i, 0].imshow(src)
axis[i, 0].set_title('Gauss noise')
axis[i, 0].axis('off')
axis[i, 1].imshow(de_noise)
axis[i, 1].set_title('ksize=%d' % k)
axis[i, 1].axis('off')
plt.subplots_adjust(wspace=0.1, hspace=0.3)
plt.show()
print(type(axis), axis.shape)
def Median_filter(img,ksize):
fig, axis = plt.subplots(len(ksize), 2, figsize=(1, 8))
fig.suptitle('Gaussian filter')
for i, k in enumerate(ksize):
de_noise = cv2.medianBlur(src, k) # blur 均值滤波
axis[i, 0].imshow(src)
axis[i, 0].set_title('Gauss noise')
axis[i, 0].axis('off')
axis[i, 1].imshow(de_noise)
axis[i, 1].set_title('ksize=%d' % k)
axis[i, 1].axis('off')
plt.subplots_adjust(wspace=0.1, hspace=0.3)
plt.show()
print(type(axis), axis.shape)