参考文章:
https://blog.csdn.net/zhoufan900428/article/details/37695357
常见噪声:高斯噪声,椒盐噪声,泊松噪声,乘性噪声
高斯噪声
概率密度函数服从高斯分布的噪声。
产生原因:
1)图像传感器在拍摄时市场不够明亮、亮度不够均匀;
2)电路各元器件自身噪声和相互影响;
3)图像传感器长期工作,温度过高
泊松噪声
泊松噪声,就是符合泊松分布的噪声模型,泊松分布适合于描述单位时间内随机事件发生的次数的概率分布。如某一服务设施在一定时间内受到的服务请求的次数,电话交换机接到呼叫的次数、汽车站台的候客人数、机器出现的故障数、自然灾害发生的次数、DNA序列的变异数、放射性原子核的衰变数等等
乘性噪声
乘性噪声一般由信道不理想引起,它们与信号的关系是相乘,信号在它在,信号不在他也就不在。
椒盐噪声
椒盐噪声,椒盐噪声又称脉冲噪声,它随机改变一些像素值,是由图像传感器,传输信道,解码处理等产生的黑白相间的亮暗点噪声。
椒盐噪声往往由图像切割引起。
瑞利噪声
瑞利噪声相比高斯噪声而言,其形状向右歪斜,这对于拟合某些歪斜直方图噪声很有用。
瑞利噪声的实现可以借由平均噪声来实现。其matlab实现如下:
a = -0.2;
b = 0.03;
n_rayleigh = a + (-b .* log(1 - rand(M,N))).^0.5;
伽马噪声
伽马噪声的分布,服从了伽马曲线的分布。伽马噪声的实现,需要使用b个服从指数分布的噪声叠加而来。指数分布的噪声,可以使用均匀分布来实现。(b=1时为指数噪声,b>1时通过若干个指数噪声叠加,得到伽马噪声)
a = 25;
b = 3;
n_Erlang = zeros(M,N);
for j=1:b
n_Erlang = n_Erlang + (-1/a)*log(1 - rand(M,N));
end
均匀噪声
使用python的skimage.util.random_noise(image, mode=‘gaussian’, seed=None, clip=True, **kwargs)来添加噪声
1.先安装必要的依赖库:numpy , scipy , matpoltlib
2.安装scikit-image
pip install scikit-image
3.导入util库
import skimage
from skimage import util
4.函数介绍
def random_noise(image, mode='gaussian', seed=None, clip=True, **kwargs):
功能:为浮点型图片添加各种随机噪声
参数:
image:输入图片(将会被转换成浮点型),ndarray型
mode: 可选择,str型,表示要添加的噪声类型
gaussian:高斯噪声
localvar:高斯分布的加性噪声,在“图像”的每个点处具有指定的局部方差。
poisson:泊松再生
salt:盐噪声,随机将像素值变成1
pepper:椒噪声,随机将像素值变成0或-1,取决于矩阵的值是否带符号
s&p:椒盐噪声
speckle:均匀噪声(均值mean方差variance),out=image+n*image
seed: 可选的,int型,如果选择的话,在生成噪声前会先设置随机种子以避免伪随机
clip: 可选的,bool型,如果是True,在添加均值,泊松以及高斯噪声后,会将图片的数据裁剪到合适范围内。如果谁False,则输出矩阵的值可能会超出[-1,1]
mean: 可选的,float型,高斯噪声和均值噪声中的mean参数,默认值=0
var: 可选的,float型,高斯噪声和均值噪声中的方差,默认值=0.01(注:不是标准差)
local_vars:可选的,ndarry型,用于定义每个像素点的局部方差,在localvar中使用
amount: 可选的,float型,是椒盐噪声所占比例,默认值=0.05
salt_vs_pepper:可选的,float型,椒盐噪声中椒盐比例,值越大表示盐噪声越多,默认值=0.5,即椒盐等量
--------
返回值:ndarry型,且值在[0,1]或者[-1,1]之间,取决于是否是有符号数
-------
注意:略(见源码)
python中的**kwargs是什么?
https://www.jianshu.com/p/037b6ea516f1这个讲的也很标准(关于位置参数,默认参数,非键值可变参数,键值可变参数)
*args
和**kwargs
称为“可变参数”,主要用与与函数定义,它们表示你可以将多个参数传递给这个函数。
这个“多个”的含义是,预先不知道会传递多少个(由于有些函数的mode参数不用,后边跟的参数数量也随之不同),上边的添加噪声函数就是个很好例子,有的噪声不需要均值方差,有的需要。
*args
是用来发一个非键值对的可变数量的参数列表给一个函数,例如
def test_var_args(f_arg, *argv):
print("first normal arg:", f_arg)
for arg in argv:
print("another arg through *argv:", arg)
test_var_args('yasoob', 'python', 'eggs', 'test')
输出如下
first normal arg: yasoob
another arg through *argv: python
another arg through *argv: eggs
another arg through *argv: test
这说明后边的多个参数会被放进一个名为argv的列表中,而函数内部通过这个列表使用这些参数
**kwargs
允许将一个不定长度的键值对,作为参数传递给函数,如果需要在一个函数中处理带名字的参数,就需要用到kwargs(意思就是kwarg代表很多有名字的参数),例如
def test_args_kwargs(arg1, arg2, arg3):
print("arg1:", arg1)
print("arg2:", arg2)
print("arg3:", arg3)
分别使用*args和**kwargs来给函数传递参数
>>> args = ("two", 3, 5)
>>> test_args_kwargs(*args)
arg1: two
arg2: 3
arg3: 5
>>> kwargs = {"arg3": 3, "arg2": "two", "arg1": 5}
>>> test_args_kwargs(**kwargs)
arg1: 5
arg2: two
arg3: 3
注意到,kwargs传递必须是键值对传递,而args只需要顺序传递进去即可
一个批量添加噪声的python代码
import cv2
import os
import numpy as np
from PIL import Image
from skimage import util
#批处理
path='F:/0.MaskRCNN(3 times)/hook_data/Mask/test3' #图片文件夹路径
image_names=os.listdir(path) #列举path下所有文件和文件夹名称(返回一个list)
save_dir=os.path.join(path,'speckle(0,0.1)_test03') #我的文件夹名称
os.mkdir(save_dir)
for image_name in image_names:
if(image_name.endswith('.jpg')):
img=Image.open(os.path.join(path,image_name))
img=np.array(img)
noise_gs_img=util.random_noise(img,mode='speckle')
noise_gs_img=noise_gs_img*255 #由于输出是[0,1]的浮点型,先转成灰度图(我的输入就是灰度图)
noise_gs_img=noise_gs_img.astype(np.int) #再变成整型数组
cv2.imwrite(os.path.join(save_dir,image_name),noise_gs_img) #保存到新建的文件夹