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

abb*_*udi 4 matlab image image-processing

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

ray*_*ica 7

直方图匹配涉及转换一个图像的直方图,使其看起来像另一个.基本原理是分别计算每个图像的直方图,然后计算它们的离散累积分布函数(CDF).我们将第一张图像的CDF表示为 而第二张图像的CDF是 .因此,将表示CDF值x对于第一图像的强度是多少.

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

可能存在我们不会完全相等的情况,因此您需要做的是找到最小的绝对差异.换句话说,对于映射M,对于每个条目,我们必须找到一个强度 这样:

您将对所有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);
Run Code Online (Sandbox Code Playgroud)

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