matlab给数字图像加高斯白噪声的几种方法

近期在研究数字图像去噪方法,碰到了给图像加高斯白噪声的问题,颇为头疼,于是小小研究了一下,做个笔记记一下。

1. randn()

首先来说一下randn()这个函数,它是默认产生一个期望为0,标准差为1的正态分布,具体生成的是向量还是矩阵都是自行控制,比如下面这样可以产生一个期望为1,标准差为2的正态分布矩阵:

r=1+2.*randn(2,2)
r =
   -1.0327    0.2521
    1.0459   -0.7869

于是下面我们可以用randn()给图像添加均值为0,标准差为10,方差为100的高斯白噪声了:

origImg = imread('Lena.bmp');
figure, imshow(origImg,[])
% 关于此处用double的解释:原图是uint8格式的数据,而randn函数生成的是float类
% 型的数据,因此要进行数据类型转换
distImg = double(origImg) + 10*randn(size(origImg));
figure, imshow(distImg,[])
noise = distImg - double(origImg);
figure,imshow(noise,[])
var = var(double(noise(:)))  % 方差
std = std2(noise)            % 标准差
mean = mean2(noise)          % 二维数组的均值
var =
  101.0287
std =
   10.0513
mean =
   -0.0105

可以看到,所求出来的基本符合预期了。

2. wgn()

官方文档是这样写的:
y = wgn(m,n,power) generates an m-by-n matrix of white Gaussian noise. power specifies the power of y in decibels relative to a watt. The default load impedance is 1 ohm.
然后附加了一个例子:

% Generate a 1000-element column vector 
% containing real white Gaussian noise of power 0 dBW.
y1 = wgn(1000,1,0);
% Confirm that the power is approximately 0 dBW, that is, 1 W.
var(y1)
ans = 0.9979

从上面的例子我们可以明白过来,其实产生的噪声的方差就是第三个参数的值,只不过在代码中要将其按照分贝(dB)来设置。我们常见的分贝是度量声音强度的单位。其转换公式为P(dB)=10lgP(W)。于是有了:
y = wgn(m,n,p) 产生一个m行n列的高斯白噪声的矩阵,p以dBW为单位指定输出噪声的强度(方差)。
同理,将上述添加噪声那句代码改为:

distImg=double(origImg) + wgn(size(origImg,1),size(origImg,2),20);

即可得到:

var =
   99.7863

std =
    9.9893

mean =
    0.0065

也是符合要求的。

3. imnoise()

官方文档说明为:
J = imnoise(I,’gaussian’,M,V) adds Gaussian white noise of mean m and variance v to the image I. The default is zero mean noise with 0.01 variance.
也就是说M表示均值,V表示方差。
那么将添加噪声的代码改为:

distImg = imnoise(origImg, 'gaussian', 0, 10^2/255^2);

可得到:

var =
   99.3884

std =
    9.9694

mean =
   -0.0197

Note : The mean and variance parameters for ‘gaussian’, ‘localvar’, and ‘speckle’ noise types are always specified as if the image were of class double in the range [0, 1]. If the input image is of class uint8 or uint16, the imnoise function converts the image to double, adds noise according to the specified type and parameters, and then converts the noisy image back to the same class as the input.
此处解释一下,原始图像origImg是uint8的灰度图像,灰度值范围为[0,255],故imnoise函数在处理时会将图像先转换为[0,1],然后按照所给的均值和方差添加噪声,最后再将图像转换到[0,255]的范围内,因此参数设置尤其要注意,如果所给的图像是uint8时,所给的均值和方差必须是在[0,1]的范围内,也就是说要归一化,不然直接给100的方差时,imnoise函数会将图像归一化,然后按照方差100来添加噪声,这样原先的图像就给淹没了,反而变成了噪声为主导。
笔者试了一下下面的情况:

1. 用imnoise()时不将噪声范围归一化

也就是

distImg = imnoise(origImg, 'gaussian', 0, 10^2);

结果如下:

var =
   7.5061e+03

std =
   86.6380

mean =
   77.4065

这里写图片描述
很显然,图像和噪声已经倒置了,噪声成为了主导。

2. 将读取的图像用double()函数转换为浮点数
origImg = double(imread('Lena.bmp'));

同样添加噪声

distImg = imnoise(origImg, 'gaussian', 0, 10^2/255^2);

结果

var =
   2.7662e+03

std =
   52.5943

mean =
  -94.8971

加完噪声以后,图像灰度范围变成了[0,1],且图像完全变成了噪声,这说明噪声和图像已经完全倒置了。
这里写图片描述

3. 将读取的图像用im2double()转换为[0,1]的浮点数
origImg = im2double(imread('Lena.bmp'));

结果得到:

var =
    0.0015

std =
    0.0389

mean =
   2.0223e-04

这里写图片描述
显然方差就是直接按照10^2/255^2计算得到的,这也难怪,如果图像一开始灰度范围是[0,1], 那么我们所添加的噪声方差也只可能是这个范围了。
先写到这,后续再继续补充,欢迎纠错。

评论 36
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值