小工具知识网

当前位置: 首页 > 行业知识 > 图像预处理(2)图像去噪之常见的去噪方法

行业知识

图像预处理(2)图像去噪之常见的去噪方法

2026-11-12 00:37:43 来源:互联网转载

二、去噪的方法

书接上回,上回说到噪声有高斯噪声,泊松噪声,椒盐噪声,瑞利噪声,爱尔兰(伽马)噪声,均匀噪声,周期性分布噪声还有指数分布噪声(求指数分布噪声python的代码资源)没看过之前博客的小伙伴们请点击下方连接急速空降哦~

图像预处理(2)图像去噪之噪声的分类-CSDN博客

今儿咱看看图像去噪中常见的去噪方法(如有其他好的方法欢迎评论一起学习进步哦~)

有以下几种:

(大多是都是直接调用OpenCV库函数,因为我的侧重点不在此处,所以就是找现成的来用可以节省很多时间,如果大家想要弄清原理的请提前退出哈,不占用大家时间了)

1.均值滤波(Mean Filter):

将每个像素的值替换为其周围像素值的平均值,适用于轻度高斯噪声。

import cv2# 读取图像image = cv2.imread('xxx.jpg', 0)# 应用均值滤波filtered_image = cv2.blur(image, (5, 5))# 显示原始图像和滤波后的图像cv2.imshow('Original Image', image)cv2.imshow('Mean Filtered Image', filtered_image)cv2.waitKey(0)cv2.destroyAllWindows()

 结果图:

 在查找资料时有人把均值滤波分为三类:算数平均滤波、几何均值滤波、谐波平均滤波

并且提出了统计排序滤波分为:中值滤波、最大值和最小值滤波、中点滤波、修正阿尔法均值滤波

(此处不详细介绍了,如果有想知道的请移步↓图像噪声、去噪基本方法合集(Python实现)_点降噪代码python-CSDN博客)

2.中值滤波(Median Filter):

顾名思义就是将每个像素的值替换为其周围像素值的中值,适用于椒盐噪声。

import cv2import numpy as np# 读取图像image = cv2.imread('xxx.jpg', 0)# 定义中值滤波函数def median_filter(image, kernel_size):    height, width = image.shape    output = np.zeros((height, width), dtype=np.uint8)    pad = kernel_size // 2    for i in range(pad, height - pad):        for j in range(pad, width - pad):            window = image[i - pad:i + pad + 1, j - pad:j + pad + 1]            output[i, j] = np.median(window)    return output# 设置滤波器大小kernel_size = 3# 调用中值滤波函数filtered_image = median_filter(image, kernel_size)# 显示原始图像和滤波后的图像cv2.imshow('Original Image', image)cv2.imshow('Median Filtered Image', filtered_image)cv2.waitKey(0)cv2.destroyAllWindows()

 结果图:

3.高斯滤波(Gaussian Filter):

使用高斯核对图像进行平滑处理,适用于高斯噪声。

import cv2import numpy as npfrom PIL import Image# 对图像添加高斯噪声def add_gauss_noise(image, mean=0, val=0.01):    size = image.shape    # 对图像归一化处理    image = image / 255    gauss = np.random.normal(mean, val ** 0.05, size)    image = image + gauss    return image#读取图像img = cv2.imread('xxx.jpg')if img is None:    print('Failed to read the image')#图片是否存在cv2.imshow('img', img)cv2.waitKey(0)img1 = add_gauss_noise(img)#img不要改cv2.imshow('img1', img1)cv2.waitKey(0)img2 = cv2.GaussianBlur(img1, (0, 0), 1, 2)# ksize高斯矩阵的长宽 ksize高斯内核大小。# ksize.width和ksize.height可以不同,但它们都必须为正数和奇数,也可以为零# sigmaX:X方向上的高斯核标准偏差# sigmaY Y方向上的高斯核标准差# 如果sigmaY为零,则将其设置为等于sigmaX;# 如果两个sigmas为零,则分别从ksize.width和ksize.height计算得出# dst输出图像的大小和类型与src相同。#下面是我变换了一些参数img3 = cv2.GaussianBlur(img1, (9, 9), 1, 2)# cv_show('img3', img3)img4 = cv2.GaussianBlur(img1, (3, 3), 100, 2)# cv_show('img4', img4)img5 = cv2.GaussianBlur(img1, (3, 3), 1, 200)# cv_show('img5', img5)#进行显示vs2 = np.hstack((img2, img3))  # 水平堆叠vs3 = np.hstack((img4, img5))  # 水平堆叠result = np.vstack((vs2, vs3)) #垂直堆叠cv2.imshow('result', result)cv2.waitKey(0)

 调用了库中的cv2.GaussianBlur函数,函数的具体参数请见代码中的注释

