复原的目的是在预定意义上改善给定的图像。尽管图像增强和图像复原之间存在重叠的部分,但前者主要是主观的处理,而图像复原大部分是客观的处理。复原利用降质现象的先验知识试图重建或恢复一幅退化的图像。因此,复原技术倾向于对退化建模,并用相反的处理来恢复原始图像。
用退化函数对退化过程建模,它和附加噪声选项一起,作用于输入图像f(x,y),产生一幅退化的图像g(x,y):
图像退化/复原处理的模型:
复原的目标就是得到原始图像的估计。我们要使这个估计尽可能接近原始的输入图像。通常,我们对H和η(x,y)知道得越多,图像的估计就越接近f(x,y)。
如果H是线性的,空间不变的过程,那么退化图像在空间域将由下面的式子给出:
h(x,y)是退化函数的空间表示,“星号”表示卷积。空间域的卷积和频域的乘法组成了傅立叶变换对,所以我们可以用等价的频域表示来写出前面的模型:
由于退化是线性的,因此空间不变的退化函数可以由卷积来建模,类似地,复原处理有时候也称为反卷积。
能够模拟噪声的行为和效果的能力是图像复原的核心。
图像处理工具箱釆用 imnoise 函数,使噪声污染一幅图像。这个函数有如下基本语法:
g = imnoise(f, type, parameters)
注意:函数 imnoise 在为图像添加噪声之前,将图像转换为范围在[0,1]的double类。
imnoise 函数有如下形式:
1.将均值为m,方差为var的高斯噪声加到图像 f 上。默认为均值是 0、方差是 0.01 的噪声。
g = imnoise(f, ’gaussian', m,var)
代码编写:
w = imread('D:\数字图像处理\第四章学习\tree.jpg');
%w = imread('D:\数字图像处理\第四章学习\building.jpg');
f = im2double(w); %把图像变为灰度图像
g = imnoise(f, 'gaussian', 0.1,0.01) ; %方差为0.01
%g = imnoise(f, 'gaussian', 0.1,0.05) ; %方差为0.05
%g = imnoise(f, 'gaussian', 0.1,0.2) ; %方差为0.2
subplot(2, 2, 1), imshow(w), title('原图像');
subplot(2, 2, 2), imshow(g,[]), title('均值为0.1方差为0.01的高斯噪声加到图像');
subplot(2, 2, 3), imshow(g,[]), title('均值为0.1方差为0.05的高斯噪声加到图像');
subplot(2, 2, 4), imshow(g,[]), title('均值为0.1方差为0.2的高斯噪声加到图像');
代码运行效果如下:
实验结论:明显看出对于同一张图片,高斯白噪声方差越大,图像越模糊。而对于不同类型图像,白天室外拍出的图片以及室内强光下拍出的图片在同样方差的高斯白噪声下,图像更清晰,而夜晚光线较差情况下拍出的图片(第一幅夜晚的树)在同样方差的高斯白噪声下,图像更模糊。所以在加入相同方差的高斯噪声的情况下,图像最终的显示效果也与图像自身的清晰度有关。
2.将均值为 0、局部方差为 V的高斯噪声添加到图像 f 上。其中,V 是与 f 大小相同的数组,其中包含了每个点的理想方差值。
g=imnoise (f,localvar,V)
编写代码:
w = imread('D:\数字图像处理\第四章学习\sea.jpg');
%w = imread('D:\数字图像处理\第四章学习\grapes.jpg');
%w = imread('D:\数字图像处理\第四章学习\building.jpg');
f = im2double(rgb2gray(w)); %把图像变为灰度图像
[n,m]=size(f);
v = rand(n,m);
g = imnoise(f,'localvar',v); %产生高斯噪声方法
subplot(1, 2, 1), imshow(w), title('原图像');
subplot(1, 2, 2), imshow(g), title('均值为0、局部方差为V的高斯噪声加到图像');
3.用椒盐噪声污染图像 f。其中,d是噪声密度(也就是包含噪声值的图像区域的百分比)。因此,大约d*nurael (f) 个像素受到影响。 默认的噪声密度是 0.05。
g=imnoise (f, 'salt & pepper ',d)
代码编写:
w = imread('D:\数字图像处理\第四章学习\tree.jpg');
f = im2double(rgb2gray(w)); %把图像变为灰度图像
g = imnoise (f, 'salt & pepper',0.12);
subplot(1, 3, 1), imshow(w), title('原图像');
subplot(1, 3, 2), imshow(f), title('原图像的灰度图像');
subplot(1, 3, 3), imshow(g), title('椒盐噪声加到图像');
代码运行效果如下:
4. 用方程式 g=f+n.*f 将乘性噪声添加到图像 f 上。其中,n是均值为 0、方差为 v 的均匀分布的随机噪声。var 的默认值是0.04。
g = imnoise(f,'speckle',v)
编写代码:
w = imread('D:\数字图像处理\第四章学习\face.jpg');
%w = imread('D:\数字图像处理\第四章学习\xiaomai.jpg');
%w = imread('D:\数字图像处理\第四章学习\blue.jpg');
%w = imread('D:\数字图像处理\第四章学习\building.jpg');
f = im2double(rgb2gray(w)); %把图像变为灰度图像
g = imnoise(f,'speckle',0.2) ;
subplot(1, 2, 1), imshow(w), title('原图像');
subplot(1, 2, 2), imshow(g), title('均值为0方差为V的均匀分布随机噪声加到图像');
实验结论:对于同一张图片,噪声方差越大,图像越模糊,而对于不同类型图像,在同样方差的均匀随机噪声下,人像和卡通图像要更清晰,这两种图像有共同点就是图像内容颜色对比度大,结构简单,轮廓清晰,风景和建筑物要更容易被噪声污染,这两种图像主要存在问题就是,图像内容颜色对比度不大(大海和蓝天都是蓝色,建筑物都是黄色,树都是绿色),建筑物结构太过复杂,大海太过单一,都没有很明显的轮廓界限,导致虽然加在图像上的噪声是一样的,但是不同图像呈现出来的噪声污染效果不同。
5.从数据中生成泊松噪声来代替人造的噪声并添加到数据中。
g=imnoise (f, 'poisson' )
代码编写:
w = imread('D:\数字图像处理\第四章学习\face.jpg');
%w = imread('D:\数字图像处理\第四章学习\grapes.jpg');
f = im2double(rgb2gray(w)); %把图像变为灰度图像
g = imnoise(f,'Poisson');
subplot(1, 3, 1), imshow(w), title('原图像');
subplot(1, 3, 2), imshow(f), title('原图像的灰度图像');
subplot(1, 3, 3), imshow(g), title('泊松噪声加到图像');
代码运行效果如下:
实验分析:图像并未看到明显模糊效果,与灰度图像一致。此处出现问题,不可能无差异,了解到泊松噪声:由于由于光具有量子特效,到达光电检测器表面的量子数目存在统计涨落,因此,图像监测具有颗粒性,这种颗粒性造成了图像对比度的变小以及对图像细节信息的遮盖,因为光量子而造成的测量不确定性成为图像的泊松噪声。泊松噪声一般在亮度很小或者高倍电子放大线路中出现。但是添加泊松噪声,应该是所有的图像都能添加,代码并未报错,看逻辑问题。
重新编写代码:
w = imread('D:\数字图像处理\第四章学习\face.jpg');
%w = imread('D:\数字图像处理\第四章学习\grapes.jpg');
f = rgb2gray(w); %把图像变为灰度图像
g = imnoise(f,'Poisson');
subplot(1, 3, 1), imshow(w), title('原图像');
subplot(1, 3, 2), imshow(f), title('原图像的灰度图像');
subplot(1, 3, 3), imshow(g), title('泊松噪声加到图像');
实验分析:把图像转换为double类型图像添加泊松噪声,图像并无变化,与原图一致,而给原图(unit8类型)添加泊松噪声,图像显示模糊状态,泊松噪声添加成功。但是百度百科显示g=imnoise(f,‘poisson’)从数据中生成泊松噪声,而不是将人工的噪声添加到数据中,为了遵守泊松统计,unit8和unit16类图像的亮度必须和光子的数量相符合。当每个像素的光子数量大于65535时,就要使用双精度图像,亮度值在0到1之间变化,并且对应于光子的数量除以10e12。说明这种差异可能不是因为图像是否为double类型或者unit8类型造成的,与图像亮度是否和光子的数量相符有关(光子数=总的光能量除以一分光子能量,N=E/hf ,f为光的频率光子的数量决定光的亮度,光子数越多,光的亮度越强)。此时设想,unit8类图像的亮度是否已经和光子的数量相符合?并且每个像素的光子数量小于65535,不需要进行double类型转换?
此时如果再进行下去遇到两个问题:
然后问了光学工程专业的同学,实践应该是很困难,用CCD,CMOS估计做不到,可以试试光电倍增管探测单光子,暂时放弃这个方案,换个角度,分析泊松噪声的定义,泊松噪声的产生是根据每个像素的亮度随机产生,举个例子,如果是0就不添加,如果是1就添加一个一定强度的噪声,如果是100,就添加一个更强的噪声,虽然随机参数是随机产生,但是随机参数也和像素点的亮度有关,对于1,1.2,1.5, 1.9都是一样的,都是1,所以给一个double类型的二维数组,里面全是小于1的数,泊松噪声函数就把这些数全当成0看待,就不加噪声。
这时候还是有问题,为什么当每个像素的光子数量大于65535时,还是要使用双精度图像,亮度值在0到1之间变化,这样不会导致跟上面一样全当0看待,不加噪声,这时候的解决方案就是会乘以一个足够大的数,最好让所有的亮度值都变成整数,这也可以理解前面为什么要用光子数做类比了,光子数是整数,而且和亮度值成正比。图像被送去加噪声之前,亮度值都会取整一下。
上述讨论,可能不能算正确的实验结论,所以暂时当成实验分析,欢迎有其他看法的博主,在评论区留言一起探讨。
在函数imnoise中,能够产生可用类型和参数的噪声是很有必要的。空间噪声值是随机数,虽然可以用 imnoise 产生这两种类型的噪声,但是从目前的上下文来看,更简单的是使用 MATLAB函数 rand 来产生均匀随机数,并使用函数 randn 产生正态(高斯)随机数。
假设拥有在区间(0, 1)内均匀分布的随机数产生器 W,并假设要用它来产生具有累积分布函数(CDF )的随机数z,形式如下:
其中,b>0。为得到z,解下面的方程:
或
此方程式有时候被称为随机数产生器方程式,因为它确定了如何产生希望的随机数。
由于平方根是非负的,因此我们可以确定:不会产生小于 a 值的 z。正如瑞利 CDF的定义中要求的那样。因此,来自产生器的均匀随机数 w可以被用在前面的方程式中,从而产生参数为 a 和 b的瑞利分布的随机变量 z。
在 MATLAB中,产生随机数组 R:
R = a + sqrt (b*log(1-rand(M,N)));
在imnoise中,可用的随机数产生器和如下表中所示的随机数产生器,在图像处理应用中对随机噪声的特性建模方面起到重要作用。
而自定义 M-函数 imnoise2 可产生具有上表中CDF的随机数。
imnoise 能够产生可用类型和参数的噪声,与 imnoise 不同,inmoise2 产生 MxN 大小的噪声数组 R,它不以任何方式缩放。 另一个主要的不同是:imnoise输出有噪声的图像, 而 inmoise2 产生噪声模式本身。用户可以直接指定希望的噪声参数值。
用 函数 imnoise2 产生数据的直方图
代码编写:
r = imnoise2('gaussian',1000,1,0,1);
p = imnoise2('uniform',10000,1,0,1);
q = imnoise2('lognormal',10000,1,1,0.25);
a = imnoise2('rayleigh',10000,1,0,1);
b = imnoise2('exponential',10000,1,1);
c = imnoise2('erlang',10000,1,2,5);
subplot(2, 3, 1), hist(r,50), title('高斯随机数直方图');
subplot(2, 3, 2), hist(p,50), title('均匀随机数直方图');
subplot(2, 3, 3), hist(q,50), title('对数正态随机数直方图');
subplot(2, 3, 4), hist(a,50), title('瑞利随机数直方图');
subplot(2, 3, 5), hist(b,50), title('指数随机数直方图');
subplot(2, 3, 6), hist(c,50), title('厄兰随机数直方图');
一幅图像的周期噪声典型地产生于图像获取过程中的电气和/或电动机械的干扰。图像的周期噪声通常通过频域滤波 来处理。周期噪声的模型是 2D正弦波,它有如下所示的方程式:
其中,x=0,1,2,…,M-1且y=0,1,2,…,N-1。A 是振幅, u 0 u_0 u0和 v 0 v_0 v0 分别确定了关于x 轴和y 轴的正弦频率。 B x B_x Bx和 B y B_y By 分别是关于原点的相移。
编写代码:
C = [0 64; 0 128; 32 32; 64 0; 128 0;-32 32];
[r,R,S] = imnoise3(512,512,C);
subplot(1, 3, 1), imshow(S,[]), title('指定脉冲的谱');
subplot(1, 3, 2), imshow(r,[]), title('在空间域中相应的正弦噪声模式');
C=[0 32; 0 64;16 16;32 0;64 0; -16 16];
[r,R,S] = imnoise3(512,512,C);
subplot(1, 2, 1), imshow(S,[ ]), title('(c)指定脉冲的谱');
subplot(1, 2, 2), imshow(r,[ ]), title('(d)在空间域中相应的正弦噪声模式');
C=[6 32;-2 2];
[r,R,S] = imnoise3(512,512,C);
imshow(r,[ ]), title('(e)其他噪声模式');
运行效果如下:
实验结论:imnoise3函数接受某个脉冲位置(频率坐标)的任意数,这些任意数中的每个都有自己的振幅、频率和相移参数,并且像前面描述的正弦和那样计算r(x,y)。这个函数还输出正弦波之和的傅立叶变换 R(u,v)以及及R(u,v)的谱。正弦波从给定脉冲的位置信息中通过逆 DFT 产生。这使它更加直观,而且也简化了空间噪声模式中频率含量的形象化显示。
注意:如果书本上imnoise3函数报错,提示1没有定义,那么修改源码
R(u2, v2) = -i*M*N*(A(j)/2)* exp(i*2*pi*(C(j,1)*B(j,1)/M + C(j, 2)*B(j, 2)/N));
为
R(u2, v2) = -i*M*N*(A(j)/2)* exp(i*2*pi*(C(j,2)*B(j,2)/M + C(j, 2)*B(j, 2)/N));
所以书本也可能存在小插曲,理解最重要。
估计周期噪声参数的典型方法是分析图像的傅立叶谱。周期噪声往往产生频率尖峰,频率 尖峰常常可以通过目测来检测。当噪声尖峰足够明显时,或在干扰频率的一些知识可用的情况 下,自动分析是有可能的。
令 z i z_i zi是用来表示一幅图像灰度级的离散随机变量,并且令 p( z i z_i zi), i=0,1,2,…,L-1。 p( z i z_i zi)是相应的归一化直方图,其中,L 是可能的灰度值的数目。直方图的分量p( z i z_i zi),是灰度值 z i z_i zi出现概率的估计 ,这个直方图也可以被看做灰度 PDF 的近似。
描述直方图形状的主要方法之一是使用直方图的中心矩(也被称做平均值的矩),定义为:
其中,n是矩的阶,m是均值。
函数 statmoments 计算平均值和n阶中心矩,并返回行向量v。语法如下:
[v, unv] = statmoments(p, n) %p 为直方图向量,n 是计算的矩的数量。
注意:对于 uint8类图像,p 的分量等于 2 8 2^8 28; 对 于 uint l6 类图像,等于2的16次方; 对于 single 或 double 类图像,等于 2 8 2^8 28或 2的16次方。
通常,噪声参数直接由带噪声的图像或一组图像估计。在这种情况下,所选择的方法是: 在一幅图像中选择尽可能与背景一样无特色的区域,以便使所选区域灰度值的可变性主要归因 于噪声。 在MATLAB中,使用函数 roipoly来选择感兴趣的区域, 这个函数将产生多边形的 ROI, 语法如下:
B = roipoly(f, c, r) %f 是我们感兴趣的图像,c 和 r 是相应(有序)多边形的顶点列坐标和行坐标(注意, 列先被指定)。
输出 B 是二值图像,大小与 f 相同,并且在感兴趣 的区域外为 0, 在感兴趣的区域内为 1。图像 B 是用来把操作限制在感兴趣的区域内的模板。
为了交互式地指定多边形的ROI,使用下面的语法:
B = roipoly(f) %把图像 f 显示到屏幕上,让用户使用鼠标来指定多边形。
为了得到二值图像和多边形顶点的列表,可以使用语法:
[B, c, r] = roipoly(...) %,c 和 r 是顶点的行坐标和列坐标。