数字图像处理python实现-图像去噪之空间域平滑线性滤波

平滑线性滤波器

图像去噪这一块内容庞杂,我本来打算和形态学处理一样用一篇博客介绍完整,但是当所有目录列出来后,还是打算分4篇博客进行介绍分别为空间域3篇和频率域1篇

这篇博客主要是空间域线性滤波

噪声类型为:

  1. 高斯噪声,
  2. 白噪声,
  3. 胡椒噪声,

效果方面为:

  1. 不(或者是非刻意)保边缘
  2. 保边缘

均值滤波

善于高斯噪声,其中分为两类均值滤波分别为:算术均值几何均值

算术均值:即求模板内的像素值平均值,理解:

  1. 假如当前点为平滑区域的点,那么与周围像素一起算均值后,其值必定保持不变
  2. 假如当前点为噪声点,那么与周围像素一起算均值后,其值必定减小,达到去噪效果
  3. 如果当前点为边缘区域的点,那么与周围像素一起算均值后,其值必定减小,则使得边缘变得模糊

几何均值:算是一个鸡肋滤波,基本无法使用,虽然可以有保边缘的作用,但是效果并不突出,在博客后面我补充了一个新的保边缘滤波故这里不做介绍

故算术均值滤波去高斯噪声不保边缘
代码如下: 其中不包含

import cv2
import cv2 as cv
import matplotlib.pyplot as plt
import numpy as np


def show(f, s, a, b, c):
    plt.subplot(a, b, c)
    plt.imshow(f, "gray")
    plt.axis('on')
    plt.title(s)


# 高斯噪声函数单行
def wgn(x, snr):
    snr = 10 ** (snr / 10.0)
    xpower = np.sum(x ** 2) / len(x)
    npower = xpower / snr
    return np.random.randn(len(x)) * np.sqrt(npower)


def main():
    original = plt.imread("lena.tiff", 0)
    rows, cols = original.shape
    original_noise = original.copy().astype(np.float64)

    # 生成噪声图像,信噪比为10
    for i in range(cols):
        original_noise[:, i] += wgn(original_noise[:, i], 10)

    mask = np.ones(9).reshape(3, 3)
    ImageDenoise = np.zeros(original.shape)
    for i in range(1, rows - 1):
        for j in range(1, cols - 1):
            ImageDenoise[i, j] = np.mean(original[i - 1:i + 2, j - 1:j + 2] * mask)

    plt.figure()
    show(original, "original", 2, 2, 1)
    show(original_noise, "original_noise", 2, 2, 2)
    show(ImageDenoise, "ImageDenoise", 2, 2, 3)
    show(original - ImageDenoise, "original - ImageDenoise", 2, 2, 4)
    plt.show()


if __name__ == '__main__':
    main()

效果如下:
在这里插入图片描述

谐(逆谐)波均值滤波

这个主要针对的盐噪声或者胡椒噪声,但是这个基本上也不会使用,因为处理上面两种噪声统计排序滤波有着极大优势!!!(下篇会有介绍),故这里不做特别介绍,读者只需要明白其中思想即可

有选择保边缘平滑滤波(保边缘)

在这里插入图片描述
其中在高斯噪声方面表现较差,而对于椒盐噪声表现良好,这里代码给出处理椒盐噪声的效果(噪声个数为2 * max(行数,列数)),需要理解为什么能够保边缘才是这个滤波的关键!!!
代码如下:可以看出残差图基本上就是噪声模式


# 添加椒盐噪声
def pepperNoise(count, I):
    rows, cols = I.shape
    newI = np.copy(I)
    for i in range(count):
        if i % 2 == 0:
            newI[random.randint(0, rows - 1)][random.randint(0, cols - 1)] = 0
        else:
            newI[random.randint(0, rows - 1)][random.randint(0, cols - 1)] = 255
    return newI

# 有选择保边缘平滑方法
def edgeFilter(noise):
    rows, cols = noise.shape
    deNoise = np.zeros(noise.shape)
    # 生成滤波模板下标数组
    maskRect = np.ones(9).reshape(3, 3)

    maskPentTop = np.array([1, 1, 1, 1, 1, 1, 0, 1, 0]).reshape(3, 3)
    maskPentLeft = np.array([1, 1, 0, 1, 1, 1, 1, 1, 0]).reshape(3, 3)
    maskPentBottom = np.array([0, 1, 0, 1, 1, 1, 1, 1, 1]).reshape(3, 3)
    maskPentRight = np.array([0, 1, 1, 1, 1, 1, 0, 1, 1]).reshape(3, 3)

    maskHexagon1 = np.array([1, 1, 0, 1, 1, 1, 0, 1, 1]).reshape(3, 3)
    maskHexagon2 = np.array([0, 1, 1, 1, 1, 1, 1, 1, 0]).reshape(3, 3)
    maskHexagon3 = np.array([0, 1, 1, 1, 1, 1, 1, 1, 0]).reshape(3, 3)
    maskHexagon4 = np.array([1, 1, 0, 1, 1, 1, 0, 1, 1]).reshape(3, 3)

    for i in range(2, rows - 2):
        for j in range(2, cols - 2):
            maskList = []
            array_var = []
            maskList.append(noise[i - 2:i + 1, j - 2:j + 1] * maskHexagon1)
            maskList.append(noise[i - 2:i + 1, j - 1:j + 2] * maskPentTop)
            maskList.append(noise[i - 2:i + 1, j:j + 3] * maskHexagon2)
            maskList.append(noise[i - 1:i + 2, j - 2:j + 1] * maskPentLeft)
            maskList.append(noise[i - 1:i + 2, j - 1:j + 2] * maskRect)
            maskList.append(noise[i - 1:i + 2, j:j + 3] * maskPentRight)
            maskList.append(noise[i:i + 3, j - 2:j + 1] * maskHexagon3)
            maskList.append(noise[i:i + 3, j - 1:j + 2] * maskPentBottom)
            maskList.append(noise[i:i + 3, j:j + 3] * maskHexagon4)

            array_var.append(np.var(noise[i - 2:i + 1, j - 2:j + 1] * maskHexagon1))
            array_var.append(np.var(noise[i - 2:i + 1, j - 1:j + 2] * maskPentTop))
            array_var.append(np.var(noise[i - 2:i + 1, j:j + 3] * maskHexagon2))
            array_var.append(np.var(noise[i - 1:i + 2, j - 2:j + 1] * maskPentLeft))
            array_var.append(np.var(noise[i - 1:i + 2, j - 1:j + 2] * maskRect))
            array_var.append(np.var(noise[i - 1:i + 2, j:j + 3] * maskPentRight))
            array_var.append(np.var(noise[i:i + 3, j - 2:j + 1] * maskHexagon3))
            array_var.append(np.var(noise[i:i + 3, j - 1:j + 2] * maskPentBottom))
            array_var.append(np.var(noise[i:i + 3, j:j + 3] * maskHexagon4))

            deNoise[i, j] = np.mean(maskList[array_var.index(min(array_var))])

    return deNoise

效果如下:
在这里插入图片描述
总结:天下没有免费的午餐,当保边缘的时候必定会牺牲一定的速度
转载我博客应当经我允许,至少要把原文链接放在文章最前面,这是对本人辛苦原创基本的尊重。

上一篇:数字图像处理冈萨雷斯-图像增强篇
下一篇:数字图像处理python实现-图像去噪之空间域统计排序滤波

  • 6
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

图像弟弟

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值