图像噪声、去噪基本方法合集(Python实现)

article/2025/9/28 2:38:53

文章目录

  • 前言
    • 本文主要参考冈萨雷斯的数字图像处理 (第4版),介绍图片中一些常见的噪声形式和常用的去噪方法,并且给出相应滤波方法的实现代码。
  • 一、噪声分类
    • 1、高斯噪声
    • 2、泊松噪声
    • 3、椒盐噪声
    • 4、瑞利噪声
    • 5、爱尔兰(伽马)噪声
    • 6、均匀噪声
  • 二、去噪方法
    • 1、均值滤波
      • 1.1 算术平均滤波
      • 1.2 几何均值滤波
      • 1.3 谐波平均滤波
    • 2、统计排序滤波
      • 2.1 中值滤波
      • 2.2 最大值和最小值滤波
      • 2.3 中点滤波
      • 2.4 修正阿尔法均值滤波
  • 总结
  • 参考文献:


前言

本文主要参考冈萨雷斯的数字图像处理 (第4版),介绍图片中一些常见的噪声形式和常用的去噪方法,并且给出相应滤波方法的实现代码。

如果要使用本文代码,建议在Jupyter Notebook环境下运行。

一、噪声分类

1、高斯噪声

指服从高斯分布(正态分布)的一类噪声,其产生的主要原因是由于相机在拍摄时视场较暗且亮度不均匀造成的,同时相机长时间工作使得温度过高也会引起高斯噪声,另外电路元器件白身噪声和互相影响也是造成高斯噪声的重要原因之一。
概率密度函数(PDF)如下:
在这里插入图片描述
初始图片:
在这里插入图片描述
注意加噪声时,不能直接将 noise+img,不然最终出来的是一片空白和零星几个噪点,原因在于cv2.imshow输入要求是 0-1 float 或者 0-255 int

(1)错误显示:
在这里插入图片描述

在这里插入图片描述
(2)正确显示:

import cv2
import random
import numpy as np
img = cv2.imread('A.png')# 产生高斯随机数
noise = np.random.normal(0,50,size=img.size).reshape(img.shape[0],img.shape[1],img.shape[2])
# 加上噪声
img = img + noise
img = np.clip(img,0,255)
img = img/255   cv2.imshow('Gauss noise',img)
cv2.waitKey(0)


(3)高斯滤波
高斯滤波是一种线性平滑滤波,一般用于消除高斯噪声。对于每一个像素点的值,是由其本身和邻域内的其他像素值经过加权平均后得到。
二维高斯函数:
在这里插入图片描述
具体过程:
在这里插入图片描述
代码:使用cv2.GaussianBlur()函数
在这里插入图片描述
注意高斯模糊半径不能为偶数
滤波结果:
在这里插入图片描述

2、泊松噪声

简言之就是符合泊松分布的噪声模型,又称散粒噪声。
在这里插入图片描述

使用**np.random.poisson()**函数

import cv2
import random
import numpy as np
img = cv2.imread('A.png')# 产生泊松噪声
noise = np.random.poisson(lam=20,size=img.shape).astype('uint8')# 加上噪声
img = img + noise
np.clip(img,0,255)
img = img/255cv2.imshow('Poisson noise',img)
cv2.waitKey(0)

在这里插入图片描述

λ值越大,噪声程度越深。

3、椒盐噪声

椒盐噪声又称为脉冲噪声,是在图像上随机出现黑色白色的像素,顾名思义就是椒盐噪声 = 椒噪声(值为0,黑色) + 盐噪声(值为255,白色)
直接上代码:

import cv2
import random
import numpy as np
img = cv2.imread('A.png')# 转化成向量
x = img.reshape(1,-1)  
# 设置信噪比
SNR = 0.85
# 得到要加噪的像素数目
noise_num = x.size * (1-SNR)
# 得到需要加噪的像素值的位置
list = random.sample(range(0,x.size),int(noise_num))for i in list:if random.random() >= 0.5:x[0][i] = 0else:x[0][i] = 255
img1 = x.reshape(img.shape)cv2.imshow('salt&pepper noise',img1)
cv2.waitKey(0)

在这里插入图片描述
SNR越小,噪声越大。

4、瑞利噪声

一般是由由信道不理想引起的,它与信号的关系是相乘,信号在它在,信号不在他也就不在。
瑞利密度对倾斜形状直方图的建模非常有用。

