http://blog.csdn.net/xixi_0921/article/details/50533487 整理笔记
一、前言
图像的灰度变换则不同,其对像素的计算仅仅依赖于当前像素和灰度变换函数。
灰度变换也被称为图像的点运算(只针对图像的某一像素点)是所有图像处理技术中最简单的技术,其变换形式如下:
S=T(r);
其中,T是灰度变换函数;r是变换前的灰度;s是变换后的像素。
图像灰度变换的有以下作用:
(1)改善图像的质量,使图像能够显示更多的细节,提高图像的对比度(对比度拉伸)灰度变换是基于点操作的增强方法,它将每一个像素的灰度值按照一定的数学变换公式转换为一个新的灰度值,如增强处理中的对比度增强。对比度增强可以采用线性拉伸和非线性拉伸。
线性拉伸可以将原始输入图像中的灰度值不加区别地扩展。如果要求对局部扩展拉伸某一范围的灰度值,或对不同范围的灰度值进行不同的拉伸处理时,采用分段线性拉伸。
非线性拉伸常采用对数扩展和指数扩展。对数扩展拉伸低亮度区,压缩高亮度区;指数扩展拉伸了高亮区,压缩了低亮度区。
影响系统图像清晰程度的因素很多,例如室外光照度不够均匀就会造成图像灰度过于集中;由CCD(摄像头)获得的图像经过A/D(数/模转换,该功能在图像系统中由数字采集卡来实现)转换、线路传送都会产生噪声污染等等。因此图像质量不可避免的降低了,轻者表现为图像不干净,难于看清细节;重者表现为图像模糊不清,连概貌也看不出来。
因此,在对图像进行分析之前,必须要对图像质量进行改善,一般情况下改善的方法有两类:图像增强和图像复原。
图像增强不考虑图像质量下降的原因,只将图像中感兴趣的特征有选择的突出,而衰减不需要的特征,它的目的主要是提高图像的可懂度。
图像复原技术与增强技术不同,它需要了解图像质量下降的原因,首先要建立"降质模型",再利用该模型,恢复原始图像。
根据图像增强处理过程所在的空间不同,图像增强可分为空域增强法和频域增强法两大类。
频域增强是在图像的某种变换域内,对图像的变换系数值进行运算,即作某种修正,然后通过逆变换获得增强了的图像。
空域增强则是指直接在图像所在的二维空间进行增强处理,既增强构成图像的像素。空域增强法主要有灰度变换增强,直方图增强,图像平滑和图像锐化等。
图像的灰度变换处理是图像增强处理技术中一种非常基础、直接的空间域图像处理法,也是图像数字化软件和图像显示软件的一个重要组成部分。灰度变换是指根据某种目标条件按一定变换关系逐点改变原图像中每一个像素灰度值的方法。目的是为了改善画质,使图像的显示效果更加清晰。
灰度变换函数描述了输入灰度值和输出灰度值之间变换关系,一旦灰度变换函数确定下来了,那么其输出的灰度值也就确定了。可见灰度变换函数的性质就决定了灰度变换所能达到的效果。用于图像灰度变换的函数主要有以下三种:
令r为变换前的灰度,s为变换后的灰度,则线性变换的函数:
其中,a为直线的斜率,b为在y轴的截距。选择不同的a,b值会有不同的效果:
在进行图像增强时,上述的线性变换函数用的较多的就是图像反转了,根据上面的参数,图像反转的变换函数为:。图像反转得到的是图像的负片,能够有效的增强在图像暗区域的白色或者灰色细节。其效果如下:
a=imread('circlesBrightDark.png'); %读取原始图像
subplot(1,2,1),
imshow(a); %显示原始图像
title('原始图像');
%显示函数的曲线图
b=255-a;
subplot(1,2,2),
imshow(b)
title('反转之后的图像');
补充代码:matlab运行试试就知道效果了。
I =imread('lena.jpg');
[d1,d2,d3] =size(I);
if(d3 > 1)
I =rgb2gray(I);%如果是灰度图就不用先变换
end
Im = double(I);
A=0.5; B=0;
darker=Im*A+B;
A=1;B=0;
mover=Im*A+B;
A=1.5;B=0;
lighter=Im*A+B;
A=-1;B=255;
reverser=Im*A+B;
J1=uint8(darker);
J2=uint8(mover);
J3=uint8(lighter);
J4=uint8(reverser);
subplot(2,3,1),imshow(I);title('原图');
subplot(2,3,2),imshow(J1);title('a=0.5 减小对比度');
subplot(2,3,5),imshow(J2);title('a=1灰度值上移');
subplot(2,3,3),imshow(J3);title('a=1.5增大对比度');
subplot(2,3,6),imshow(J4);title('a=-1反相');
运行上述代码后得到结果,当
a
=0.5的时候,图片的对比度减小,整体偏灰蒙蒙的感觉;当
a
=1.5时,图片的对比度增大,由于黑色部分比白色部分面积少,白色的增强使得整张图片显亮;当
a
=1,
b
=30时,对比度不变,但是所有像素点的灰度值都加30,使得整体均匀提亮;
a
=-1,
b
=255时,相当于求每个像素点灰度值的补,也就是黑的变白,白的变黑,做了反相运算,也就是负片变换。当图片整体偏黑,遮盖了细节时,可以负片处理。
为了突出感兴趣的目标或者灰度区间,相对抑制那些不感兴趣的灰度区域,可采用分段线性法。常用的是三段线性变换。
分段线性变换称为图像直方图的拉伸,它与完全线性变换类似,其不同之处在于其变换函数是分段的。其变换函数表达式如下:
I=imread('glass.png'); %读取图像
subplot(2,2,1);
imshow(I);
title('原图像');
subplot(2,2,2);
imhist(I);
title('原图像直方图');
subplot(2,2,3);
J=imadjust(I,[],[0.4 0.6]); %调整图像的灰度到指定范围
imshow(J);
title('调整灰度后的图像');
subplot(2,2,4);
imhist(J);
title('调整灰度后的直方图');
在电视和图形监视器中,显像管发生的电子束及其生成的图像亮度并不是随显像管的输入电压线性变化,电子流与输入电压相比是按照指数曲线变化的,输入电压的指数要大于电子束的指数。这说明暗区的信号要比实际情况更暗,而亮区要比实际情况更高。所以,要重现摄像机拍摄的画面,电视和监视器必须进行伽玛补偿。这种伽玛校正也可以由摄像机完成。我们对整个电视系统进行伽玛补偿的目的,是使摄像机根据入射光亮度与显像管的亮度对称而产生的输出信号,所以应对图像信号引入一个相反的非线性失真,即与电视系统的伽玛曲线对应的摄像机伽玛曲线,它的值应为1/γ,我们称为摄像机的伽玛值。电视系统的伽玛值约为2.2,所以电视系统的摄像机非线性补偿伽玛值为0.45。彩色显像管的伽玛值为2.8,它的图像信号校正指数应为1/2.8=0.35,但由于显像管内外杂散光的影响,重现图像的对比度和饱和度均有所降低,所以彩色摄像机的伽玛值仍多采用0.45。在实际应用中,我们可以根据实际情况在一定范围内调整伽玛值,以获得最佳效果。
(Gamma Correction,伽玛校正):所谓伽玛校正就是对图像的伽玛曲线进行编辑,以对图像进行非线性色调编辑的方法,检出图像信号中的深色部分和浅色部分,并使两者比例增大,从而提高图像对比度效果。计算机绘图领域惯以此屏幕输出电压与对应亮度的转换关系曲线,称为伽玛曲线(Gamma Curve)。
以传统CRT(Cathode Ray Tube)屏幕的特性而言,该曲线通常是一个乘幂函数,Y=(X+e)γ,其中,Y为亮度、X为输出电压、e为补偿系数、乘幂值(γ)为伽玛值,改变乘幂 值(γ)的大小,就能改变CRT的伽玛曲线。典型的Gamma值是0.45,它会使CRT的影像亮度呈现线性。使用CRT的电视机等显示器屏幕,由于对于 输入信号的发光灰度,不是线性函数,而是指数函数,因此必需校正。
假设图像中有一个像素,值是 200 ,那么对这个像素进行校正必须执行如下步骤:
1. 归一化 :将像素值转换为 0 ~ 1 之间的实数。 算法如下 : ( i + 0. 5)/256 这里包含 1 个除法和 1 个加法操作。对于像素 A 而言 , 其对应的归一化值为 0. 783203 。
2. 预补偿 :根据公式 , 求出像素归一化后的 数据以 1 /gamma 为指数的对应值。这一步包含一个 求指数运算。若 gamma 值为 2. 2 , 则 1 /gamma 为 0. 454545 , 对归一化后的 A 值进行预补偿的结果就 是 0. 783203 ^0. 454545 = 0. 894872 。
3. 反归一化 :将经过预补偿的实数值反变换为 0 ~ 255 之间的整数值。具体算法为 : f*256 - 0. 5 此步骤包含一个乘法和一个减法运算。续前 例 , 将 A 的预补偿结果 0. 894872 代入上式 , 得到 A 预补偿后对应的像素值为 228 , 这个 228 就是最后送 入显示器的数据。
如上所述如果直接按公式编程的话,假设图像的分辨率为 800*600 ,对它进行 gamma 校正,需要执行 48 万个浮点数乘法、除法和指数运算。效率太低,根本达不到实时的效果。
针对上述情况,提出了一种快速算法,如果能够确知图像的像素取值范围 , 例如 , 0 ~ 255 之间的整数 , 则图像中任何一个像素值只能 是 0 到 255 这 256 个整数中的某一个 ; 在 gamma 值 已知的情况下 ,0 ~ 255 之间的任一整数 , 经过“归一 化、预补偿、反归一化”操作后 , 所对应的结果是唯一的 , 并且也落在 0 ~ 255 这个范围内。
如前例 , 已知 gamma 值为 2. 2 , 像素 A 的原始值是 200 , 就可求得 经 gamma 校正后 A 对应的预补偿值为 228 。基于上述原理 , 我们只需为 0 ~ 255 之间的每个整数执行一次预补偿操作 , 将其对应的预补偿值存入一个预先建立的 gamma 校正查找表 (LUT:Look Up Table) , 就可以使用该表对任何像素值在 0 ~ 255 之 间的图像进行 gamma 校正。
for i=0:255;
f=power((i+0.5)/256,1/2.2);
LUT(i+1)=uint8(f*256-0.5);
end
img=imread('onion.png'); %读入图像
img0=rgb2ycbcr(img);
R=img(:,:,1);
G=img(:,:,2);
B=img(:,:,3);
Y=img0(:,:,1);
Yu=img0(:,:,1);
[x y]=size(Y);
for row=1:x
for width=1:y
for i=0:255
if (Y(row,width)==i)
Y(row,width)=LUT(i+1);
break;
end
end
end
end
img0(:,:,1)=Y;
img1=ycbcr2rgb(img0);
R1=img1(:,:,1);
G1=img1(:,:,2);
B1=img1(:,:,3);
subplot(1,2,1);
imshow(img); %显示图像
title('原图');
subplot(1,2,2);
imshow(img1);
title('Gamma矫正后的图像')
原理:
当用某些非线性函数作为图像的映射函数时,可实现图像灰度的非线性变换,如利用对数函数、指数函数等可实现对数变换和指数变换。
对数变换主要用于将图像的低灰度值部分扩展,将其高灰度值部分压缩,以达到强调图像低灰度部分的目的。变换方法由下式给出
其中,c是一个常数,,假设,根据上图中的对数函数的曲线可以看出:对数变换,将源图像中范围较窄的低灰度值映射到范围较宽的灰度区间,同时将范围较宽的高灰度值区间映射为较窄的灰度区间,从而扩展了暗像素的值,压缩了高灰度的值,能够对图像中低灰度细节进行增强。;从函数曲线也可以看出,反对数函数的曲线和对数的曲线是对称的,在应用到图像变换其结果是相反的,反对数变换的作用是压缩灰度值较低的区间,扩展高灰度值的区间。
I=imread('office_4.jpg');
I1=rgb2gray(I);
subplot(1,2,1),imshow(I1);
title('灰度图像');
axis([50,250,50,200]);
grid on; %显示网格线
axis on; %显示坐标系
J=double(I1);
J=40*(log(J+1));
H=uint8(J);
subplot(1,2,2),
imshow(H);
title('对数变换图像');
axis([50,250,50,200]);
grid on;
axis on;
Im=imread('coins.png');
f =mat2gray(Im,[0 255]);
v = 5;
g_1 = log2(1 +v*f)/log2(v+1);
v = 10;
g_2 = log2(1 +v*f)/log2(v+1);
v = 200;
g_3 = log2(1 +v*f)/log2(v+1);
subplot(2,2,1);
imshow(f,[0 1]);
xlabel('a).原图');
subplot(2,2,2);
imshow(g_1,[0 1]);
xlabel('b).\fontname{TimesNew Roman}\itv\rm=5');
subplot(2,2,3);
imshow(g_2,[0 1]);
xlabel('c).\fontname{TimesNew Roman}\itv\rm=10');
subplot(2,2,4);
imshow(g_3,[0 1]);
xlabel('d).\fontname{TimesNew Roman}\itv\rm=200');
4.反对数变换
原理:
与对数函数不同的是,反对数强调高灰度部分,其原理已在上例中详述。只要将s和r互换就可以得到图像之间的关系。
Im =imread('coins.png');
f =mat2gray(Im,[0 255]);
v = 2;
g_1 =((f.^(v+1)))/v;
disp(g_1);
v = 5;
g_2 =((f.^(v+1)))/v;
disp(g_2);
v = 20;
g_3 =((f.^(v+1)))/v;
subplot(2,2,1);
imshow(f,[0 1]);
xlabel('a).原图');
subplot(2,2,2);
imshow(g_1,[0 1]);
xlabel('b).\fontname{TimesNew Roman}\itv\rm=2');
subplot(2,2,3);
imshow(g_2,[0 1]);
xlabel('c).\fontname{TimesNew Roman}\itv\rm=5');
subplot(2,2,4);
imshow(g_3,[0 1]);
xlabel('d).\fontname{TimesNew Roman}\itv\rm=20');
5.直方图均衡化
http://blog.csdn.net/superjunenaruto/article/details/52431941 写的非常好的一个博客,通俗易懂。
原理:
直方图均衡化是一种最常用的直方图修正。它是把给定图象的直方图分布改造成均匀直方图分布。由信息学的理论来解释,具有最大熵(信息量)的图象为均衡化图象。直观地讲,直方图均衡化导致图象的对比度增加。直方图均衡化基本做法是将每个灰度区间等概率分布代替了原来的随机分布,即增强后的图象中每一灰度级的像元数目大致相同。直方图均衡化可使得面积最大的地物细节得以增强,而面积小的地物与其灰度接近的地物进行合并,形成综合地物。减少灰度等级换取对比度的增大要注意的是,均衡化处理后的图象只能是近似均匀分布。均衡化图象的动态范围扩大了,但其本质是扩大了量化间隔,而量化级别反而减少了,因此,原来灰度不同的象素经处理后可能变的相同,形成了一片的相同灰度的区域,各区域之间有明显的边界,从而出现了伪轮廓。
I =imread('coins.png');
[d1,d2,d3] =size(I);
if(d3 > 1)
I = rgb2gray(I);%如果是灰度图就不用先变换
end
I = double(I) /255;
Im = uint8(255 *I * 0.5 + 0.5);
subplot(2,2,1);imshow(Im);title('原图');
gp=zeros(1,256);%计算各灰度出现的概率
for i=1:256
gp(i)=length(find(Im==(i-1)))/(d1*d2);
end
subplot(2,2,2);
bar(0:255,gp);
set(gca,'XLim',[0 255]);
title('原图灰度直方图');
newGp=zeros(1,256);%计算新的各灰度出现的概率
S1=zeros(1,256);
S2=zeros(1,256);
tmp=0;
for i=1:256
tmp=tmp+gp(i);
S1(i)=tmp;
S2(i)=round(S1(i)*256);
end
for i=1:256
newGp(i)=sum(gp(find(S2==i)));
end
subplot(2,2,4);
bar(0:255,newGp);
set(gca,'XLim',[0 255]);
title('均衡化后直方图');
newGrayPic=Im; %填充各像素点新的灰度值
for i=1:256
newGrayPic(find(Im==(i-1)))=S2(i);
end
subplot(2,2,3);imshow(newGrayPic);title('均衡化后');
小结:
灰度直方图均衡化的算法,简单地说,就是把直方图的每个灰度级进行归一化处理,求每种灰度的累积分布,得到一个映射的灰度映射表,然后根据相应的灰度值来修正原图中的每个像素。
但是经典的直方图均衡化算法可能存在以下一些不足:
(1)输出图像的实际灰度变化范围很难达到图像格式所允许的最大灰度变化范围;
(2)输出图像的灰度分布直方图虽然接近均匀分布, 但其值与理想值1/n仍有可能存在较大的差异, 并非是最佳值;
(3)输出图像的灰度级有可能被过多地合并。由于灰度的吞噬也易造成图像信息的丢失。