数字图像处理第二章
数字图像处理—灰度变换与空间滤波
图像的处理有两种思路,一种是对图像本身的直接处理,即空间域处理;另一种是在频率域进行处理。在空间域的处理相对简单,因此本文首先介绍的是空间域处理法。空域中有两种重要处理方法:灰度变换(或亮度变换)和空间滤波(或邻域处理、空间卷积)。
(一)背景知识
空间域处理表达式:
g(x,y)=T[f(x,y)]
其中,f(x,y)为输入图像,g(x,y)为处理后的图像,T为对图像的f的算子,作用于点(x,y)的领域。
(二)灰度变换函数
由于输出图像仅仅取决于点的灰度值,而不是取决于点的领域,因此灰度变换函数通常如公式所示:
s=T(r)
其中,r表示图像f中的灰度,s表示图像g中的灰度。两者在图像中处于相同的坐标(x,y)处。
2.1 imadjust函数
imadjust函数是针对灰度图像进行灰度变换的基本图像处理工具箱函数。
语法格式:
g = imadjust(f,[low_in; high_in],[low_out; high_out],gamma)
此函数将f的灰度值映射到g中的新值,也就是将low_in至hige_in之间的值映射到low_out至high_out之间的值。low_in以下与high_in以上的值被截去。也就是将low_in以下的值映射到low_out,high_in以上的值映射到high_out。
参数gamma指明了由f映射生成图像g时的曲线。如果gamma小于1,映射被加权至较亮的输出值。如果gamma大于1,映射被加权到较暗的输出值。如果省略了函数的参量,则gamma默认为1(线性映射)。
代码案例如下:
imread('D:\数字图像处理\blue.jpg'); %读取图片文件中的数据
f=imread('D:\数字图像处理\blue.jpg');
g1 = imadjust(f, [0 1], [1 0]); %对像素值进行反转,负片效果
imshow(g1); %显示图像g1
g2 = imadjust(f, [0.5 0.75], [0 1]); %将[0.5,0.75]之间的灰度扩展到[0,1]整个范围,图像颜色变鲜艳
figure; %创建一个用来显示图形输出的一个窗口对象
g3= imadjust(f, [0 1],[0.5 0.75]); %将[0.5,0.75]之间的灰度压缩到[0,1]整个范围,图像颜色变暗淡
figure; %创建一个用来显示图形输出的一个窗口对象
imshow(g3); %显示图像g3
g4 = imadjust(f, [], [],2); %非线性变化处理
figure; %创建一个用来显示图形输出的一个窗口对象
imshow(g4); %显示图像g4
g5= imadjust(f, [], [],0.6); %非线性变化处理
figure; %创建一个用来显示图形输出的一个窗口对象
imshow(g5); %显示图像g5
分析:
- f到g1的变换,负片变换,即取反变换。对一个灰度图像f 取反(负片)变换即为255减去f 中的每个像素点的灰度值,得到的新图像g1 即为负片变换后的图像。对像素值进行了反转,g1也被称为负片图像。
- g2图是将[0.5 0.75]之间的灰度扩大到[0 1]整个范围,图像整体变明亮了,这种类型的处理对于强调图像中感兴趣的灰度区非常有用,能提高图片的对比度。
- g3图是将[0 1]之间的灰度压缩到[0.5 0.75]范围,图像整体变灰暗了,这种类型的处理能降低图片的对比度。
- g4图灰度图像的靠近low_in的灰度值较低像素点灰度值变低,其灰度变化范围被压缩,灰度值靠近high_in的一端的灰度变化范围被拉伸,映射加权至较暗的输出值。
- g5图灰度图像靠近low_in的灰度值较低像素点灰度值变高,其灰度变化范围被拉伸,灰度值靠近high_in的一端灰度变化范围被压缩,图像整体变明亮。
深入理解:
uint8类型图像,实际区间为[ ]x255=[0 255]。uint16类型图像,实际区间为[ ]x65536=[0 65536],以[0.5 0.75]为例,uint8类型图像,实际区间为[ 127.5 191.25],uint16类型图像,实际区间为[ 32767 49151]。而imadjust(f, [0.5 0.75], [0 1]),就是将区间[127.5 191.25]映射到[0 255],映射默认的是线性对应,由两点确定一条直线。
2.2 scretchlim函数
scretchlim函数用于自适应找到一个分割阈值向量来改变一幅图像的对比度。能计算图像的直方图,并自动判断调节范围,它以分向量形式返回灰度范围,然后将这个向量直接传递给imadjust函数。如果没有使用这个函数,就需要先观察输入图像的直方图。
语法格式:
Low_High = stretchlim(f,tol);
代码案例如下:
imread('D:\数字图像处理\第二章学习\blue.jpg');
f=imread('D:\数字图像处理\第二章学习\blue.jpg');
low_high=stretchlim(f); %对比度拉伸,是一个两元素的向量
g6=imadjust(f,low_high,[]);
imshow(f);
figure;
imshow(g6);
2.3 对数及对比度扩展变换
对数和对比度扩展变换是动态范围操作的基本工具。对数变换通过下列表达式实现:
g=c*log(1+f) %c为尺度比例常数,f为原图灰度值,g 为变换后的目标灰度值
分析:
- 变换形状与gamma曲线相似, gamma曲线是可变的,但是对数函数的形状是固定的。
- 主要应用:压缩动态范围,实现图像灰度扩展和压缩功能,扩展低灰度值而压缩高灰度值。
- 例子:傅里叶变换的频谱图。傅立叶频谱的范围在[0,10^6]或更高范围是常见的,而显示器是无法完整的显示如此大范围的灰度值的,从而导致频谱中低灰度值细节会被丢失掉。而将得到的频谱值进行对数变换,可以将其动态范围变换到一个合适区间,通常期望得到的是将压缩值返回至显示的全域。
代码案例如下:
imread('D:\数字图像处理\第二章学习\jimei.jpg');
f=imread('D:\数字图像处理\第二章学习\jimei.jpg');
g7=im2uint8(mat2gray(f)); %mat2gray(f):会将压缩值限定在【0,1】范围 im2uint8( mat2gray(f) ):会将值限定在【0,255】范围
g8 = im2uint8(mat2gray(log(1 + double(z))));
imshow(g7);
figure, imshow(g8);
2.4.指定任意灰度变换
使用指定的变换函数变换一幅图像的灰度。
表达式:
g=interp1(z,T,f) //f是输入图像,g是输出图像,T表示包含变换函数值的列向量,z是长度与T相同的列向量
z=linspace(0,1,numel(T))
对于f中的像素值,interp1首先查找横坐标(z)的值,然后查找(内插)相应的T中的值,并在相应的像素位置输出g的内插值。
代码案例如下:
z = 0:10;
T = sin(x);
xi = 0:.25:10;
g = interp1(z,T,xi); %默认分段线性内插
plot(z,T,'o',xi,g)
2.5 针对灰度变换的某些公用M-函数
2.5.1处理可变数目的输入或输出
nargin函数:检测输入到M-函数的参量的数目;
n=nargin %返回输入到M-函数的参量的实际数量
nargout函数:M-函数的输出;
n=nargout %指定调用函数所返回的参数的个数
nargchk函数:能够在M-函数体中检测传递过来的参量的数量是否正确。
msg=nargchk(low,high,number)
代码案例如下:
function spir_len = examp(d, n, lcolor) %计算螺旋线的周长,并以lcolor颜色填充螺旋线
% 输入参数:
% d: 螺旋的旋距
% n: 螺旋的圈数
% lcolor:画图线的颜色
% 输出参数:
% spir_len:螺旋的周长
if nargin > 3 % 输入参数的实际数量大于3
error('输入变量过多!');
elseif nargin == 2 % 输入参数的实际数量等于2
lcolor = 'b'; % 默认情况下为蓝色
end
j = sqrt(-1);
phi = 0 : pi/1000 : n*2*pi; %角度
amp = 0 : d/2000 : n*d; %模长
spir = amp .* exp(j*phi); %用复数形式表示
if nargout == 1
spir_len = sum(abs(diff(spir))); %diff一阶查分求解螺旋线的周长
fill(real(spir), imag(spir), lcolor);
elseif nargout == 0
plot(spir, lcolor); %以spir元素为横坐标值, lcolor元素为纵坐标值绘制曲线。
else
error('输出变量过多!');
end
axis('square'); %将当前坐标系图形设置为方形。横轴及纵轴比例是1:1
function msg = nargchk(low, high, number)
msg = [ ] ;
if (number < low) %当函数在number的值小于low返回下列消息
msg = ' Not enough input arguments. ' ;
elseif (number > high) %当函数在number的值大于high返回下列消息
msg = ' Too many input arguments. ' ;
end
2.5.2 另一个针对灰度变换的M-函数
intrans函数:能执行负片变换,对数变换,gamma变换及对比度扩展。
代码案例如下:
function image = changeclass(class, varargin)
switch class
case 'uint8'
image = im2uint8(varargin{:}); %varargin是单元数组,因而其中的元素应使用花括号进行选择
case 'uint16'
image = im2uint16(varargin{:});
case 'double'
image = im2double(varargin{:});
otherwise
error('Unsupported IPT data class.');
end
function g = intrans(f, varargin)
if strcmp(class(f), 'double') & max(f(:)) > 1 & ...
~strcmp(varargin{1}, 'log')
f = mat2gray(f);
else
f = im2double(f);
end
method = varargin{1};
switch method
case 'neg'
g = imcomplement(f);
case 'log'
if length(varargin) == 1
c = 1;
elseif length(varargin) == 2
c = varargin{2};
elseif length(varargin) == 3
c = varargin{2};
classin = varargin{3};
else
error('Incorrect number of inputs for the log option.')
end
g = c*(log(1 + double(f)));
case 'gamma'
if length(varargin) < 2
error('Not enough inputs for the gamma option.')
end
gam = varargin{2};
g = imadjust(f, [ ], [ ], gam);
case 'stretch'
if length(varargin) == 1
m = mean2(f);
E = 4.0;
elseif length(varargin) == 3
m = varargin{2};
E = varargin{3};
else error('Incorrect number of inputs for the stretch option.')
end
g = 1./(1 + (m./(f + eps)).^E);
otherwise
error('Unknown enhancement method.')
end
g = changeclass(classin, g);
f = imread('D:\数字图像处理\第二章学习\jimei.jpg');
figure(1)
imshow(f)
g = intrans(f, 'stretch', mean2(im2double(f)), 0.9);
figure(2)
imshow(g)
2.5.3 用于标定灰度的M-函数
gscale函数:当处理图像时,导致像素值在负值到正值很宽的范围内是很普遍的。尽管在中间计算过程中没有问题,但当我们想利用8位或16位格式保存或观看一幅图像时,就会出现问题。在这种情况下,通常希望把图像标度在全尺度,即最大范围[0, 255]或[0, 65535]。而称作gscale的M-函数可以实现此功能。此外,此函数能将输出灰度映射到某个特定的范围。
g = gscale(f, method, low, high)
f是将被标度的图像,method的可选值有full8(默认)和full16,full8把输出标度为全范围[0, 255],full16把输出标度为全范围[0, 65535]。如果内含,参数low与high在两种变换中都将被忽略。第三个method的可选为’minmax’,在这种情况下,low与high都在范围[0, 1]内的值。当选用的minmax,结果映射值必须在[low,high]范围内。