概率密度函数(PDF)如下:
在这里插入图片描述
很多地方给出的瑞利分布是下面这个公式:
在这里插入图片描述
这两个公式其实是同一个公式,只需要做如下变量替换就得到和第一个公式相同的形式了。
在这里插入图片描述

在生成瑞利噪声的时候,其实采用的是**np.random.rayleigh()** 方法生成,而这个方法就是根据第二个公式来的,所以只需要指定1个参数,得到的分布和第一个公式相比本质是相同的。

代码:

import cv2
import random
import numpy as np
img = cv2.imread('A.png')# 产生瑞利噪声
sigma = 70.0
noise = np.random.rayleigh(sigma, size=img.shape)
# 可以试试下面这个效果
# noise = np.random.rayleigh(img, size=img.shape)# 加上噪声
img = img + noise
np.clip(img,0,255)
img = img/255cv2.imshow('Rayleigh noise',img)
cv2.waitKey(0)
print(img.shape)

在这里插入图片描述

5、爱尔兰(伽马)噪声

概率密度函数(PDF)如下:(b是一个正整数)
在这里插入图片描述
指数分布和卡方分布其实可以看成是伽马分布的特殊形式。

b = 1时:指数分布;
b =n/2,a = 1/2时:卡方分布。
代码:

noise = np.random.gamma(shape=10.0,scale=10.0,size=img.shape)
#其他部分同上

在这里插入图片描述

6、均匀噪声

概率密度函数(PDF)如下:
在这里插入图片描述
代码:

noise = np.random.uniform(50,100,img.shape)
#其他部分同上

在这里插入图片描述

二、去噪方法

1、均值滤波

1.1 算术平均滤波

在这里插入图片描述

import cv2
import random
import numpy as np
img = cv2.imread('A.png')# 产生高斯随机数
noise = np.random.normal(0,50,size=img.size).reshape(img.shape[0],img.shape[1],img.shape[2])
# 加上噪声
img = img + noise
img = np.clip(img,0,255)
img = img/255   # 算术平均滤波
img1 = np.transpose(img,(2,0,1))  #转换成[channel,H,W]形式
m = 3   #定义滤波核大小
n = 3
rec_img = np.zeros((img1.shape[0],img1.shape[1]-m+1,img1.shape[2]-n+1))
for channel in range(rec_img.shape[0]):for i in range(rec_img[channel].shape[0]):for j in range(rec_img[channel].shape[1]):rec_img[channel][i,j] = img1[channel][i:i+m,j:j+n].sum()/(m*n)
rec_img = np.transpose(rec_img,(1,2,0))cv2.imshow('average',rec_img)
cv2.waitKey(0)

具体过程可以配合下图理解
在这里插入图片描述
去噪效果:

在这里插入图片描述

1.2 几何均值滤波

在这里插入图片描述

import cv2
import random
import numpy as np
img = cv2.imread('A.png')# 产生高斯随机数
noise = np.random.normal(0,50,size=img.size).reshape(img.shape[0],img.shape[1],img.shape[2])
# 加上噪声
img = img + noise
img = np.clip(img,0,255)
img = img/255   # 几何均值滤波
img1 = np.transpose(img,(2,0,1))  #转换成[channel,H,W]形式
m = 3   #定义滤波核大小
n = 3
rec_img = np.zeros((img1.shape[0],img1.shape[1]-m+1,img1.shape[2]-n+1))
for channel in range(rec_img.shape[0]):for i in range(rec_img[channel].shape[0]):for j in range(rec_img[channel].shape[1]):rec_img[channel][i,j] = np.power(np.prod(img1[channel][i:i+m,j:j+n]),1/(m*n))
rec_img = np.transpose(rec_img,(1,2,0))cv2.imshow('average',rec_img)
cv2.waitKey(0)

去噪效果:

在这里插入图片描述
几何均值滤波对0值是非常敏感,缺陷也很明显,那就是当窗口内像素只要有一个值为0,则其计算得到的值就是0。

1.3 谐波平均滤波

在这里插入图片描述

rec_img[channel][i,j] = 1/(np.power(img1[channel][i:i+m,j:j+n],-1).sum())*(m*n)
# 其余部分同上

在这里插入图片描述

该方法既能处理盐粒噪声,又能处理类似于于高斯噪声的其他噪声,但是不能处理胡椒噪声
### 1.4 ·
在这里插入图片描述
Q:滤波器的阶数。适用于降低或消除椒盐噪声。

注意:Q=0时。简化成算术平均滤波;Q=1,简化为谐波平均滤波。

代码:

