← 返回首页
图像噪点消除
发表时间:2025-02-20 00:57:00
图像噪点消除

图像噪声是图像在摄取或传输时所受的随机信号干扰,表现为图像信息或者像素亮度的随机变化。目前最常见的两者噪声是椒盐噪声和高斯噪声。

1.噪点

在图像领域噪点‌通常也指的是图像噪声(image noise)。即在影像表面形成的随机或固定的斑点或彩色污点,表现为照片中的“颗粒感”。噪点产生的原因包括感光元件的质量、感光度(ISO)的高低、曝光时间的长短等‌。噪点可以分为亮度噪点和颜色噪点,亮度噪点与光线亮度有关,而颜色噪点与色彩波动有关‌。

1.1 高斯噪声

高斯噪声是指它的概率密度函数服从高斯分布(即正态分布)的一类噪声。如果一个噪声,它的幅度分布服从高斯分布,而它的功率谱密度又是均匀分布的,则称它为高斯白噪声。高斯白噪声的二阶矩不相关,一阶矩为常数,是指先后信号在时间上的相关性。

产生原因: 1. 图像传感器在拍摄时不够明亮、亮度不够均匀; 2. 电路各元器件自身噪声和相互影响; 3. 图像传感器长期工作,温度过高。

1.2 椒盐噪声

椒盐噪声,椒盐噪声又称脉冲噪声,它随机改变一些像素值,是由图像传感器,传输信道,解码处理等产生的黑白相间的亮暗点噪声。椒盐噪声往往由图像切割引起。

2.滤波

滤波器:也可以叫做卷积核,与自适应二值化中的核一样,主要用于减少图像噪声,提取图像特征或增强图像的某些部分。滤波器本身是一个小的区域,有着特定的核值,并且工作原理也是在原图上进行滑动并计算中心像素点的像素值。滤波器可分为线性滤波和非线性滤波,线性滤波对邻域中的像素进行线性运算,如在核的范围内进行加权求和,常见的线性滤波器有均值滤波、高斯滤波等。非线性滤波则是利用原始图像与模板之间的一种逻辑关系得到结果,OpenCV提供了多种滤波方法,如均值滤波、中值滤波和高斯滤波等。

2.1 均值滤波(Mean Filter)

功能:对图像进行平滑处理,减少噪声。

应用场景: - 去除图像中的细小噪声。 - 模糊图像,弱化细节。

操作原理:使用一个固定大小的卷积核(如 3×3 或 5×5),计算该核内像素的平均值,并用平均值替换中心像素。

均值滤波是一种最简单的滤波处理,它取的是卷积核区域内元素的均值,如3x3的卷积核:

在OpenCV中,你可以使用cv2.blur()函数或者cv2.boxFilter()函数来实现均值滤波。以下是使用这两种方法的例子:

使用cv2.blur()函数可以用来应用均值滤波。你需要指定一个核(kernel)的大小,核越大,模糊效果越明显。

import cv2
import numpy as np

# 读取图像
image = cv2.imread('./images/jpg/personal01.jpg')

# 应用均值滤波,核大小为5x5
blurred_image = cv2.blur(image, (5, 5))

# 显示原图和模糊后的图像
cv2.imshow('Original Image', image)
cv2.imshow('Blurred Image', blurred_image)

cv2.waitKey(0)
cv2.destroyAllWindows()

使用cv2.boxFilter()函数也是用来实现均值滤波的,它允许你更灵活地控制归一化行为。如果不进行归一化,它将简单地计算卷积而没有除以核大小。

import cv2
import numpy as np

# 读取图像
image = cv2.imread('./images/jpg/personal01.jpg')

# 应用均值滤波,核大小为5x5,不进行归一化
blurred_image = cv2.boxFilter(image, -1, (5, 5), normalize=True)

# 显示原图和模糊后的图像
cv2.imshow('Original Image', image)
cv2.imshow('Blurred Image', blurred_image)

cv2.waitKey(0)
cv2.destroyAllWindows()

2.2 方框滤波(Box Filter)

与均值滤波不同的是方框滤波可以自由选择是否对均值滤波的结果进行归一化,即可以自由选择滤波结果是邻域像素值之和的平均值,还是邻域像素值之和。

仍然以 5×5 的邻域为例,如果计算的是邻域像素值的均值,则使用的卷积核为:

如果计算的是邻域像素值之和,则使用的卷积核为:

OpenCV使用cv2.boxFilter()函数实现方框滤波。

import cv2

lena = cv2.imread('./images/jpg/personal01.jpg',cv2.IMREAD_UNCHANGED)[::2, ::2, :]

img1 = cv2.boxFilter(src=lena, ddepth=-1, ksize=(3, 3), normalize=True)
img2 = cv2.boxFilter(src=lena, ddepth=-1, ksize=(3, 3), normalize=False)

cv2.imshow('Original', lena)
cv2.imshow('BoxFilter With normalize', img1)
cv2.imshow('BoxFilter No normalize', img2)
cv2.waitKey(0)
cv2.destroyAllWindows()

2.3 高斯滤波(Gaussian Blur)

功能: 平滑图像,减少噪声,同时尽可能保留边缘信息。

