当前位置:   article > 正文

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

图像去噪

二、去噪的方法

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

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

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

有以下几种:

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

1.均值滤波(Mean Filter)

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

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

 结果图:

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

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

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

2.中值滤波(Median Filter)

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

  1. import cv2
  2. import numpy as np
  3. # 读取图像
  4. image = cv2.imread('xxx.jpg', 0)
  5. # 定义中值滤波函数
  6. def median_filter(image, kernel_size):
  7. height, width = image.shape
  8. output = np.zeros((height, width), dtype=np.uint8)
  9. pad = kernel_size // 2
  10. for i in range(pad, height - pad):
  11. for j in range(pad, width - pad):
  12. window = image[i - pad:i + pad + 1, j - pad:j + pad + 1]
  13. output[i, j] = np.median(window)
  14. return output
  15. # 设置滤波器大小
  16. kernel_size = 3
  17. # 调用中值滤波函数
  18. filtered_image = median_filter(image, kernel_size)
  19. # 显示原始图像和滤波后的图像
  20. cv2.imshow('Original Image', image)
  21. cv2.imshow('Median Filtered Image', filtered_image)
  22. cv2.waitKey(0)
  23. cv2.destroyAllWindows()

 结果图:

3.高斯滤波(Gaussian Filter)

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

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

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

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

