参考文章:
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
)
#保存到新建的文件夹