Image 不使用histeq的两幅图像直方图匹配

Image 不使用histeq的两幅图像直方图匹配,image,matlab,image-processing,Image,Matlab,Image Processing,众所周知,MATLAB中的histeq可以执行直方图匹配,从而将图像的直方图转换为另一个直方图。我试图在不使用histeq的情况下执行相同的操作。我知道您需要计算两个图像之间的CDF,但我不确定下一步要做什么。我该怎么办?直方图匹配涉及到变换一幅图像的直方图,使其看起来像另一幅图像。基本原理是分别计算每个图像的直方图,然后计算其离散值。让我们将第一个图像的CDF表示为,而第二个图像的CDF表示为。因此,将表示第一幅图像的强度x的CDF值 计算每个图像的CDF后,需要计算将第一个图像的一个强度变换

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

直方图匹配涉及到变换一幅图像的直方图,使其看起来像另一幅图像。基本原理是分别计算每个图像的直方图,然后计算其离散值。让我们将第一个图像的CDF表示为,而第二个图像的CDF表示为。因此,将表示第一幅图像的强度
x
的CDF值

计算每个图像的CDF后,需要计算将第一个图像的一个强度变换为与第二个图像的强度分布一致的贴图。为此,对于第一幅图像中的每个强度(假设为8位图像,我们将其称为
[0255]
),我们必须在第二幅图像中找到一个强度(也在
[0255]
范围内),以便:

在某些情况下,我们可能无法得到确切的等式,因此您需要做的是找到和之间最小的绝对差。换句话说,对于映射
M
,对于的每个条目,我们必须找到一个强度,以便:

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


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

我明白了。nut我想要直方图匹配两幅图像我写了一个答案。你需要进一步的帮助吗?需要。我认为cdf在您的代码中是错误的。CDF是概率,你应该使用它:probc=cumsum(freq)/numel(GIm);除了规范CDF之外,代码是正确的。这是我忘记做的一件事,谢谢你的更正。请查看此链接:@abbasmahmudi除了规范化
cumsum
结果之外,代码是正确的。方框图证明了这一点,但感谢您的链接@abbasmahmudi-不客气。我忘记了通过像素总数进行规格化以正确计算CDF。谢谢你的更正,祝你好运!对分别均衡每个位置。这是通常所做的,尽管并不理想。@mLstudent33:这是
numel
,L以L结尾。它计算矩阵中元素的数量:
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);