一、实验目的
1、熟悉基于基于单像素空域图像增强方法,理解并掌握直方图均衡化和规定化实现图像增强
二、实验环境
Matlab 2020B
三、实验内容
题目
1)对一幅低对比度分辨率的图像采用除直方图处理方法之外的灰度级变换方法实现图像增强。(图自选)
2)对一幅低对比度分辨率的图像采用直方图均衡化和规定化方法(单映射或组映射)实现图像增强,分别采用系统函数和自己编写函数实现相应用功能。(图自选)
3)写出实验报告。报告要求:实验目的、实验内容、实验过程、实验小结和较详细的图文说明。
相关知识
对于低分辨率的图像,可以用基于空域图像增强的方法。除了直方图处理方法,还可以使用灰度反转、对数变换、指数变换、对比度拉伸、灰度切片等。
直方图匹配(规定化)也使用histeq实现。histeq的两个参数分别为原图、被匹配图像的直方图。
在编写函数实现直方图规定化(直方图匹配)时,同样的,首先处理出原图的直方图和被匹配图像的直方图。直方图匹配可以使用单映射实现,也可以使用组映射实现。在实现单映射时,把原图中的相应灰度值按累积概率密度映射成被匹配图像的累积概率密度对应的灰度值。在实现组映射时,把被匹配图像的相应灰度值按累积概率密度映射成原图相应累积概率密度时对应的灰度值,并且需要填补空缺值。
部分核心代码
I_0=imread("Couple.bmp"); I_0=im2double(I_0); c=1; gamma=0.40; [w,h]=size(I_0); I_1=zeros(w,h); for i=1:w for j=1:h I_1(i,j)=I_0(i,j).^gamma; end end title("实验1-1") subplot(1,2,1);imshow(I_0);title('原图') subplot(1,2,2);imshow(I_1);title('新图')
完成了指数变换,使用了公式s = c r γ s=cr^\gammas=crγ,γ = 0.4 \gamma=0.4γ=0.4,成功使得图像变得更亮。
I_0=imread("Couple.bmp"); I_0=im2double(I_0); c=1; gamma=0.40; [w,h]=size(I_0); I_1=imadjust(I_0,[0.1 0.5],[0 1]); title("实验2-3") subplot(1,2,1);imshow(I_0);title('原图') subplot(1,2,2);imshow(I_1);title('imadjust')
完成了图像的对比度拉伸,使用matlab自带的imadjust函数实现,使得图像变亮。
I=im2double(I); anew=0; bnew=1; a0=min(min(min(I))); b0=0.5; A1=anew+(bnew-anew)/(b0-a0)*(I-a0); [row,col]=size(I); for i=1:row for j=1:col if(A1(i,j)<0) A1(i,j)=0; end if A1(i,j)>1 A1(i,j)=1; end end end imshow(A1)
I_0=imread("Couple.bmp"); I_0=im2double(I_0); c=2; [w,h]=size(I_0); I_1=zeros(w,h); for i=1:w for j=1:h I_1(i,j)=c*log(I_0(i,j)+1); end end title("实验1-1") subplot(1,2,1);imshow(I_0);title('原图') subplot(1,2,2);imshow(I_1);title('新图')
完成了图像的对数变换,取c = 2 c=2c=2,成功地使得图像变亮。
I=imread("Couple.bmp"); I=im2double(I); subplot(1,2,1);imshow(I);title('原图') [w,h]=size(I); I1=ones(w,h); for i=1:w for j=1:h I1(i,j)=1-I(i,j); end end subplot(1,2,2);imshow(I1);title('新图')
完成了图像的灰度反转,使得暗处变亮,亮处变暗。
I=imread("Couple.bmp"); subplot(2,2,1) imshow(I);title("原图") subplot(2,2,2) imhist(I);title("原直方图") ylim('auto') g=histeq(I,256); subplot(2,2,3) imshow(g);title("新图") subplot(2,2,4) imhist(g);title("新直方图") ylim('auto')
调用系统函数实现直方图均衡化
I=imread("Couple.bmp"); histogram=zeros(1,255); [w,h]=size(I); for i=1:w for j=1:h histogram(I(i,j)+1)=histogram(I(i,j)+1)+1;%处理出每个灰度级的像素点数量 end end %bar(zhifangtu) n=w*h;%图上像素点总数 p=histogram/n;%概率密度函数 s=zeros(1,255);%累积概率密度 s(1)=p(1); for i=2:255 s(i)=s(i-1)+p(i); end newimg=zeros(w,h);%新图 for i=1:w for j=1:h newimg(i,j)=s(I(i,j)+1);%新图对应像素点值为原图对应像素点值*灰度级数。但在此代码中,使用double存图 end end imshow(newimg) newimg=im2uint8(newimg); newhistogram=zeros(1,255); for i=1:w for j=1:h newhistogram(newimg(i,j)+1)=newhistogram(newimg(i,j)+1)+1;%新图中每个灰度级的像素点数量 end end title("实验2-8") subplot(2,2,1);imshow(I);title('原图') subplot(2,2,2);bar(histogram);title('原直方图') subplot(2,2,3);imshow(newimg);title('直方图均衡化后图像') subplot(2,2,4);bar(newhistogram);title('直方图均衡化后直方图')
自行编写函数实现了图像的直方图均衡化。先处理出原图每个灰度级出现的概率密度,再求解每个灰度级
I=imread("Couple.bmp"); Imatch=imread("match.png"); Imatch=rgb2gray(Imatch); [histogram,x]=imhist(Imatch); Inew=histeq(I,histogram); subplot(3,2,1),imshow(I);title("原图") subplot(3,2,2);imhist(I);title("原直方图") subplot(3,2,3);imshow(Imatch);title("被匹配图") subplot(3,2,4);imhist(Imatch);title("被匹配直方图") subplot(3,2,5);imshow(Inew);title("新图") subplot(3,2,6);imhist(Inew);title("新直方图")
使用matlab自带的函数实现了直方图匹配(直方图规定化)。
I=imread("Couple.bmp"); histogram=zeros(1,255); [w,h]=size(I); for i=1:w for j=1:h histogram(I(i,j)+1)=histogram(I(i,j)+1)+1;%处理出每个灰度级的像素点数量 end end %bar(zhifangtu) n=w*h; p=histogram/n; s1=zeros(1,255); s1(1)=p(1); for i=2:255 s1(i)=s1(i-1)+p(i); end I2=imread("match.png");%被匹配图像 histogram2=zeros(1,255); I2=im2gray(I2); [w2,h2]=size(I2); for i=1:w2 for j=1:h2 histogram2(I2(i,j)+1)=histogram2(I2(i,j)+1)+1;%处理出每个灰度级的像素点数量 end end n2=w2*h2; p2=histogram2/n2; s2=zeros(1,255); s2(1)=p2(1); for i=2:255 s2(i)=s2(i-1)+p2(i); end map=zeros(1,255);%将灰度级i映射成j for i=1:255 for j=1:254 if (s1(i)>=s2(j) && s1(i)<=s2(j+1))%将原图的灰度级与新图的灰度级匹配 if (abs(s1(i)-s2(j))<abs(s1(i)-s2(j+1)))%匹配到概率密度最接近的点 map(i)=j; else map(i)=j+1; end break end end end newimg=zeros(w,h);%新图 for i=1:w for j=1:h newimg(i,j)=map(I(i,j)+1);%按照匹配关系将原图像素点映射到新图 end end newimg=newimg/255; newimg=im2uint8(newimg); newhistogram=zeros(1,255); for i=1:w for j=1:h newhistogram(newimg(i,j)+1)=newhistogram(newimg(i,j)+1)+1;%新图的直方图 end end subplot(3,2,1),imshow(I);title("原图") subplot(3,2,2);bar(histogram);title("原直方图") subplot(3,2,3);imshow(Imatch);title("被匹配图") subplot(3,2,4);bar(histogram2);title("被匹配直方图") subplot(3,2,5);imshow(newimg);title("新图") subplot(3,2,6);bar(newhistogram);title("新直方图")
自行编写函数实现了直方图匹配,实现了单映射。先处理出原图每个灰度级出现的概率密度和累积概率密度,再处理被匹配图像每个灰度级的概率密度和累积概率密度。最后,将原图像的灰度级按照累积概率密度映射成被匹配图像的灰度级。得到原图的灰度级和其被映射成的灰度级的关系后,创建新图并将原图像的对应像素的灰度级的映射值填入。
I=imread("Couple.bmp"); histogram=zeros(1,255); [w,h]=size(I); for i=1:w for j=1:h histogram(I(i,j)+1)=histogram(I(i,j)+1)+1;%处理出每个灰度级的像素点数量 end end %bar(zhifangtu) n=w*h; p=histogram/n; s1=zeros(1,255); s1(1)=p(1); for i=2:255 s1(i)=s1(i-1)+p(i); end I2=imread("match.png");%被匹配图像 histogram2=zeros(1,255); I2=im2gray(I2); [w2,h2]=size(I2); for i=1:w2 for j=1:h2 histogram2(I2(i,j)+1)=histogram2(I2(i,j)+1)+1;%处理出每个灰度级的像素点数量 end end n2=w2*h2; p2=histogram2/n2; s2=zeros(1,255); s2(1)=p2(1); for i=2:255 s2(i)=s2(i-1)+p2(i); end map=zeros(1,255);%将灰度级i映射成j for j=1:255 for i=1:254 if (s2(j)>=s1(i) && s2(j)<=s1(i+1))%将新图的灰度级映射成原图的灰度级,组映射 if (abs(s2(j)-s1(i))<abs(s2(j)-s1(i+1))) map(i)=j; else map(i)=j+1; end break end end end for i=2:255 if (map(i)==0) map(i)=map(i-1); end end newimg=zeros(w,h); for i=1:w for j=1:h newimg(i,j)=map(I(i,j)+1); end end newimg=newimg/255; newimg=im2uint8(newimg); newhistogram=zeros(1,255); for i=1:w for j=1:h newhistogram(newimg(i,j)+1)=newhistogram(newimg(i,j)+1)+1; end end subplot(3,2,1),imshow(I);title("原图") subplot(3,2,2);bar(histogram);title("原直方图") subplot(3,2,3);imshow(Imatch);title("被匹配图") subplot(3,2,4);bar(histogram2);title("被匹配直方图") subplot(3,2,5);imshow(newimg);title("新图") subplot(3,2,6);bar(newhistogram);title("新直方图")
自行编写函数实现了直方图匹配,实现了组映射。同样的,先处理出原图每个灰度级出现的概率密度和累积概率密度,再处理被匹配图像每个灰度级的概率密度和累积概率密度。将被匹配的灰度级按照累积概率密度映射成被原图的灰度级。之后,若存在缺失值,即原图中某个灰度级被映射成的新图灰度级未知,则需要填补缺失值。得到原图的灰度级和其被映射成的灰度级的关系后,创建新图并将原图像的对应像素的灰度级的映射值填入。
实验结果
成功地实现了指数变换,可以看到新图明显地比原图更亮、对比度更高,因为s = c r γ s=cr^\gammas=crγ的γ < 1 \gamma<1γ<1。
成功地实现了对比度拉伸,使用matlab自带的imadjust函数。由于参数的选择,可以看到,部分点明显变亮,而部分像素点颜色仍然没有变化。
实现了对数变换,取参数c > 1 c>1c>1。可以明显地看到部分点变亮。
实现了灰度反转。
编写函数实现的函数类似于imadjust的效果,将[ 0 , 0.5 ] [0,0.5][0,0.5]的灰度值映射到[ 0 , 1 ] [0,1][0,1]。可以明显地看到图像变亮了。
使用系统自带的直方图均衡化函数,实现了直方图均衡化。可以看到,图像明显变亮。原本图像的灰度值分布在大约0150的范围内,在被直方图均衡化后,灰度值分布的更“均衡”了,分布在0255的范围。与前文不基于直方图的变换相比,此方法更好的保存了图像的一些细节,看起来更自然、真实。
使用自行编写的程序,实现了直方图均衡化。可以看到,自行编写的程序很好地还原了系统自带的直方图均衡化的程序的实现效果。不仅在图像上与系统自带的函数的处理结果类似,而且这一点能够在直方图的图像上体现出来。
调用了系统自带的函数,实现了直方图匹配。可以看到,被匹配的直方图在200~230的灰度级上的分布存在一个明显的高峰,所以这一高峰也体现在了直方图匹配处理后的图像上,也在200~230的灰度级上出现高峰。所以,图片明显变亮了。但是,由于被匹配图选取得过于亮,所以新图也显得过于亮了。
自行实现了直方图匹配,利用单映射的方法。可以看到,在处理的整体效果上较为还原了系统自带的函数的效果。
自行实现了直方图匹配,利用组映射的方法。虽然实现组映射的程序与单映射的程序略有区别,但是实现的效果还是类似的,殊途同归,都与调用系统自带的函数实现的效果大同小异。