赞
踩
书接上回,上回说到噪声有高斯噪声,泊松噪声,椒盐噪声,瑞利噪声,爱尔兰(伽马)噪声,均匀噪声,周期性分布噪声还有指数分布噪声(求指数分布噪声python的代码资源)没看过之前博客的小伙伴们请点击下方连接急速空降哦~
今儿咱看看图像去噪中常见的去噪方法(如有其他好的方法欢迎评论一起学习进步哦~)
有以下几种:
(大多是都是直接调用OpenCV库函数,因为我的侧重点不在此处,所以就是找现成的来用可以节省很多时间,如果大家想要弄清原理的请提前退出哈,不占用大家时间了)
将每个像素的值替换为其周围像素值的平均值,适用于轻度高斯噪声。
- 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博客)
顾名思义就是将每个像素的值替换为其周围像素值的中值,适用于椒盐噪声。
- import cv2
- import 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()

结果图:
使用高斯核对图像进行平滑处理,适用于高斯噪声。
- import cv2
- import numpy as np
- from 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为原图,下面是添加噪声之后的图片,右边四幅为改变不同参数后的输出结果
利用小波变换将信号分解为不同频率的子带,然后通过阈值处理去除噪声。
- import cv2
- import numpy as np
- from pywt import dwt2, idwt2
- from PIL import Image
-
- img = 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))

结果图:图片上方有该图片的名字可以对照着来看
利用图像中相似区域的信息来去除噪声,适用于保留图像细节的情况。
- 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)
h
: 决定滤波器的强度,值越大表示滤波器越强,去噪效果越明显。通常取值范围在10到30之间。
hForColorComponents
: 控制彩色分量的权重,可以单独调整每个颜色通道的权重。较大的值将增加对彩色信息的保留,较小的值将更多地依赖灰度信息。通常取值范围在10到30之间。
templateWindowSize
和searchWindowSize
: 这两个参数影响了滤波器的窗口大小,较大的窗口可以更好地捕捉图像的结构信息,但会增加计算复杂度。通常取值范围在5到21之间。
通过调整这些参数,特别是hForColorComponents
参数,可以自己控制彩色分量的权重,从而影响非局部均值去噪的效果。可以根据自己的需求和图像特性,尝试不同的参数组合来获得最佳的去噪效果。
在实际应用中,可以通过尝试不同的参数值并观察结果来选择最适合的参数组合。您可以根据具体的图像和要求进行调整,以达到最佳的去噪效果。
通过最小化图像的总变差来去除噪声,适用于保持图像边缘的情况。Python 中的总变差去噪(Total Variation Denoising)是一种常见的图像处理技术,可以用来去除图像中的噪声和平滑图像。总变差去噪的核心思想是通过最小化图像的总变差来实现去噪。
- import numpy as np
- import cvxpy as cp
- from matplotlib import pyplot as plt
-
- def 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 中,你可以使用以下库来实现总变差去噪:
NumPy:NumPy 是一个 Python 库,用于科学计算和数值操作。使用 NumPy 可以方便地进行矩阵运算和数值计算,包括实现总变差去噪。
SciPy:SciPy 是一个 Python 库,包含许多科学计算的工具和算法。SciPy 中包括了用于图像处理的模块,可以用来实现总变差去噪。
OpenCV:OpenCV 是一个开源计算机视觉库,可以用于图像处理和计算机视觉应用。OpenCV 提供了很多图像处理函数和算法,包括总变差去噪算法。OpenCV-Python 图像去噪 | 五十九 - 掘金 (juejin.cn)
- from PIL import Image
- import 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)
- div_p = (px - rx) + (py - ry)
- u = u + tau * div_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 plt
-
- plt.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的时候不知道要用镜像,估计看我文章的应该都会用国内镜像吧,不会的我在这里统一教一下吧
首先是几个国内的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一起讨论哦~
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。