import cv2
import random
import numpy as np
img = cv2.imread('A.png')#---------椒盐噪声----------
# 转化成向量
x = img.reshape(1,-1)  
# 设置信噪比
SNR = 0.85
# 得到要加噪的像素数目
noise_num = x.size * (1-SNR)
# 得到需要加噪的像素值的位置
list = random.sample(range(0,x.size),int(noise_num))for i in list:if random.random() >= 0.5:x[0][i] = 0else:x[0][i] = 255
img = x.reshape(img.shape)
img = img/255
#--------------------------# 反谐波平均滤波
img1 = np.transpose(img,(2,0,1))  #转换成[channel,H,W]形式
m = 3   #定义滤波核大小
n = 3
Q = 0.1
rec_img = np.zeros((img1.shape[0],img1.shape[1]-m+1,img1.shape[2]-n+1))
for channel in range(rec_img.shape[0]):for i in range(rec_img[channel].shape[0]):for j in range(rec_img[channel].shape[1]):rec_img[channel][i,j] = ((np.power(img1[channel][i:i+m,j:j+n],Q+1)).sum())/((np.power(img1[channel][i:i+m,j:j+n],Q)).sum())
rec_img = np.transpose(rec_img,(1,2,0))cv2.imshow('average',rec_img)
cv2.waitKey(0)

加噪图:

在这里插入图片描述
去噪效果:

在这里插入图片描述

注意:Q的值不要过大,否则就会变成下图(Q=2时):

在这里插入图片描述

2、统计排序滤波

2.1 中值滤波

我们非常熟悉的一种去噪方法,它是用像素邻域中的灰度中值来代替像素的值。
在这里插入图片描述
代码:

import cv2
import random
import numpy as np
img = cv2.imread('A.png')# 产生高斯随机数
noise = np.random.normal(0,50,size=img.size).reshape(img.shape[0],img.shape[1],img.shape[2])
# 加上噪声
img = img + noise
img = np.clip(img,0,255)
img = img/255   # 中值滤波
img1 = np.transpose(img,(2,0,1))  #转换成[channel,H,W]形式
m = 3   #定义滤波核大小
n = 3
rec_img = np.zeros((img1.shape[0],img1.shape[1]-m+1,img1.shape[2]-n+1))
for channel in range(rec_img.shape[0]):for i in range(rec_img[channel].shape[0]):for j in range(rec_img[channel].shape[1]):rec_img[channel][i,j] = np.median(img1[channel][i:i+m,j:j+n])
rec_img = np.transpose(rec_img,(1,2,0))cv2.imshow('median',rec_img)
cv2.waitKey(0)

去噪效果:

在这里插入图片描述
或者直接使用cv2.medianBlur()函数

import cv2
import random
import numpy as np
img = cv2.imread('A.png')# 产生高斯随机数
noise = np.random.normal(0,50,size=img.size).reshape(img.shape[0],img.shape[1],img.shape[2])
# 加上噪声
img = img + noise
img = np.clip(img,0,255)
img = np.uint8(img)# 中值滤波
rec_img = cv2.medianBlur(img,3)cv2.imshow('median',rec_img)
cv2.waitKey(0)

2.2 最大值和最小值滤波

在这里插入图片描述
在这里插入图片描述
主要使用到:np.amax() 和 np.amin()两个函数

2.3 中点滤波

在这里插入图片描述
代码:

rec_img[channel][i,j] = (np.amax(img1[channel][i:i+m,j:j+n]) + np.amin(img1[channel][i:i+m,j:j+n]))/2

高斯噪声处理的滤波效果:

在这里插入图片描述

2.4 修正阿尔法均值滤波

处理方法:在邻域 S x y S_{xy} Sxy 内删除 d / 2 d/2 d/2个最低灰度值和 d / 2 d/2 d/2个最高灰度值。 g R ( r , c ) g_{R}(r,c) gR(r,c)表示 S x y S_{xy} Sxy 中剩下的 m n − d mn-d mnd个像素。

d = 0 d=0 d=0: 变成算术平均滤波
d = m n − 1 d=mn-1 d=mn1:中值滤波

在这里插入图片描述
代码:

