import numpy as np
import cv2
from copy import deepcopy
from PIL import Image
from matplotlib import pyplot as plt
"""制造噪声图像"""
def add_salt_noise(img, snr=0.5):
SNR = snr # 指定信噪比(默认0.5)
size = img.size # 获取总共像素个数
# print(type(size))
noiseSize = int(size * (1 - SNR))
for i in range(0, noiseSize):
# 随机获取 某个点
xi = int(np.random.uniform(0, img.shape[1]))
xj = int(np.random.uniform(0, img.shape[0]))
if img.ndim == 2: # 判断是否为2维图像(即灰度图像)
img[xj, xi] = 0 # 设置值为黑点
elif img.ndim == 3:
img[xj, xi] = 0 # 设置值为黑点,也可以设置为白色255
return img
"""彩色图中值滤波"""
def median_Blur(img, filiter_size=3): # 当输入的图像为彩色图像
image_copy = np.array(img, copy=True).astype(np.float32)
processed = np.zeros_like(image_copy)
middle = int(filiter_size / 2)
r = np.zeros(filiter_size * filiter_size)
g = np.zeros(filiter_size * filiter_size)
b = np.zeros(filiter_size * filiter_size)
for i in range(middle, image_copy.shape[0] - middle):
for j in range(middle, image_copy.shape[1] - middle):
count = 0
# 依次取出模板中对应的像素值
for m in range(i - middle, i + middle + 1):
for n in range(j - middle, j + middle + 1):
r[count] = image_copy[m][n][0]
g[count] = image_copy[m][n][1]
b[count] = image_copy[m][n][2]
count += 1
r.sort() #从小到大排序
g.sort()
b.sort()
zz = int(filiter_size * filiter_size / 2) #得到中间值索引,排好序的9个数,中间值缩影为int(9/2) = 4
processed[i][j][0] = r[zz] #[i][j]表示像素位置
processed[i][j][1] = g[zz]
processed[i][j][2] = b[zz]
processed = np.clip(processed, 0, 255).astype(np.uint8)
return processed
"""灰度图中值滤波"""
def median_Blur_gray(img, filiter_size=3): # 当输入的图像为灰度图像
image_copy = np.array(img, copy=True).astype(np.float32)
processed = np.zeros_like(image_copy)
middle = int(filiter_size / 2)
for i in range(middle, image_copy.shape[0] - middle):
for j in range(middle, image_copy.shape[1] - middle):
temp = []
for m in range(i - middle, i + middle + 1):
for n in range(j - middle, j + middle + 1):
if m - middle < 0 or m + middle + 1 > image_copy.shape[0] or n - middle < 0 or n + middle + 1 > \
image_copy.shape[1]:
temp.append(0)
else:
temp.append(image_copy[m][n])
# count += 1
temp.sort()
processed[i][j] = temp[(int(filiter_size * filiter_size / 2) + 1)]
processed = np.clip(processed, 0, 255).astype(np.uint8)
return processed
if __name__ == "__main__":
img = input("Please input name of image:") # 默认是string类型
img = cv2.imread(img)
print("img.shape:", img.shape)
# plt.imshow显示cv2.imread读取的图像蓝与红有区别
b, g, r = cv2.split(img)
src_img = cv2.merge([r, g, b])
img_demo = deepcopy(src_img) #使得两图像不干扰
snr = float(input("Please input signal noise ratio:"))
img_salt = add_salt_noise(img_demo, snr)
filiter_size = int(input("Please input size of filiter:"))
median_blur = median_Blur(img_salt, filiter_size)
plt.figure("Image processing---MedianBlur") # 图像窗口名称
plt.subplot(1, 3, 1)
plt.imshow(src_img)
plt.axis('off') # 关掉坐标轴
plt.title("src_img")
plt.subplot(1, 3, 2)
plt.imshow(img_salt)
plt.axis('off') # 关掉坐标轴
plt.title("img_salt")
plt.subplot(1, 3, 3)
plt.imshow(median_blur)
plt.axis('off') # 关掉坐标轴
plt.title("median_blur")
plt.tight_layout() # 调整整体空白
plt.subplots_adjust(left=None, bottom=None, right=None, top=None,
wspace=None, hspace=None) # 调整子图间距
plt.savefig("reult.png", dpi=1000)
plt.show()
信噪比为0.5,卷积核为3,进行中值滤波得到了这样的对比图:
信噪比为0.9,卷积核为3,进行中值滤波得到了这样的对比图:
如果噪声够低,信噪比为0.99,进行中值滤波能得到这样的效果:
【定义】中值滤波是一种非线性的信号处理方法,所以它是一种非线性滤波器,也是一种统计排序滤波器。它将每一像素点的灰度值设置为该点某邻域窗口内的所有像素点灰度值的中值。
【目的】中值滤波对孤立的噪声像素即椒盐噪声、脉冲噪声具有良好的滤波效果,可以保持图像的边缘特性,不会使图像产生显著的模糊。
原文链接:https://blog.csdn.net/lixiao0314/article/details/120948652
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。