找回密码
 会员注册
查看: 32|回复: 0

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

[复制链接]

5

主题

0

回帖

16

积分

新手上路

积分
16
发表于 2024-9-11 11:05:18 | 显示全部楼层 |阅读模式
文章目录前言本文主要参考冈萨雷斯的数字图像处理(第4版),介绍图片中一些常见的噪声形式和常用的去噪方法,并且给出相应滤波方法的实现代码。一、噪声分类1、高斯噪声2、泊松噪声3、椒盐噪声4、瑞利噪声5、爱尔兰(伽马)噪声6、均匀噪声二、去噪方法1、均值滤波1.1算术平均滤波1.2几何均值滤波1.3谐波平均滤波2、统计排序滤波2.1中值滤波2.2最大值和最小值滤波2.3中点滤波2.4修正阿尔法均值滤波总结参考文献:前言本文主要参考冈萨雷斯的数字图像处理(第4版),介绍图片中一些常见的噪声形式和常用的去噪方法,并且给出相应滤波方法的实现代码。如果要使用本文代码,建议在JupyterNotebook环境下运行。1一、噪声分类1、高斯噪声指服从高斯分布(正态分布)的一类噪声,其产生的主要原因是由于相机在拍摄时视场较暗且亮度不均匀造成的,同时相机长时间工作使得温度过高也会引起高斯噪声,另外电路元器件白身噪声和互相影响也是造成高斯噪声的重要原因之一。概率密度函数(PDF)如下:初始图片:注意加噪声时,不能直接将noise+img,不然最终出来的是一片空白和零星几个噪点,原因在于cv2.imshow输入要求是0-1float或者0-255int。(1)错误显示:(2)正确显示:importcv2importrandomimportnumpyasnpimg=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+noiseimg=np.clip(img,0,255)img=img/255cv2.imshow('Gaussnoise',img)cv2.waitKey(0)1234567891011121314(3)高斯滤波高斯滤波是一种线性平滑滤波,一般用于消除高斯噪声。对于每一个像素点的值,是由其本身和邻域内的其他像素值经过加权平均后得到。二维高斯函数:具体过程:代码:使用cv2.GaussianBlur()函数注意高斯模糊半径不能为偶数滤波结果:2、泊松噪声简言之就是符合泊松分布的噪声模型,又称散粒噪声。使用**np.random.poisson()**函数importcv2importrandomimportnumpyasnpimg=cv2.imread('A.png')#产生泊松噪声noise=np.random.poisson(lam=20,size=img.shape).astype('uint8')#加上噪声img=img+noisenp.clip(img,0,255)img=img/255cv2.imshow('Poissonnoise',img)cv2.waitKey(0)123456789101112131415λ值越大,噪声程度越深。3、椒盐噪声椒盐噪声又称为脉冲噪声,是在图像上随机出现黑色白色的像素,顾名思义就是椒盐噪声=椒噪声(值为0,黑色)+盐噪声(值为255,白色)直接上代码:importcv2importrandomimportnumpyasnpimg=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))foriinlist:ifrandom.random()>=0.5:x[0][i]=0else:x[0][i]=255img1=x.reshape(img.shape)cv2.imshow('salt&peppernoise',img1)cv2.waitKey(0)123456789101112131415161718192021222324SNR越小,噪声越大。4、瑞利噪声一般是由由信道不理想引起的,它与信号的关系是相乘,信号在它在,信号不在他也就不在。瑞利密度对倾斜形状直方图的建模非常有用。概率密度函数(PDF)如下:很多地方给出的瑞利分布是下面这个公式:这两个公式其实是同一个公式,只需要做如下变量替换就得到和第一个公式相同的形式了。在生成瑞利噪声的时候,其实采用的是**np.random.rayleigh()**方法生成,而这个方法就是根据第二个公式来的,所以只需要指定1个参数,得到的分布和第一个公式相比本质是相同的。代码:importcv2importrandomimportnumpyasnpimg=cv2.imread('A.png')#产生瑞利噪声sigma=70.0noise=np.random.rayleigh(sigma,size=img.shape)#可以试试下面这个效果#noise=np.random.rayleigh(img,size=img.shape)#加上噪声img=img+noisenp.clip(img,0,255)img=img/255cv2.imshow('Rayleighnoise',img)cv2.waitKey(0)print(img.shape)123456789101112131415161718195、爱尔兰(伽马)噪声概率密度函数(PDF)如下:(b是一个正整数)指数分布和卡方分布其实可以看成是伽马分布的特殊形式。b=1时:指数分布;b=n/2,a=1/2时:卡方分布。代码:noise=np.random.gamma(shape=10.0,scale=10.0,size=img.shape)#其他部分同上126、均匀噪声概率密度函数(PDF)如下:代码:noise=np.random.uniform(50,100,img.shape)#其他部分同上12二、去噪方法1、均值滤波1.1算术平均滤波importcv2importrandomimportnumpyasnpimg=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+noiseimg=np.clip(img,0,255)img=img/255#算术平均滤波img1=np.transpose(img,(2,0,1))#转换成[channel,H,W]形式m=3#定义滤波核大小n=3rec_img=np.zeros((img1.shape[0],img1.shape[1]-m+1,img1.shape[2]-n+1))forchannelinrange(rec_img.shape[0]):foriinrange(rec_img[channel].shape[0]):forjinrange(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)12345678910111213141516171819202122232425具体过程可以配合下图理解去噪效果:1.2几何均值滤波importcv2importrandomimportnumpyasnpimg=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+noiseimg=np.clip(img,0,255)img=img/255#几何均值滤波img1=np.transpose(img,(2,0,1))#转换成[channel,H,W]形式m=3#定义滤波核大小n=3rec_img=np.zeros((img1.shape[0],img1.shape[1]-m+1,img1.shape[2]-n+1))forchannelinrange(rec_img.shape[0]):foriinrange(rec_img[channel].shape[0]):forjinrange(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)12345678910111213141516171819202122232425去噪效果:几何均值滤波对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)#其余部分同上12该方法既能处理盐粒噪声,又能处理类似于于高斯噪声的其他噪声,但是不能处理胡椒噪声。###1.4·Q:滤波器的阶数。适用于降低或消除椒盐噪声。注意:Q=0时。简化成算术平均滤波;Q=1,简化为谐波平均滤波。代码:importcv2importrandomimportnumpyasnpimg=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))foriinlist:ifrandom.random()>=0.5:x[0][i]=0else:x[0][i]=255img=x.reshape(img.shape)img=img/255#--------------------------#反谐波平均滤波img1=np.transpose(img,(2,0,1))#转换成[channel,H,W]形式m=3#定义滤波核大小n=3Q=0.1rec_img=np.zeros((img1.shape[0],img1.shape[1]-m+1,img1.shape[2]-n+1))forchannelinrange(rec_img.shape[0]):foriinrange(rec_img[channel].shape[0]):forjinrange(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)1234567891011121314151617181920212223242526272829303132333435363738加噪图:去噪效果:注意:Q的值不要过大,否则就会变成下图(Q=2时):2、统计排序滤波2.1中值滤波我们非常熟悉的一种去噪方法,它是用像素邻域中的灰度中值来代替像素的值。代码:importcv2importrandomimportnumpyasnpimg=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+noiseimg=np.clip(img,0,255)img=img/255#中值滤波img1=np.transpose(img,(2,0,1))#转换成[channel,H,W]形式m=3#定义滤波核大小n=3rec_img=np.zeros((img1.shape[0],img1.shape[1]-m+1,img1.shape[2]-n+1))forchannelinrange(rec_img.shape[0]):foriinrange(rec_img[channel].shape[0]):forjinrange(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)12345678910111213141516171819202122232425去噪效果:或者直接使用cv2.medianBlur()函数importcv2importrandomimportnumpyasnpimg=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+noiseimg=np.clip(img,0,255)img=np.uint8(img)#中值滤波rec_img=cv2.medianBlur(img,3)cv2.imshow('median',rec_img)cv2.waitKey(0)12345678910111213141516172.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]))/21对高斯噪声处理的滤波效果:2.4修正阿尔法均值滤波处理方法:在邻域SxyS_{xy}Sxy​内删除d/2d/2d/2个最低灰度值和d/2d/2d/2个最高灰度值。gR(r,c)g_{R}(r,c)gR​(r,c)表示SxyS_{xy}Sxy​中剩下的mn−dmn-dmn−d个像素。d=0d=0d=0:变成算术平均滤波d=mn−1d=mn-1d=mn−1:中值滤波代码:importcv2importrandomimportnumpyasnpimg=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+noiseimg=np.clip(img,0,255)img=img/255#修正阿尔法均值滤波img1=np.transpose(img,(2,0,1))#转换成[channel,H,W]形式m=3#定义滤波核大小n=3d=4#d取偶数rec_img=np.zeros((img1.shape[0],img1.shape[1]-m+1,img1.shape[2]-n+1))forchannelinrange(rec_img.shape[0]):foriinrange(rec_img[channel].shape[0]):forjinrange(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('alphaaverage',rec_img)cv2.waitKey(0)123456789101112131415161718192021222324252627去噪效果:总结介绍的主要是一些非常基础的滤波器,滤波功能只能针对某一类噪声有作用,其滤波效果总的来说并不是很好,对于真实环境中纷繁复杂的噪声类型,需要采用更合适、更好的滤波方法,但是这些方法或多或少都是基于这些基本方法去不断优化和改善的。后面有时间再更新一些更强的去噪方法。有些地方可能存在问题和不足,欢迎大家一起交流!参考文献:[1]阮秋琦,阮宇智译;(美)拉斐尔·C.冈萨雷斯,理查德·E.伍兹.国外电子书与通信教材系列数字图像处理第4版[M].北京:电子工业出版社,2020
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 会员注册

本版积分规则

QQ|手机版|心飞设计-版权所有:微度网络信息技术服务中心 ( 鲁ICP备17032091号-12 )|网站地图

GMT+8, 2024-12-31 06:35 , Processed in 0.506289 second(s), 25 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表