灰度最邻近的K个邻点平均法(Python实现)

K nearest neighbor averaging

基本原理

在这里插入图片描述

编程实现

导入相应的库文件

%matplotlib inline
import numpy as np
import matplotlib.pyplot as plt
import skimage.util as util
from skimage import data, img_as_float
from skimage.metrics import structural_similarity as ssim
from skimage.metrics import mean_squared_error as MSE
from skimage.metrics import peak_signal_noise_ratio as psnr

读取skimage库自带的图像,cameraman,并添加噪声

img = img_as_float(data.camera())
rows, cols = img.shape
#noise_img = util.random_noise(img,mode='gaussian',var=0.05)
img_noise_1 = util.random_noise(img,mode='s&p')
img_noise_2 = util.random_noise(img,mode='gaussian',var = 0.1**2)

本程序添加的噪声类型有两种,高斯 噪声和椒盐噪声

fig, axes = plt.subplots(nrows=1, ncols=3, figsize=(10, 4))
ax = axes.ravel()

ax[0].imshow(img, cmap=plt.cm.gray, vmin=0, vmax=1)
ax[0].set_title('Original image')
ax[0].axis('off')

ax[1].imshow(img_noise_1, cmap=plt.cm.gray, vmin=0, vmax=1)
ax[1].set_title('Image with s&p noise')
ax[1].axis('off')

ax[2].imshow(img_noise_2, cmap=plt.cm.gray, vmin=0, vmax=1)
ax[2].set_title('Image with gaussian noise')
ax[2].axis('off')

在这里插入图片描述

定义函数实现k个零点平均

def K_nearest_average(noise_img,windows_size=3,k_num = 6):
    """
    # 本函数旨在实现灰度最邻近的K个邻点平均
    input:
    ------------------------------------
    noise_img: 输入的含噪声图像
    windows_size: 窗口的大小
    k_num: 灰度值最接近的K个邻点的平均灰度值来代替中心的灰度值
    output:
    ------------------------------------
    img_out: 最邻近的K个邻点平均去噪图像
    """
    rows, cols = noise_img.shape
    half_size = windows_size//2
    ndarray=np.pad(noise_img,(half_size,half_size),'constant')#对图像边界进行补零填充
    img_out = np.zeros((rows,cols),dtype='double')

    for x in range(half_size,rows):
        for y in range(half_size,cols):
            window = ndarray[x-half_size:x+half_size+1,y-half_size:y+half_size+1]
            window_flatten = (window-ndarray[x,y]).reshape(windows_size**2)
            temp = np.argsort(np.abs(window_flatten)) #按照与中心点的灰度值的差异值进行排序
            img_out[x-1,y-1] = np.average(window_flatten[temp[1:k_num+1]])+ndarray[x,y]
    return img_out

对含有椒盐噪声的图像去噪

并通过原图计算MSE、SSIM(结构相似性)、PSNR(峰值信噪比)来衡量图像质量的好坏

img_out1 = K_nearest_average(img_noise_1,3,6)
img_out2 = K_nearest_average(img_noise_1,3,3)
img_out3 = K_nearest_average(img_noise_1,5,12)

mse_noise = MSE(img, img_noise_1)
ssim_noise = ssim(img, img_noise_1,
                  data_range=img_noise_1.max() - img_noise_1.min())
psnr_noise =psnr(img,img_noise_1)

mse_out1 = MSE(img,img_out1)
ssim_out1 = ssim(img, img_out1,
                  data_range=img_out1.max() - img_out1.min())
psnr_out1 =psnr(img, img_out1)

mse_out2 = MSE(img,img_out2)
ssim_out2 = ssim(img, img_out2,
                  data_range=img_out2.max() - img_out2.min())
psnr_out2 =psnr(img, img_out2)

mse_out3 = MSE(img,img_out3)
ssim_out3 = ssim(img, img_out3,
                  data_range=img_out3.max() - img_out3.min())
psnr_out3 =psnr(img, img_out3)