4.小波去噪(Wavelet Denoising)

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

  1. import cv2
  2. import numpy as np
  3. from pywt import dwt2, idwt2
  4. from PIL import Image
  5. img = cv2.imread('xxx.jpg')
  6. # 灰度变换
  7. gray_img = cv2.cvtColor(img, code=cv2.COLOR_BGR2GRAY) # 灰度化
  8. cv2.imshow("gray_img", gray_img)
  9. cv2.waitKey(0) # 等待按键命令
  10. cv2.destroyAllWindows()
  11. #对img进行haar小波变换:
  12. cA, (cH, cV, cD) = dwt2(gray_img, 'haar')
  13. #小波变换之后,低频分量对应的图像:
  14. zhangwen_a = cv2.imwrite('zhangwen_a.png', np.uint8(cA / np.max(cA) * 255))
  15. cv2.destroyAllWindows()
  16. # 小波变换之后,水平方向高频分量对应的图像:
  17. zhangwen_h = cv2.imwrite('zhangwen_h.png', np.uint8(cH / np.max(cH) * 255))
  18. # 小波变换之后,垂直平方向高频分量对应的图像:
  19. zhangwen_v = cv2.imwrite('zhangwen_v.png', np.uint8(cV / np.max(cV) * 255))
  20. # 小波变换之后,对角线方向高频分量对应的图像:
  21. zhangwen_d = cv2.imwrite('zhangwen_d.png', np.uint8(cD / np.max(cD) * 255))
  22. # 根据小波系数重构回去的图像
  23. rimg = idwt2((cA, (cH, cV, cD)), 'haar')
  24. cv2.imwrite('rimg.png', np.uint8(rimg))

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

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

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

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

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

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

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

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

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

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


 

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

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

  1. import numpy as np
  2. import cvxpy as cp
  3. from matplotlib import pyplot as plt
  4. def total_variation_denoising(image, lambda_tv=0.1, num_iters=100):
  5. height, width = image.shape
  6. x = cp.Variable((height, width))
  7. objective = cp.Minimize(cp.norm(x - image, 'fro') + lambda_tv * cp.tv(x))
  8. constraints = []
  9. problem = cp.Problem(objective, constraints)
  10. problem.solve(max_iters=num_iters)
  11. denoised_image = x.value
  12. return denoised_image
  13. # 读取图像
  14. image = cv2.imread('input_image.jpg', cv2.IMREAD_GRAYSCALE)
  15. # 转换为浮点数
  16. image = image.astype(np.float64)
  17. # 应用总变差去噪
  18. denoised_image = total_variation_denoising(image, lambda_tv=0.1, num_iters=100)
  19. # 显示原始图像和去噪后的图像
  20. plt.subplot(1, 2, 1)
  21. plt.imshow(image, cmap='gray')
  22. plt.title('Original Image')
  23. plt.axis('off')
  24. plt.subplot(1, 2, 2)
  25. plt.imshow(denoised_image, cmap='gray')
  26. plt.title('Denoised Image')
  27. plt.axis('off')
  28. 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)

  1. from PIL import Image
  2. import numpy as np
  3. #定义总变差去噪函数
  4. def total_variation_denoise(image, weight=0.2, num_iter=100):
  5. u = np.copy(image)
  6. px = np.zeros_like(image)
  7. py = np.zeros_like(image)
  8. tau = 0.125
  9. for _ in range(num_iter):
  10. u_old = u
  11. # 计算梯度
  12. grad_x = np.roll(u, -1, axis=1) - u
  13. # 计算了数组 u 在水平方向上的梯度,并将结果存储在变量 grad_x 中。
  14. grad_y = np.roll(u, -1, axis=0) - u
  15. # np.roll(a, shift, axis=None)
  16. # a: 要进行移位操作的数组。
  17. # shift: 移位的数量,可以是正数(向右移动)或负数(向左移动)。
  18. # axis: 沿着哪个轴进行移位操作,默认为 None,表示数组会被展平后进行移位。
  19. # 更新梯度
  20. px_new = px + tau * weight * grad_x
  21. py_new = py + tau * weight * grad_y
  22. norm = np.maximum(1, np.sqrt(px_new ** 2 + py_new ** 2))
  23. # NumPy库中的np.maximum函数来计算给定参数的最大值。
  24. # 计算px_new和py_new的欧几里德范数,然后将这个范数与1进行比较,返回一个新数组
  25. # 其中每个元素是对应位置上的最大值,即要么是欧几里德范数的值,要么是 1中的较大值。
  26. px = px_new / norm
  27. py = py_new / norm
  28. # 计算了向量(px_new, py_new)的单位向量,并将归一化后的结果存储在(px, py)中。
  29. # 更新图像
  30. rx = np.roll(px, 1, axis=1)
  31. ry = np.roll(py, 1, axis=0)
  32. div_p = (px - rx) + (py - ry)
  33. u = u + tau * div_p
  34. return u
  35. # 读取图像文件
  36. image_path = "xxx.jpg"
  37. image = Image.open(image_path)
  38. # 将图像转换为数组
  39. image_array = np.array(image)
  40. # 打印数组的形状和数据类型(可以不打印)
  41. print("Image Array Shape:", image_array.shape)
  42. print("Image Array Data Type:", image_array.dtype)
  43. # 添加高斯噪声
  44. noisy_image = image_array + 50 * np.random.rand(*image_array.shape)
  45. #50可以根据需求增加或减少
  46. # 如果没有图像可以采用下面的随机生成图像
  47. # # np.random.seed(42)
  48. # # image = np.random.rand(100, 100)
  49. # noisy_image = image + 0.1 * np.random.rand(100, 100)
  50. # 使用Total Variation去噪
  51. denoised_image = total_variation_denoise(noisy_image, weight=0.1, num_iter=100)
  52. #noisy_image 是输入的带有噪声的图像。(不需要改)
  53. #weight=0.1 是指定的总变差正则化项的权重,控制平滑度和保留细节之间的平衡。
  54. #较小的权重值会导致更平滑的图像,而较大的权重值会保留更多细节但可能会保留更多噪声。
  55. #num_iter=100 是指定的迭代次数,即算法执行的总变差去噪迭代次数。
  56. #较多的迭代次数可以更好地去除噪声,但也可能导致过度平滑。
  57. #权重和迭代次数需要自己根据实际情况进行更改
  58. # 显示原始图像、带噪声图像和去噪后的图像
  59. import matplotlib.pyplot as plt
  60. plt.figure(figsize=(10, 5))#创建新图形窗口的函数,这里宽度设置为10英寸,高度设置为5英寸
  61. plt.subplot(131)# 将当前的图形窗口分割成1行3列并选择第1个子图作为当前绘图区域。
  62. plt.imshow(image, cmap='gray')#以灰度的方式显示图像数据。
  63. plt.title('Original Image')
  64. plt.axis('off')#关闭坐标轴的显示(可以选择不加)
  65. plt.subplot(132)
  66. plt.imshow(noisy_image, cmap='gray')
  67. plt.title('Noisy Image')
  68. plt.axis('off')
  69. plt.subplot(133)
  70. plt.imshow(denoised_image, cmap='gray')
  71. plt.title('Denoised Image')
  72. plt.axis('off')
  73. 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:我个人用的清华大学的,用下来的感觉也不错,感觉还挺全的,其他的好像最开始的时候用过几个好像不太好用,之后才用的清华大学的,时间有点久了忘记了,如果想省事的话直接用清华的,强推(๑•̀ㅂ•́)و✧

下载包的格式就是:

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

我下载了pycharm↓:

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


写在后面的话:

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

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

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

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

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/很楠不爱3/article/detail/596359
推荐阅读
相关标签
  

闽ICP备14008679号