当我们在MATLAB中使用histeq
函数时,请解释一下图像会发生什么?数学解释会非常有用。
答案 0 :(得分:14)
直方图均衡旨在展平您的图像直方图。基本上,它将图像建模为概率密度函数(或者更简单地说,直方图,您可以将每个条目标准化为图像中的像素总数),并尝试确保像素采用特定强度的概率是等概率(概率相同)。
直方图均衡背后的前提是对比度差的图像。看起来像是太暗的图像,或者如果它们过于褪色,或者它们太亮,则适合应用直方图均衡的图像。如果绘制直方图,则像素的范围限制在非常窄的范围内。通过直方图均衡,直方图将因此变平并为您提供更好的对比度图像。直方图的效果是它会拉伸直方图的动态范围。
就数学定义而言,我不会厌倦你的细节,我很乐意在这里做一些LaTeX,但它并不受支持。因此,我将您推荐到此链接,该链接更详细地解释了它:http://www.math.uci.edu/icamp/courses/math77c/demos/hist_eq.pdf
但是,执行直方图均衡的最终方程基本上是1对1映射。对于图像中的每个像素,您可以提取其强度,然后通过此函数运行它。然后它会为您提供输出图像中的输出强度。
假设p_i
是您在图像中遇到强度为i
的像素的概率(取像素强度i
的直方图箱数并除以总数图像中的像素)。鉴于您的图片中有L
个强度,在i
的强度下,此位置的输出强度取决于:
g_i = floor( (L-1) * sum_{n=0}^{i} p_i )
您将所有概率从像素强度0,然后是1,然后是2,一直到强度i
。这通常被称为累积分布函数。
MATLAB基本上使用这种方法执行直方图均衡。但是,如果你想自己实现它,它实际上非常简单。假设您有一个无符号8位整数类型的输入图像im
。
function [out] = hist_eq(im, L)
if (~exist(L, 'var'))
L = 256;
end
h = imhist(im) / numel(im);
cdf = cumsum(h);
out = (L-1)*cdf(double(im)+1);
out = uint8(out);
此函数接收假定为无符号8位整数的图像。您可以选择指定输出的级别数。通常,对于8位图像,L = 256
,因此如果省略第二个参数,则{I}}将被假设为此类。第一行计算概率。下一行计算累积分布函数(CDF)。计算输入/输出后的下两行使用直方图均衡,然后转换回无符号的8位整数。请注意,L
投射会隐式执行 floor 操作。您需要注意我们在访问CDF时必须添加偏移1 。原因是因为MATLAB开始索引为1,而图像的强度从0开始。
MATLAB命令uint8
几乎完全相同,只是如果你调用histeq
,它会假设你的图像中有32个强度。因此,您可以通过指定一个额外的参数来覆盖histeq(im)
函数,该参数指定在图像中看到的强度值的数量,就像我们上面所做的那样。因此,你会histeq
。在MATLAB中调用它,并使用我上面写的函数应该给你相同的结果。
作为一项练习,让我们使用一个名为histeq(im, 256);
的MATLAB发行版中的图像。我们还要显示其直方图。
pout.tif
如您所见,图像的对比度较差,因为大多数强度值都适合窄范围。直方图均衡化将使图像变平并因此增加图像的对比度。因此,尝试这样做:
im = imread('pout.tif');
figure;
subplot(2,1,1);
imshow(im);
subplot(2,1,2);
imhist(im);
这就是我们得到的:
正如您所看到的,对比度更好。较暗的像素倾向于向较暗的一端移动,而较亮的像素被推向较轻的一端。我认为成功的结果!请记住,当您尝试进行直方图均衡时,并非所有图像都能为您提供良好的结果。图像处理主要是一个反复试验的事情,因此你将不同技术的混合物放在一起,直到你得到一个好的结果。
这应该有希望让你开始。祝你好运!