结果图:img为原图,下面是添加噪声之后的图片,右边四幅为改变不同参数后的输出结果

4.小波去噪(Wavelet Denoising):

利用小波变换将信号分解为不同频率的子带,然后通过阈值处理去除噪声。

import cv2import numpy as npfrom pywt import dwt2, idwt2from PIL import Imageimg = cv2.imread('xxx.jpg')# 灰度变换gray_img = cv2.cvtColor(img, code=cv2.COLOR_BGR2GRAY)  # 灰度化cv2.imshow("gray_img", gray_img)cv2.waitKey(0)  # 等待按键命令cv2.destroyAllWindows()#对img进行haar小波变换:cA, (cH, cV, cD) = dwt2(gray_img, 'haar')#小波变换之后,低频分量对应的图像:zhangwen_a = cv2.imwrite('zhangwen_a.png', np.uint8(cA / np.max(cA) * 255))cv2.destroyAllWindows()# 小波变换之后,水平方向高频分量对应的图像:zhangwen_h = cv2.imwrite('zhangwen_h.png', np.uint8(cH / np.max(cH) * 255))# 小波变换之后,垂直平方向高频分量对应的图像:zhangwen_v = cv2.imwrite('zhangwen_v.png', np.uint8(cV / np.max(cV) * 255))# 小波变换之后,对角线方向高频分量对应的图像:zhangwen_d = cv2.imwrite('zhangwen_d.png', np.uint8(cD / np.max(cD) * 255))# 根据小波系数重构回去的图像rimg = idwt2((cA, (cH, cV, cD)), 'haar')cv2.imwrite('rimg.png', np.uint8(rimg))

 结果图:图片上方有该图片的名字可以对照着来看

5.非局部均值去噪(Non-Local Means Denoising):

利用图像中相似区域的信息来去除噪声,适用于保留图像细节的情况。

import cv2# 读取图像image = cv2.imread('xxx.jpg')# 应用非局部均值去噪denoised_image = cv2.fastNlMeansDenoisingColored(image, None, 10, 10, 7, 21)#其中,src为待处理的彩色图像(xxx.jpg)# h为控制噪声去除强度的参数# hForColorComponents为控制彩色分量权重的参数# templateWindowSize和searchWindowSize分别为局部均值计算和搜索窗口的大小# 显示原始图像和去噪后的图像cv2.imshow('Original Image', image)cv2.imshow('Denoised Image', denoised_image)cv2.waitKey(0)cv2.destroyAllWindows()

 cV2.fastNlMeansDenoisingColored是OpenCV库中的一个函数,用于去除彩色图像中的噪声。它是一种基于非局部均值去噪算法的改进版本,速度较快,适用于处理较大的图像。该函数的输入为待处理的彩色图像,输出为去噪后的图像。它的使用方法如下:

dst = cv2.fastNlMeansDenoisingColored(src, h,hForColorComponents,templatewindowSize,searchwindowSize)
  1. h: 决定滤波器的强度,值越大表示滤波器越强,去噪效果越明显。通常取值范围在10到30之间。

  2. hForColorComponents: 控制彩色分量的权重,可以单独调整每个颜色通道的权重。较大的值将增加对彩色信息的保留,较小的值将更多地依赖灰度信息。通常取值范围在10到30之间。

  3. templateWindowSize和searchWindowSize: 这两个参数影响了滤波器的窗口大小,较大的窗口可以更好地捕捉图像的结构信息,但会增加计算复杂度。通常取值范围在5到21之间。

通过调整这些参数,特别是hForColorComponents参数,可以自己控制彩色分量的权重,从而影响非局部均值去噪的效果。可以根据自己的需求和图像特性,尝试不同的参数组合来获得最佳的去噪效果。

在实际应用中,可以通过尝试不同的参数值并观察结果来选择最适合的参数组合。您可以根据具体的图像和要求进行调整,以达到最佳的去噪效果。

 