fig, axes = plt.subplots(nrows=2, ncols=2, figsize=(18, 18))
ax = axes.ravel()
label = 'MSE:{:.4f},SSIM:{:.4f},psnr:{:.4f}'

ax[0].imshow(img_noise_1, cmap=plt.cm.gray, vmin=0, vmax=1)
ax[0].set_title('s&p noise image')
ax[0].set_xlabel(label.format(mse_noise, ssim_noise, psnr_noise))


ax[1].imshow(img_out1, cmap=plt.cm.gray, vmin=0, vmax=1)
ax[1].set_title('windows_size =3 ,k_num =6')
ax[1].set_xlabel(label.format(mse_out1, ssim_out1, psnr_out1))

ax[2].imshow(img_out2, cmap=plt.cm.gray, vmin=0, vmax=1)
ax[2].set_title('windows_size =3 ,k_num =3')
ax[2].set_xlabel(label.format(mse_out2, ssim_out2, psnr_out2))

ax[3].imshow(img_out3, cmap=plt.cm.gray, vmin=0, vmax=1)
ax[3].set_title('windows_size =5 ,k_num =12')
ax[3].set_xlabel(label.format(mse_out3, ssim_out3, psnr_out3))

plt.show()

在这里插入图片描述

对含有高斯噪声的图像去噪

并通过原图计算MSE、SSIM(结构相似性)、PSNR(峰值信噪比)来衡量图像质量的好坏

img_out4 = K_nearest_average(img_noise_2,3,6)
img_out5 = K_nearest_average(img_noise_2,3,3)
img_out6 = K_nearest_average(img_noise_2,5,12)

mse_noise = MSE(img, img_noise_2)
ssim_noise = ssim(img, img_noise_2,
                  data_range=img_noise_2.max() - img_noise_2.min())
psnr_noise =psnr(img,img_noise_2)

mse_out4 = MSE(img,img_out4)
ssim_out4 = ssim(img, img_out4,
                  data_range=img_out4.max() - img_out4.min())
psnr_out4 =psnr(img, img_out4)

mse_out5 = MSE(img,img_out5)
ssim_out5 = ssim(img, img_out5,
                  data_range=img_out5.max() - img_out5.min())
psnr_out5 =psnr(img, img_out5)

mse_out6 = MSE(img,img_out6)
ssim_out6 = ssim(img, img_out6,
                  data_range=img_out6.max() - img_out6.min())
psnr_out6 =psnr(img, img_out6)

fig, axes = plt.subplots(nrows=2, ncols=2, figsize=(18, 18))
ax = axes.ravel()
label = 'MSE:{:.4f},SSIM:{:.4f},psnr:{:.4f}'

ax[0].imshow(img_noise_2, cmap=plt.cm.gray, vmin=0, vmax=1)
ax[0].set_title('gaussian image')
ax[0].set_xlabel(label.format(mse_noise, ssim_noise, psnr_noise))


ax[1].imshow(img_out4, cmap=plt.cm.gray, vmin=0, vmax=1)
ax[1].set_title('windows_size =3 ,k_num =6')
ax[1].set_xlabel(label.format(mse_out4, ssim_out4, psnr_out4))

ax[2].imshow(img_out5, cmap=plt.cm.gray, vmin=0, vmax=1)
ax[2].set_title('windows_size =3 ,k_num =3')
ax[2].set_xlabel(label.format(mse_out5, ssim_out5, psnr_out5))

ax[3].imshow(img_out6, cmap=plt.cm.gray, vmin=0, vmax=1)
ax[3].set_title('windows_size =5 ,k_num =12')
ax[3].set_xlabel(label.format(mse_out6, ssim_out6, psnr_out6))

plt.show()

在这里插入图片描述

得出结论

较小的K值使噪声方差降低较少,但保持细节也较好;而较大的K值平滑噪声较好,但也将使图像模糊,对于3×3窗口,取K=6为宜

本人水平有限,欢迎批评指正!

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值