摘自《数字图像处理》 冈萨雷斯
3.1 背景
3.2 亮度变换函数
亮度变换函数仅取决于亮度的值,而与(x, y)无关,所以亮度变换函数通常可写作如下所示的简单形式:
s = T(r)
其中,r表示图像f中响应点(x, y)的亮度,s表示图像g中响应点(x, y)的亮度
3.2.1 函数imadjust
语法为:
g = imadjust(f, [low_in high_in], [low_out high_out], gamma)
函数将对两个区间的值进行映射,区间外的将被剪掉。如果输入的是[]矩阵,则取默认区间[0 1]。参数gamma指定了曲线的形状,该曲线用来映射f的亮度值,以便生成图像g。若gamma小于1,则映射被加权至更高(更亮)的输出值,若gamma大于1则更暗。若省略gamma,则默认值为1,为线性映射。曲线形状如下图所示。
例3.1 使用函数imadjust
首先,我们的原图片是一幅数字乳房X射线图像f,他显示了一处疾患。采用下面的语句读入
>> f = imread('Fig0303(a)(breast).tif'); |
使用下面的语句进行明暗反转(负片图像),如上面的右图
>> g1 = imadjust(f, [0 1], [1 0]); |
这种获得明暗反转图像的过程可用于增强潜入在大片黑色区域中的白色或灰色细节。例如,在右边的图就可以非常容易的分析乳房组织。一幅图像的负片同样可以使用IPT函数imcomplement得到:
g = imcomplement(f)
下面的左图是执行下面语句的结果
>> g2 = imadjust(f, [0.5 0.75], [0 1]);
>> imshow(g2)
|
该命令将0.5至0.75之间的灰度级扩展到范围[0, 1]。这种类型的处理过程可以突出我们感兴趣的亮度带。最后使用如下命令得到下面右图
3.2.2 对数和对比度拉伸变换
对数与对比度拉伸变换是进行动态范围处理的基本工具。对数变换通过如下表达式实现:
g = c*log(1 + double(f))
其中,c是一个常数。该变换的形状类似于gamma曲线,在两个坐标轴上,低值设置为0,高值设置为1.注意,gamma曲线的形状是可变的,而对数函数形状是固定的。
对数变换的一项主要应用时压缩动态范围。
当执行一个对数变换时,我们通常期望将导致的压缩值还原为显示的全范围。对8比特而言,在matlab中这样做的最简方法是使用语句
gs = im2nint8(mat2gray(g));
使用函数mat2gray可将值限定在范围[0, 1]内,使用函数im2uint8可将值限定在范围[0, 255]内。
图3.4(a)所示的函数称为对比度拉伸变换函数,因为该函数可将输入值低于m的灰度级压缩为输出图像中较暗灰度级的较窄范围内;类似,该函数可以将输入值高于m的灰度级压缩为输出图像中较亮灰度级的较窄范围内。输出的是一幅具有高对比度的图像。实际上,在图3.4(b)所示的限制条件下,输出值是一幅二值图像。这种限制函数称为阈值函数,它是图像分割的一种有效工具。使用本节开头介绍的表示法,图3.4(a)所示的函数的形式为
其中,r表示输入图像的亮度,s是输出图像中的相应亮度值,E控制该函数的斜率。在Matlab中,该式由如下语句对整幅图像完成操作:
g = 1./(1 + (m./ (double(f) + eps)) .^E)
注意,使用eps可以避免f出现0值时的一处现象。由于T(r)的限制值为1,所以在执行此类变换时,输出值也被缩放在范围[0, 1]内。图3.4(a)所示的曲线形状是使用E = 20时获得的。
例3.2 使用对数变换减小动态范围
>> g = im2uint8(mat2gray(log(1 + double(f))));
>> imshow(g)
|
3.2.3 亮度变换的一些实用M函数
3.3 直方图处理与函数绘图
直方图表示某一个灰度级所出现的概率,只跟灰度值有关。
3.3.1 生成并绘制图像的直方图
一幅数字图像在范围[0, G]内总共有L个灰度级,其直方图定义为离散函数
h(rk) = nk
其中,rk是区间[0, G]内的第k级亮度,nk是灰度级为rk的图像中的象素数。对于uint8类图像,G的值为255;对于uint16类图像,G的值为65535;对于double类图像,G的值为1.0.记住,MATLAB的索引不能为0,故r1相当于灰度级0,r2相当于灰度级1,如此等等,rL相当于灰度级G。其中uint8类图像或uint16类图像中G= L -1.
通常,我们会用到归一化直方图
在处理图像直方图的工具箱中,核心函数是imhist(f, h)
其中,f为输入图像,h为其直方图h(rk),b是用于形成直方图的“收集箱”的个数(即灰度级的个数)。若b未包含在此变量中,则其默认值为256。使用表达式
p = imhist(f, b) / numel(f)
就可以简单地获得归一化直方图。函数numel(f)给出数组f中的元素个数。
例3.4 计算并绘制图像的直方图
考虑例3.1中的第一个图f。绘制其直方图的最简单的方法是使用imhist
>> f = imread('Fig0303(a)(breast).tif');
>> imhist(f)
|
直方图通常利用条形图来绘制。为达到此目的,我们使用函数
bar(horz, v, width)
其中,v是一个行向量,它包含将被绘制的点;horz是一个与v有着相同维数的向量,它包含水平标度值的增量;widdth是一个值在0和1之间的数。若省略horz,则水平轴会从0至length(v)等分为若干个单位。当width的值为1时,竖条较明显;当width为0时,竖条是简单的垂直线,width的默认值为0.8
>> f = imread('Fig0303(a)(breast).tif');
>> imhist(f)
>> h = imhist(f);
>> h1 = h(1:10:256);
>> horz = 1:10:256;
>> bar(horz, h1)
>> axis([0 255 0 15000])
>> set(gca, 'xtick', 0:50:255)
>> set(gca, 'ytick', 0:2000:15000)
|
3.3.2 直方图均衡化
假设灰度级为归一化至范围[0, 1]内的连续量,并令p_r(r)表示某给定图像中的灰度级的概率密度函数(PDF),其下标用来区分输入图像和输出图像的PDF。假设我们队输入灰度级执行如下变化,得到(处理后的)输出灰度级s:
换言之,前述变换生成一幅图像,该图像的灰度级较为均衡化,且覆盖了整个范围[0, 1]。灰度级均衡化处理的最终结果是一幅扩展了动态范围的图像,它具有较高的对比度。注意,该变换只不过是一个累积分布函数(CDF)
基本思想是把原始图的直方图变换为均与分布的形式,这样就增加了象素灰度值的动态范围从而达到增强图象整体对比度的效果。
点处理增强函数t = EH(s)需要满足两个条件:
(1) EH(s)在0 <= S <= L-1范围内是1个单值单增函数;
(2)s和t的值域相同
累积分布函数
直方图均衡化的优缺点
优点:
自动增强整个图象的对比度。
缺点:
具体效果不易控制,处理的结果总是得到全局均衡化的直方图
在Matlab中,直方图均衡化的实现由工具箱中的函数histeq实现,该函数的语法为
g = histeq(f, nlev)
式中,f为输入图像,nlev是为输出图像指定的灰度级数。若nlev等于L(输入图像中可能的灰度级总数),则histeq直接执行变换函数。若小于L,则划分灰度级,以便能够得到较为平坦的直方图。与函数imhist不同,histeq中的默认值为nlev = 64.一般来说,我们将nlev赋值为弧度及的最大可能数量(通常为256),因为这样能够得到较为准确的结果。
例3.5 直方图均衡化
>> f = imread('Fig0308(a)(pollen).tif');
>> figure, imshow(f)
>> figure, imhist(f)
>> ylim('auto')
>> g = histeq(f, 256);
>> figure, imshow(g)
>> figure, imhist(g)
>> ylim('auto')
|
如先前所提到的那样,变换函数仅仅是归一化直方图取值的累加。我们可以使用函数cumsum来实现变换功能。
>> hnorm = imhist(f)./numel(f);
>> cdf = cumsum(hnorm);
>> x = linspace(0, 1, 256);
>> plot(x, cdf)
>> axis([0 1 0 1.1])
>> set(gca, 'xtick', 0:.2:1)
>> set(gca, 'ytick', 0: .2: 1)
>> xlabel('Input intensity values')
>> ylabel('Output intensity values')
|
这幅图就是我们计算出来的变换函数。
3.3.3 直方图匹配(规定化)
实际中有时需要变换直方图,使之成为某个特定的形状,从而有选择地增强某个灰度值方位内的对比度。这是可以用比较灵活的直方图规定化方法。一般来说可以获得更好的效果。
直方图规定化
直方图规定化方法主要有3个步骤(设M和N分别为原始图和规定图中的灰度级数,且只考虑N<=M的情况):
(1)对原始图像进行灰度均衡化
(2)规定需要的直方图,并计算能使规定的直方
图均衡化的变换:
(3)将第一个步骤得到的变换翻转过来,即将原始直方图对应映射到规定的直方图
映射规则
在Matlab工具箱中,使用函数histeq的如下形式实现直方图匹配:
g = histeq(f, hspec)
其中,f为输入图像,hspec为指定的直方图(一个由指定值构成的行向量),g为输出。histeq的一个特性是在length(hspec)远小于图像f中的灰度级数时,图像g的直方图通常会较好的匹配hspec。
例3.6 直方图匹配
首先,我们采用直方图均衡化进行图像处理
>> f = imread('Fig0310(a)(Moon Phobos).tif');
>> imshow(f)
>> figure,imhist(f)
>> f1 = histeq(f);
>> figure, imshow(f1)
>> figure, imhist(f1)
|
可以看出,效果不是很好,反而由于灰度级的移动出现了褪色现象。灰度级移动的原因是原始直方图中的暗色分量过于集中在0附近。从而,由该直方图得到的累积变换函数非常陡,因此才把灰度级低端过于集中的象素映射到了灰度级的高端。
一种补偿这种现象的方法是使用直方图匹配,期望的直方图在灰度级低端应有较小的集中范围,并能够保留源图像的直方图的大体形状。由原始图像的直方图可知,直方图主要有两个峰值,较大的峰值出现在原点处,较小的峰值则出现在灰度级的高端。我们可以使用多峰高斯函数来模拟这种类型的直方图。下列M函数计算一个已归一化到单位区域的双峰值高斯函数,以便可将它用作一个指定的直方图。
function p = twomodegauss(m1, sig1, m2, sig2, A1, A2, k)
%TWOMODEGAUSS Generates a two-mode Gaussian function.
%
%
%
%
%
%
%
%
%
%
%
%
%
c1 = A1 * (1 / ((2 * pi) ^ 0.5) * sig1);
k1 = 2 * (sig1 ^ 2);
c2 = A2 * (1 / ((2 * pi) ^ 0.5) * sig2);
k2 = 2 * (sig2 ^ 2);
z
p = k + c1 * exp(-((z - m1) .^ 2) ./ k1) + ...
p = p ./ sum(p(:));
|
下列交互式函数从键盘读取输入信息,并绘制最终的高斯函数。
function p = manualhist
%MANUALHIST Generates a two-mode histogram interactively.
%
%
%
%
%
%
%
%
%
%
%
%
%
%
%
%
% Initialize.
repeats = true;
quitnow = 'x';
% Compute a default histogram in case the user quits before
% estimating at least one histogram.
p = twomodegauss(0.15, 0.05, 0.75, 0.05, 1, 0.07, 0.002);
% Cycle until an x is input.
while repeats
end
|
使用方法如下
>> p = manualhist
Enter m1, sig1, m2, sig2, A1, A2, k OR x to quit:0.15 0.05 0.75 0.05 1 0.07 0.002
Enter m1, sig1, m2, sig2, A1, A2, k OR x to quit:x
>> g = histeq(f, p);
>> figure, imshow(g)
>> figure, imhist(g)
|