应用场景: - 去除高斯噪声。 - 模糊处理,常用于计算机视觉中的预处理步骤。

操作原理: 使用一个基于高斯分布权重的卷积核,距离中心越近的像素权重越大,生成平滑效果。

高斯滤波(Gaussian Blur)是一种常用于图像平滑处理的线性滤波技术,它能够有效地减少图像噪声。在OpenCV中,你可以使用cv2.GaussianBlur函数来应用高斯滤波。

import cv2
import numpy as np

# 读取图像
image = cv2.imread('./images/jpg/personal01.jpg')

# 应用高斯滤波
# 第一个参数是输入图像
# 第二个参数是内核大小,格式为(width, height),必须为正数和奇数
# 第三个参数是标准差,如果不指定,则从内核大小自动计算
blurred_image = cv2.GaussianBlur(image, (5, 5), 0)

# 显示原图和模糊后的图像
cv2.imshow('Original image', image)
cv2.imshow('Gaussian Blurred image', blurred_image)

# 等待任意键盘按键后关闭窗口
cv2.waitKey(0)
cv2.destroyAllWindows()

2.4 中值滤波(Median Filtering)

功能: 对图像进行平滑,去除“椒盐噪声”,保留边缘。

应用场景: - 图像去噪,特别是去除“盐和胡椒噪声”。 - 保留图像的边缘细节。

操作原理: 取卷积核内像素的中值,替代中心像素的值。

import cv2
import numpy as np

# 读取图片
image = cv2.imread('./images/jpg/personal01.jpg')

# 应用中值滤波
# 第二个参数是滤波器的大小,必须是正数和奇数
median_filtered_image = cv2.medianBlur(image, 5)

# 显示原图和滤波后的图片
cv2.imshow('Original Image', image)
cv2.imshow('Median Filtered Image', median_filtered_image)

# 等待任意键盘按键后关闭窗口
cv2.waitKey(0)
cv2.destroyAllWindows()

2.5 双边滤波(Bilateral Filter)

双边滤波(Bilateral Filter)是一种非线性的滤波器,它结合了高斯滤波和空间域滤波的优点,能够在保持边缘细节的同时减少图像噪声。双边滤波特别适用于图像降噪,同时保留边缘信息。

为什么要使用双边滤波? - 保留边缘信息:相比于简单的平均滤波或高斯滤波,双边滤波在平滑图像的同时,可以更好地保持图像的边缘信息。 - 减少噪声:对于含有较多噪点的图像,双边滤波可以有效地降低噪声水平。

代码实现:

import cv2
import numpy as np
from matplotlib import pyplot as plt

# 读取图像
image = cv2.imread('./images/jpg/personal01.jpg')

# 应用双边滤波
# 假设我们使用直径为9,sigmaColor为75,sigmaSpace为75
filtered_image = cv2.bilateralFilter(image, 13, 75, 75)

# 显示原图和滤波后的图像
plt.subplot(121), plt.imshow(cv2.cvtColor(image, cv2.COLOR_BGR2RGB)), plt.title('Original Image')
plt.subplot(122), plt.imshow(cv2.cvtColor(filtered_image, cv2.COLOR_BGR2RGB)), plt.title('Bilateral Filtered Image')
plt.show()

3. 图像降噪案例

下面是使用OpenCV实现上述五种滤波方法实现的图像降噪的代码示例:

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

#平均滤波
def apply_mean_filter(image):
    return cv2.blur(image, (7, 7))

#高斯滤波
def apply_gaussian_filter(image):
    return cv2.GaussianBlur(image, (13, 13), 1.0)

#中值滤波
def apply_median_filter(image):
    return cv2.medianBlur(image, 7)

#方框滤波
def apply_box_filter(image):
    return cv2.boxFilter(image, ddepth=-1, ksize=(7, 7), normalize=True)

#双边滤波
def apply_bilateral_filter(image):
    return cv2.bilateralFilter(image,13, 75, 75)


def display_images(original, mean_filtered, gaussian_filtered, median_filtered,box_filtered, bilateral_filter):
    titles = ['Original Image', 'Mean Filtered Image', 'Gaussian Filtered Image', 'Median Filtered Image','BoxFiltered Image','Bilateral Filter Image']
    images = [original, mean_filtered, gaussian_filtered, median_filtered,box_filtered,bilateral_filter]

    for i in range(6):
        plt.subplot(2, 3, i+1), plt.imshow(cv2.cvtColor(images[i], cv2.COLOR_BGR2RGB))
        plt.title(titles[i])
        plt.xticks([]), plt.yticks([])

    plt.show()

def main():
    image_path = './images/jpg/sample01.jpg'  # 请替换为你的图像路径
    image = cv2.imread(image_path)

    if image is None:
        print(f"Error: Unable to load image at {image_path}")
        return

    mean_filtered = apply_mean_filter(image)
    gaussian_filtered = apply_gaussian_filter(image)
    median_filtered = apply_median_filter(image)
    bilateral_filtered = apply_bilateral_filter(image)
    box_filtered = apply_box_filter(image)

    display_images(image, mean_filtered, gaussian_filtered, median_filtered,box_filtered, bilateral_filtered)

if __name__ == "__main__":
    main()

我们发现双边滤波(Bilateral Filter)的效果最好。