Matlab数字图像处理(二)——图像增强的基本操作(含代码)
基本概念
(1)γ校正:由于数字显示设备的非线性转换特征,使得图像的显示与原始场景相比较而言发生偏暗或偏亮的现象,这个时候就可以采用γ校正进行处理,使图像的显示等于或接近原始场景。消除图像噪声是图像增强、恢复的内容之一。
(2)图像平滑去噪:在常见的图像处理软件中,都提供了常用的除噪功能,其中,空间域的平滑操作最常见。在Matlab中可以实现均值滤波和中值滤波。
(3)图像锐化:图像锐化的目的是突出图像的细节,或者是增强被模糊的细节,这种模糊是在数据获取过程中,由于操作失误导致或经过特殊方法处理后的结果。在matlab中可以实现在空间域的图像锐化,根据一阶和二阶微分算子,设计不同的模板,对图像进行微分计算。
1. γ校正:
(1)准备一幅8bit(256色)的灰度图像。如果是彩色图像,可利用rgb2gray函数转换为灰度图像。
(2)读取图像,用函数imadjust对图像进行校正,如下:
(3)用不同的γ值,重复(2),得到处理后的图像I1,I2,I3,…等。
(4)用subplot在同一个窗口中显示I,I1,I2,I3,…,以及它们的直方图。
【代码】
1. I=imread('pic1.jpg');
2. H=rgb2gray(I);
3. subplot(2,1,1);imshow(H);
4. subplot(2,1,2);imhist(H);
5. i=1;
6. for gamma=0.3:0.2:0.9
7. G=imadjust(H,[0 1],[0 1],gamma);
8. subplot(4,2,i);imshow(G);
9. i=i+1;
10. subplot(4,2,i);imhist(G);
11. i=i+1;
12.end
2.噪声的消除
关于对于边界数据的处理:
(1)忽略边界数据
(2)拓展图像(四周补上数据)
使用P值填充(如:P=0)
复制图像边界像素的值
镜像图像边界像素的值
周期扩展
关于两种方法的优劣
1.忽略边界数据
优点:滤波后的图像中所有像素点都能由整个模版处理
缺点:处理后的图像比原始图像小,输出的图像尺寸=n-w+1,w为模板的大小,但这里我们通过跳过边缘这些值来使得图像的大小不变。
2.拓展图像
优点:与原图的尺寸相等
缺点:若扩展方法不当,补在靠近图像边缘的部分会给处理后的图像带来不良影响,而且会随着滤波器尺寸的增加而增大
这里不论是均值滤波还是中值滤波,都直接采用忽略边界值的方法,因此从第二行、第二列开始,对每一像素求的相邻9个像素的均值来替代原像素,直到处理完倒数第二行、第二列的所有像素,同时跳过边缘的数据,得到除噪后的图像。
(1)均值滤波
【代码】
1. %avefilter.m
2. function G=avefilter(F,k)
3. %F 是待处理的图像
4. %k 是模版的大小,奇数
5. [m,n]=size(F);
6. %得到待处理图像F的大小
7.
8. %转换数据类型,便于计算
9. G=uint16(zeros(m,n));Ft=uint16(F);M=uint16(ones(k,k));
10.h=(k+1)/2;
11.for i=1:m
12. for j=1:n
13. if((i<h)||(j<h)||(i>m-h+1)||(j>n-h+1)) %不能被模版处理的区域
14. G(i,j)=Ft(i,j);continue; %像素值不变
15. end
16.
17.%取和模板同样大小的图像块,中间的像素是待处理的像素
18. T=Ft(i-(k-1)/2:i+(k-1)/2,j-(k-1)/2:j+(k-1)/2);
19. T=T.*M; %和模版相乘
20. G(i,j)=sum(T(:))/k^2; %结果求和并计算平均值
21. end
22.end
23.G=uint8(G); %结果转换成8-bit图像的数据类型
新建一个avefiltertest脚本来测试avefilter函数:
1. %aveflitertest
2. clear;
3.
4. F=imread('peppers2.jpg'); % 导入图像
5. F1=rgb2gray(F);
6. Fn=imnoise(F1,'salt & pepper',0.05); %给图像添加椒盐噪声
7. %Fn=imnoise(F1,'gaussian',0,0.01); %给图像添加高斯噪声
8.
9. subplot(2,3,1),imshow(F1);title('原图像') %画出原图像
10. subplot(2,3,2),imshow(Fn);title('添加噪声后的图像') %画出带噪音的图像
11.
12. %3*3 average filter
13. OUT1=avefilter(Fn,3);
14. subplot(2,3,3),imshow(OUT1);title('3*3均值滤波结果')
15.
16. %7*7 median filter
17. OUT2=avefilter(Fn,7);
18. subplot(2,3,4),imshow(OUT2);title('7*7均值滤波结果')
19.
20. %9*9 median filter
21. OUT3=avefilter(Fn,9);
22. subplot(2,3,5),imshow(OUT3);title('9*9均值滤波结果')
23.
24. %11*11 median filter
25. OUT4=avefilter(Fn,11);
26. subplot(2,3,6),imshow(OUT4);title('11*11均值滤波结果')
(2)中值滤波
【代码】
1. %medianfilter
2. function d=medianfilter(x,n)
3. p=size(x); %输入图像是p×q的,且p>n,q>n
4. x1=double(x);
5. x2=x1;
6. for i=1:p(1)-n+1
7. for j=1:p(2)-n+1
8. c=x1(i:i+(n-1),j:j+(n-1)); %取出x1中从(i,j)开始的n行n列元素,即模板(n×n的)
9. e=c(1,:); %是c矩阵的第一行
10. for u=2:n
11. e=[e,c(u,:)]; %将c矩阵变为一个行矩阵
12. end
13. mm=median(e); %mm是中值
14. x2(i+(n-1)/2,j+(n-1)/2)=mm;
15. end
16.end
17.d=uint8(x2);
新建一个medianfiltertest脚本来测试medianfilter函数,类似于均值滤波的测试函数,将调用的avefilter替换为medianfilter。
分析:
均值滤波中,模板越大,图像的细节越不清晰,图像越模糊。中值滤波中,模板的大小对图像细节与清晰度的影响较均值滤波相对较小。同时,均值滤波对高斯噪声处理效果更好,中值滤波对椒盐噪声处理效果更佳。
因为椒盐噪声的幅值基本是相同的,只是出现噪声点的位置是随机的,所以在统计意义下的噪声均值也不为零,因此,即使理想状况下,也无法完全去除噪声;而且,经过均值处理之后,噪声部分被弱化到周围像素点上,所以得到的结果是噪声幅值减小,但是噪声点的颗粒面积同时变大,所以效果不好。但是如果用中值滤波处理椒盐噪声,可以找到椒盐噪声点周围像素的中值从而来代替改噪声点,不会扩大噪声点的范围,所以效果会比均值滤波好。
高斯噪声的幅值大小不定,如果用中值滤波可能会使周围的正常点受到影响,但是用均值滤波的话,可以直接使用噪声点及其周围的点的均值来代替噪声点,效果比用中值滤波好。因此,均值滤波对高斯噪声有较好的抑制作用,而对于椒盐噪声的处理,中值滤波较有优势
3.图像的锐化
(1)利用一阶微分算子锐化图像
【代码】
1. %sharpen1
2. function G=sharpen1(F,Dx,Dy)
3. [m,n]=size(F); %获取图像大小
4. [N,N]=size(Dx); %获取模板大小
5. h=(N+1)/2;
6.
7. for i=1:m
8. for j=1:n
9. if((i<h)||(j<h)||(i>m-h+1)||(j>n-h+1))
10. G(i,j)=double(F(i,j)); %图像不能被处理的区域
11. continue;
12. end
13. T=double(F(i-h+1:i+h-1,j-h+1:j+h-1));
14. T1=Dx.*T;
15. T2=Dy.*T;
16. G(i,j)=(sum(sum(T1))^2+sum(sum(T2))^2)^0.5;
17. end
18.end
19.
20.%将计算结果调整到[0,255]的范围
21.Min = min(G(:));
22.Max = max(G(:));
23.s=255/(Max-Min);
24.G = uint8((G-Min)*s);
新建一个testsharpen1脚本,调用一阶微分算子函数对图像进行处理
【代码】
1. clear;
2. F=imread('gull.jpg');
3.
4. Dx=[1 2 1;0 0 0;-1 -2 -1];
5. Dy=zeros(3,3);
6. G=sharpen1(F,Dx,Dy);
7. S=F+G;
8. subplot(4,2,1),imshow(G);title('水平微分算子提取的轮廓');
9. subplot(4,2,2),imshow(S);title('水平微分算子锐化后的叠加图像');
10.
11.Dx=zeros(3,3);
12.Dy=[1 0 -1;2 0 -2;1 0 -1];
13.G1=sharpen1(F,Dx,Dy);
14.S1=F+G1;
15.subplot(4,2,3),imshow(G1);title('垂直微分算子提取的轮廓');
16.subplot(4,2,4),imshow(S1);title('垂直微分算子锐化后的叠加图像');
17.
18.Dx=[-1 0 -1;-1 0 -1;-1 0 -1];
19.Dy=[-1 -1 -1;0 0 0;1 1 1];
20.G2=sharpen1(F,Dx,Dy);
21.S2=F+G2;
22.subplot(4,2,5),imshow(G2);title('priwitt微分算子提取的轮廓');
23.subplot(4,2,6),imshow(S2);title('priwitt微分算子锐化后的叠加图像');
24.
25.Dx=[-1 0 1;-2 0 2;-1 0 1];
26.Dy=[-1 -2 -1;0 0 0;1 2 1];
27.G3=sharpen1(F,Dx,Dy);
28.S3=F+G3;
29.subplot(4,2,7),imshow(G3);title('sobel微分算子提取的轮廓');
30.subplot(4,2,8),imshow(S3);title('sobel微分算子锐化后的叠加图像');
(2)利用二阶微分算子处理图像
【代码】
2. function G=laplacian(F,D)
3. [m,n]=size(F); %图像大小
4. [N,N]=size(D); %模板大小
5. h=(N+1)/2;
6. for i=1:m
7. for j=1:n
8. if((i<h)||(j<h)||(i>m-h+1)||(j>n-h+1))
9. G(i,j)=double(F(i,j)); %图像不能被处理的区域
10. continue;
11. end
12. T=double(F(i-h+1:i+h-1,j-h+1:j+h-1));
13. TR=D.*T;
14. G(i,j)=abs(sum(sum(TR)));
15. end
16.end
17.Min = min(G(:));
18.Max = max(G(:));
19.s=255/(Max-Min);
20.G = uint8((G-Min)*s);
建立一个testLaplacian脚本,调用Laplacian函数
【代码】
1. %testlaplacian.m
2. H=imread('gull.jpg'); %读取8bit的RGB图像
3. subplot(1,3,1),imshow(H);
4. title('原图像');
5.
6. D=[0 -1 0;-1 4 -1;0 -1 0];
7. G=laplacian(H,D);
8. subplot(1,3,2),imshow(G);
9. title('二阶微分Laplacian算子轮廓');
10.
11.S=G+H;
12.subplot(1,3,3),imshow(S);
13.title('二阶微分Laplacian算子锐化叠加');
4.图像的去噪与锐化的组合
先用均值滤波器去除噪声,然后用Laplacian算子锐化
【代码】
1. F=imread('building.jpg');
2. subplot(3,2,1),imshow(F);
3. title('building');
4.
5. %加上高斯噪声
6. Fn=imnoise(F, 'gaussian',0.05);
7. subplot(3,2,3),imshow(Fn);
8. title('添加高斯噪声');
9.
10.%用均值滤波器去除噪声
11.G=avefilter(Fn,3);
12.subplot(3,2,5),imshow(G);
13.title('用均值滤波器去除噪声');
14.
15.%用Laplacian算子锐化
16.D=[0 -1 0;-1 4 -1;0 -1 0];
17.H=laplacian(G,D);
18.subplot(3,2,4),imshow(H);
19.title('用Laplacian算子锐化');
20.
21.%图像叠加
22.K = imadd(F,H,'uint16');
23.subplot(3,2,6);
24.imshow(K,[]);
25.title('锐化图像叠加');
先用Laplacian算子锐化,然后用均值滤波器去除噪声
【代码】
1. F=imread('building.jpg');
2. subplot(3,2,1),imshow(F);
3. title('building');
4.
5. %加上高斯噪声
6. Fn=imnoise(F, 'gaussian',0.05);
7. subplot(3,2,3),imshow(Fn);
8. title('添加高斯噪声');
9.
10.%用Laplacian算子锐化
11.D=[0 -1 0;-1 4 -1;0 -1 0];
12.H=laplacian(Fn,D);
13.subplot(3,2,5),imshow(H);
14.title('用Laplacian算子锐化');
15.
16.%用均值滤波器去除噪声
17.G=avefilter(H,3);
18.subplot(3,2,4),imshow(G);
19.title('用均值滤波器去除噪声');
20.
21.%图像叠加
22.K = imadd(F,G,'uint16');
23.subplot(3,2,6);
24.imshow(K,[]);
25.title('图像叠加')
5.相同的直方图的两幅不同的图像3*3均值滤波
(1) 生成一半为黑,一半为白的图像
建立一个生成一半为黑,一半为白的图像
【代码】
1. function img = writehalf(width,height)
2. for i=1:width
3. for j=1:height/2
4. img(i,j)=255;
5. end
6. end
7. for i=1:width
8. for j=height/2+1:height
9. img(i,j)=0;
10. end
11.end
(2) 生成棋盘格图像
建立一个生成棋盘格的函数
【代码】
1. function chess = writeChess(width,height,xNum,yNum)
2. %width 单元格宽度,以像素为单位
3. %height 单元格高度,以像素为单位
4. %xNum 棋盘格横向单元格个数
5. %yNum 棋盘格纵向单元格个数
6. for row = 1 : xNum
7. for col = 1 : yNum
8. up = row*height-height+1;
9. down = row*height;
10. left = width*col-width+1;
11. right = width*col;
12. if mod((row+col),2)
13. chess(up:down,left:right) = 0;
14. else
15. chess(up:down,left:right) = 255;
16. end
17. end
18.end
19.end
调用两个函数对不同大小的的图像一和图像二进行处理,并绘制处理前后的图像以及其直方图。
分析:
图像1和图像2在滤波处理之前的直方图是一样的,当尺寸为8*8时,图像1滤波后的直方图中灰度值为0和255的都有26个像素,灰度值为85和170的都有6个像素;图像2滤波后的直方图中灰度值为0和255均有14个像素,灰度值为113和142的都有18个像素。
通过对比两幅滤波过后的图像,发现结果也不同:图像一是黑白交界处出现了两种灰色的像素,但是图像二的在图像的中心部分,除了最外层的一圈28个像素没有变换之外,中间的正方形内像素都发生了灰度上的变化。
当图像尺寸增加到24*24及更大时,图一的直方图的形态没有变化,图二的直方图的形态发生了变化。且当尺寸不断增大时,中间的两个灰度值的元素所占的比例逐渐减小。