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