import cv2
import random
import numpy as np
img = cv2.imread('A.png')# 产生高斯随机数
noise = np.random.normal(0,50,size=img.size).reshape(img.shape[0],img.shape[1],img.shape[2])
# 加上噪声
img = img + noise
img = np.clip(img,0,255)
img = img/255   # 修正阿尔法均值滤波
img1 = np.transpose(img,(2,0,1))  #转换成[channel,H,W]形式
m = 3  #定义滤波核大小
n = 3
d = 4    #d取偶数
rec_img = np.zeros((img1.shape[0],img1.shape[1]-m+1,img1.shape[2]-n+1))
for channel in range(rec_img.shape[0]):for i in range(rec_img[channel].shape[0]):for j in range(rec_img[channel].shape[1]):img2 = np.sort(np.ravel(img1[channel][i:i+m,j:j+n]))  #np.ravel():多维数组变成一维数组rec_img[channel][i,j] = (img2[int(d/2):-int(d/2)].sum())*(1/(m*n-d))
rec_img = np.transpose(rec_img,(1,2,0))cv2.imshow('alpha average',rec_img)
cv2.waitKey(0)

去噪效果:

在这里插入图片描述

总结

介绍的主要是一些非常基础的滤波器,滤波功能只能针对某一类噪声有作用,其滤波效果总的来说并不是很好,对于真实环境中纷繁复杂的噪声类型,需要采用更合适、更好的滤波方法,但是这些方法或多或少都是基于这些基本方法去不断优化和改善的。后面有时间再更新一些更强的去噪方法。
有些地方可能存在问题和不足,欢迎大家一起交流!

参考文献:

[1] 阮秋琦,阮宇智译;(美)拉斐尔·C.冈萨雷斯,理查德·E.伍兹.国外电子书与通信教材系列 数字图像处理 第4版[M].北京:电子工业出版社,2020


http://chatgpt.dhexx.cn/article/cyjv6ryM.shtml

相关文章

干货 | 6款漏扫工具来了(附工具下载链接)

渗透测试收集信息完成后,就要根据所收集的信息,扫描目标站点可能存在的漏洞了,包括我们之前提到过的如:SQL注入漏洞、跨站脚本漏洞、文件上传漏洞、文件包含漏洞及命令执行漏洞等,通过这些已知的漏洞,来寻找…

webshell扫描工具

webshell扫描工具,这是一种内部有多个漏洞,可自动进行url采集,自采集多个引擎和友情链接url,轻松日出上百。 演示地址:https://note.youdao.com/s/Xi9S4I16 目录遍历攻击又称(目录爬升,目录回溯…

网站漏洞扫描工具AWVS_v13下载和安装

Acunetix Web Vulnerability Scanner(简称AWVS)是一款知名的网络漏洞扫描工具,它能够测试你的网站安全,检测网站的安全漏洞,如sql 注入,交叉站点脚本等等。 AWVS_v13软件的下载 1、AWVS漏洞扫描工具是一款…

2022-渗透测试-推荐一款好用的网站漏洞扫描工具-WPscan

目录 WPscan简介 WPscan工具利用 查看帮助信息 更新漏洞库 扫描WordPress漏洞 扫描wordpress用户 扫描所使用的主题和漏洞 指定字典暴力破解密码 WPscan简介 WPScan是Kali Linux默认自带的一款漏洞扫描工具,它可以全面检查wp网站的漏洞,从而能够及时应对…

动手实现简易网站目录扫描器——WebScanner

效果展示 项目目录: 引言 不知是否有小伙伴在学习Web安全相关的知识,如果有的话,那应该对XSS,SQL注入,文件上传,一句话脚本等等基本功应该是再熟悉不过了。最初学习的时候是它,实战最先测试的…

网站指纹扫描工具whatweb

目录 前言whatweb简介whatweb的使用 ~~~~~~~~ 因为想要面对一个新的开始,一个人必须有梦想、有希望、有对未来的憧憬。如果没有这些,就不叫新的开始,而叫逃亡。 ​​​​ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~…

web扫描工具了解

前言:此文章用于发现web的漏洞查询,信息收集 一.whois查询(可以查到域名,注册商,联系人,更新时间,创建时间,过期时间,域名服务器,DNS) kali中带有…

目录,系统,网站漏洞扫描工具

目录扫描工具 1.yujian yujian是一款可以进行端口扫描和目录扫描的软件,图形化界面,使用也比较简单,例如,今天使用的是它的目录扫描。 yujian针对目录扫描有它自己默认的字典,通过字典对其网站目录进行扫描 这里要…

网站安全在线扫描工具

现在网络上有许多一些关于网站安全检测的工具软件。有收费的,也有免费的。在这我就列举2个免费的在线网站扫描工具。 对于站长的来说: 之前对与网站的的安全检测,我都是直接用***软件***自己网站,再从问题里面进行修复。不过现在已…

