两个图像的直方图匹配,不使用histeq

时间:2014-11-05 18:00:31

标签: image matlab image-processing

众所周知,MATLAB中的histeq可以执行直方图匹配,以便将图像的直方图转换为另一个直方图。我试图在不使用histeq的情况下执行相同的操作。我知道你需要计算两张图像之间的CDF,但我不知道下一步该做什么。我该怎么办?

1 个答案:

答案 0 :(得分:6)

直方图匹配涉及转换一个图像的直方图,使其看起来像另一个。基本原则是分别计算每个图像的直方图,然后计算它们的离散cumulative distribution functions (CDFs)。我们将第一个图像的CDF表示为,而第二个图像的CDF是。因此,表示第一张图片的强度x的CDF值。

计算每个图像的CDF后,您需要计算一个映射,该映射可以转换第一个图像中的一个强度,使其与第二个图像的强度分布一致。要做到这一点,对于第一张图片中的每个强度 - 让我们调用此来自假设8位图像的[0,255] - 我们必须找到强度在第二个图像中(也在[0,255]的范围内),使得:

可能存在我们不能完全相等的情况,因此您需要做的是找到和{{0}之间的最小绝对差异}}。换句话说,对于映射M,对于的每个条目,我们必须找到强度,以便:{/ p>

您将对所有256个值执行此操作,我们将生成映射。找到此映射后,您只需在第一个图像上应用此映射,使其看起来像第二个图像的强度分布。粗略(也许效率低下)的算法看起来像这样。让im1成为第一个图像(uint8类型),而im2是第二个图像(uint8类型):

M = zeros(256,1,'uint8'); %// Store mapping - Cast to uint8 to respect data type
hist1 = imhist(im1); %// Compute histograms
hist2 = imhist(im2);
cdf1 = cumsum(hist1) / numel(im1); %// Compute CDFs
cdf2 = cumsum(hist2) / numel(im2);

%// Compute the mapping
for idx = 1 : 256
    [~,ind] = min(abs(cdf1(idx) - cdf2));
    M(idx) = ind-1;
end

%// Now apply the mapping to get first image to make
%// the image look like the distribution of the second image
out = M(double(im1)+1);

out应该包含匹配的图像,它会转换第一张图像的强度分布以匹配第二张图像的强度分布。特别注意out声明。 im1的强度范围跨越[0,255],但MATLAB对数组的索引从 1 开始。因此,我们需要为im1的每个值添加1,以便我们可以正确地索引到M以生成输出。但是,im1的类型为uint8,如果您尝试超过255,MATLAB会使值饱和。因此,为了确保达到256,我们必须转换为超过8的数据类型比特精度。我决定使用double,然后当我们为im1中的每个值添加1时,我们将介于1到256之间,因此我们可以正确地索引到M。另外,当我找到最小化差异的位置时,我也必须减去1,因为数据类型跨越[0,255]