6.总变差去噪(Total Variation Denoising):

通过最小化图像的总变差来去除噪声,适用于保持图像边缘的情况。Python 中的总变差去噪(Total Variation Denoising)是一种常见的图像处理技术,可以用来去除图像中的噪声和平滑图像。总变差去噪的核心思想是通过最小化图像的总变差来实现去噪。

import numpy as npimport cvxpy as cpfrom matplotlib import pyplot as pltdef total_variation_denoising(image, lambda_tv=0.1, num_iters=100):    height, width = image.shape    x = cp.Variable((height, width))    objective = cp.Minimize(cp.norm(x - image, 'fro') + lambda_tv * cp.tv(x))    constraints = []    problem = cp.Problem(objective, constraints)    problem.solve(max_iters=num_iters)    denoised_image = x.value    return denoised_image# 读取图像image = cv2.imread('input_image.jpg', cv2.IMREAD_GRAYSCALE)# 转换为浮点数image = image.astype(np.float64)# 应用总变差去噪denoised_image = total_variation_denoising(image, lambda_tv=0.1, num_iters=100)# 显示原始图像和去噪后的图像plt.subplot(1, 2, 1)plt.imshow(image, cmap='gray')plt.title('Original Image')plt.axis('off')plt.subplot(1, 2, 2)plt.imshow(denoised_image, cmap='gray')plt.title('Denoised Image')plt.axis('off')plt.show()

在此代码运行过程中需要下载cvxpy库,下载的过程中我用的清华大学的镜像网站没有下载成功,我就去查阅到了相关资料,需要下载一个.whl文件,网址如下↓

Archived: Python Extension Packages for Windows - Christoph Gohlke (uci.edu)

网站截图如下↓ 需要选择对应自己Python版本的.whl文件

eg:python版本为3.10,64位的就要下载文件为cp38和amd64,也就是下图所示标红的文件

不过我的python是3.11的,这个方法就用不了咯,我还是选择老老实实的直接下载吧,下的贼慢还总容易超时最后也没有下载下来(逐渐烦躁ing),如果有什么好的下载方法欢迎评论哦~

在 Python 中,你可以使用以下库来实现总变差去噪:

  1. NumPy:NumPy 是一个 Python 库,用于科学计算和数值操作。使用 NumPy 可以方便地进行矩阵运算和数值计算,包括实现总变差去噪。

  2. SciPy:SciPy 是一个 Python 库,包含许多科学计算的工具和算法。SciPy 中包括了用于图像处理的模块,可以用来实现总变差去噪。

  3. OpenCV:OpenCV 是一个开源计算机视觉库,可以用于图像处理和计算机视觉应用。OpenCV 提供了很多图像处理函数和算法,包括总变差去噪算法。OpenCV-Python 图像去噪 | 五十九 - 掘金 (juejin.cn)