网站目录扫描工具

目录 御剑 dirbuster Webdirscan 网站后台扫描工具都是利用目录字典进行爆破扫描,字典越多,扫描到的结果也越多。常用的网站后台扫描工具御剑、dirbuster和Webdirscan,不管哪个工具,要想扫描到更多的东西,都必须要有一个强大的目录字典! 御剑 御剑也是一款好用的网站…

网站扫描(Wker_网站探测工具)

Wker_网站探测工具 对于网站的扫描,我们需要完整详细的数据,才能进行准确的分析。 对于网站的分析,我们大致需要以下一些数据。 一. 域名信息查询 whois查询(联系人,联系邮箱,DNS)SEO查询权重查…

常用Web安全扫描工具合集

初入门时,喜欢将目标站点直接丢扫描器,慢慢等扫描结果,极度依赖Web扫描器;而有一些漏洞高手,善于运用运用各种工具但并不依赖工具,经常可以找到扫描工具发现不了的漏洞。 一款好用的Web扫描器对于白帽子来说…

【网络安全干货分享】Web安全常用的扫描工具有哪些?

Web安全是网络安全的一部分,常用的扫描工具共分为两大类:系统扫描工具和应用扫描工具。那么Web安全常用的扫描工具有哪些?以下便是详细的内容介绍。 第一种:系统扫描工具  系统扫描工具主要是针对网络中系统软件的脆弱性进行信息安全评估&…

OpenCV_03 Numpy库和Mat

前言 主要学习Numpy库的相关操作和Mat的基础知识。 目录 前言一、Numpy基本操作1.创建矩阵创建数组array()创建全0/1数组zeros()/ones()创建全值数组full()单位矩阵identity()/eye() 2.检索与赋值3.获取子矩阵Region of Image(ROI) 二、Mat结构体1.Mat的实现2.Mat拷贝Mat浅拷贝…

【MATLAB Image Processing Toolbox 入门教程六】“导入、导出和转换”之“图像类型转换Ⅰ——在不同图像类型之间转换”

【MATLAB Image Processing Toolbox 入门教程六】 1 gray2ind函数2 ind2gray函数3 mat2gray函数4 rgb2gray函数5 rgb2ind函数6 label2rgb函数7 imsplit函数8 grayslice函数 MATLAB Image Processing Toolbox支持的图像类型有:二值图像、索引图像、灰度图像、彩色图像…

黑白图转RGB(Matlab)

SamplePath1 "C:\Users\LY\Desktop\green\"; %存储图像的路径 fileExt *.bmp; %待读取图像的后缀名 %获取所有路径 files dir(fullfile(SamplePath1,fileExt)); len size(files,1); for ii1:lenfileName strcat(SamplePath1,files(ii).name);Iimread(fileNa…

【mmdeploy】mmseg转ONNX/TensorRT,附推理代码

目录 1.关于mmdeploy 2.环境安装 2.1预编译安装(Linux-x86_64, CUDA 11.x, TensorRT 8.2.3.0): 2.2预编译安装(Linux-x86_64, CUDA 11.x, ONNX): 3.mmseg工程torch转onnx 4.使用onnx模型文件进行推理…

讨论Matlab中double,im2double,mat2gray函数区别

图像类和类型间的转换 im2uint8 将输入中所有小于0的设置为0,而将输入中所有大于1的设置为255 其他的所有乘以255 im2uint16 将输入中所有小于0的设置为0,而将输入中所有大于1的设置为65535 mat2gray 把一个double类的任意数组转换成值范围在[0,1]的归一化double类数组 im2…

Matlab中double,im2double,mat2gray函数使用方法介绍

图像类和类型间的转换 im2uint8 将输入中所有小于0的设置为0,而将输入中所有大于1的设置为255 其他的所有乘以255 im2uint16 将输入中所有小于0的设置为0,而将输入中所有大于1的设置为65535 mat2gray 把一个double类的任意数组转换成值范围在[0,1]的归一化double类数组 im2…

numpy转PIL.Image: 处理Mask图像为单通道的彩色/灰度图colormap.png

文章目录 从分割数据集说起8位彩色图8位灰度图1位二值图 什么是图像位深PNG图像格式简介如何处理Mask图像注意!!!PIL一定要手动close 防止内存泄漏PIL库相关函数 从分割数据集说起 8位彩色图 下图是 NYU数据集 里的一张Mask图像, 显示彩图,…