from PIL import Imageimport numpy as np#定义总变差去噪函数def total_variation_denoise(image, weight=0.2, num_iter=100):    u = np.copy(image)    px = np.zeros_like(image)    py = np.zeros_like(image)    tau = 0.125    for _ in range(num_iter):        u_old = u        # 计算梯度        grad_x = np.roll(u, -1, axis=1) - u        # 计算了数组 u 在水平方向上的梯度,并将结果存储在变量 grad_x 中。        grad_y = np.roll(u, -1, axis=0) - u        # np.roll(a, shift, axis=None)        # a: 要进行移位操作的数组。        # shift: 移位的数量,可以是正数(向右移动)或负数(向左移动)。        # axis: 沿着哪个轴进行移位操作,默认为 None,表示数组会被展平后进行移位。        # 更新梯度        px_new = px + tau * weight * grad_x        py_new = py + tau * weight * grad_y        norm = np.maximum(1, np.sqrt(px_new ** 2 + py_new ** 2))        # NumPy库中的np.maximum函数来计算给定参数的最大值。        # 计算px_new和py_new的欧几里德范数,然后将这个范数与1进行比较,返回一个新数组        # 其中每个元素是对应位置上的最大值,即要么是欧几里德范数的值,要么是 1中的较大值。        px = px_new / norm        py = py_new / norm        # 计算了向量(px_new, py_new)的单位向量,并将归一化后的结果存储在(px, py)中。        # 更新图像        rx = np.roll(px, 1, axis=1)        ry = np.roll(py, 1, axis=0)        p_p = (px - rx) + (py - ry)        u = u + tau * p_p    return u# 读取图像文件image_path = "xxx.jpg"image = Image.open(image_path)# 将图像转换为数组image_array = np.array(image)# 打印数组的形状和数据类型(可以不打印)print("Image Array Shape:", image_array.shape)print("Image Array Data Type:", image_array.dtype)# 添加高斯噪声noisy_image = image_array + 50 * np.random.rand(*image_array.shape)#50可以根据需求增加或减少#  如果没有图像可以采用下面的随机生成图像# # np.random.seed(42)# # image = np.random.rand(100, 100)# noisy_image = image + 0.1 * np.random.rand(100, 100)# 使用Total Variation去噪denoised_image = total_variation_denoise(noisy_image, weight=0.1, num_iter=100)#noisy_image 是输入的带有噪声的图像。(不需要改)#weight=0.1 是指定的总变差正则化项的权重,控制平滑度和保留细节之间的平衡。#较小的权重值会导致更平滑的图像,而较大的权重值会保留更多细节但可能会保留更多噪声。#num_iter=100 是指定的迭代次数,即算法执行的总变差去噪迭代次数。#较多的迭代次数可以更好地去除噪声,但也可能导致过度平滑。#权重和迭代次数需要自己根据实际情况进行更改# 显示原始图像、带噪声图像和去噪后的图像import matplotlib.pyplot as pltplt.figure(figsize=(10, 5))#创建新图形窗口的函数,这里宽度设置为10英寸,高度设置为5英寸plt.subplot(131)# 将当前的图形窗口分割成1行3列并选择第1个子图作为当前绘图区域。plt.imshow(image, cmap='gray')#以灰度的方式显示图像数据。plt.title('Original Image')plt.axis('off')#关闭坐标轴的显示(可以选择不加)plt.subplot(132)plt.imshow(noisy_image, cmap='gray')plt.title('Noisy Image')plt.axis('off')plt.subplot(133)plt.imshow(denoised_image, cmap='gray')plt.title('Denoised Image')plt.axis('off')plt.show()

 结果图:


 附:下载python库使用的国内镜像网站

我发现我身边的一些朋友刚接触Python的时候不知道要用镜像,估计看我文章的应该都会用国内镜像吧,不会的我在这里统一教一下吧

首先是几个国内的pip网站↓:

    阿里云 http://mirrors.aliyun.com/pypi/simple/ 

    中国科技大学 https://pypi.mirrors.ustc.edu.cn/simple/ 

    豆瓣(douban) http://pypi.douban.com/simple/ 

    清华大学 https://pypi.tuna.tsinghua.edu.cn/simple/ 

    中国科学技术大学 http://pypi.mirrors.ustc.edu.cn/simple/

ps:我个人用的清华大学的,用下来的感觉也不错,感觉还挺全的,其他的好像最开始的时候用过几个好像不太好用,之后才用的清华大学的,时间有点久了忘记了,如果想省事的话直接用清华的,强推(๑•̀ㅂ•́)و✧

下载包的格式就是:

pip install cvxpy -i http://pypi.mirrors.ustc.edu.cn/simple/ #cvxpy就是你要下的库的名字#http://pypi.mirrors.ustc.edu.cn/simple/#是清华大学的镜像网址,可以替换成上述其他的网址

我下载了pycharm↓:

 没下pycharm的应该在电脑终端下载(之前在哪里下现在还在那里下,只不过指令不一样而已)


写在后面的话:

图像去噪到此就告一段落啦,此篇文章仅供参考,目的是为了可以更好的梳理自己所查阅的知识,同时也希望可以让大家找资料的时候方便一些吧,文章中如果存在一些问题请即使和我沟通哈,如果大家有什么更好的提议也可以互相交流呀,谢谢大家啦 

如果有对掌纹方面或者识别方面感兴趣的欢迎大家加我的QQ哦~

qq:2311035985(为了研究新开的小号嘿嘿,放心加啦)

如果有什么好的提议或见解也欢迎大家加我QQ一起讨论哦~

上一篇:如何查询软件服务器的等级?

下一篇:揭秘时尚潮流背后的深层结构,探寻流行元素起源与发展!