将图像的直方图与特定曲线匹配

时间:2017-06-20 17:07:58

标签: image matlab image-processing histogram

我试图将图像的直方图形成抛物线。我遵循Digital Image Processing Book by Gonzalez and Woods中指定的直方图匹配技术。在此之后,我得到了以下结果。

Original Histogram & Equalized Histogram Transformed Histogram & Specified Histogram

但我认为变换后的直方图有点像指定的直方图。我在这里做错了还是应该是这样的?

我还包括我用来获得这些结果的MATLAB脚本。

clear
clc

inputImage = rgb2gray(imread('office_2.jpg'));

[counts, bins] = imhist(inputImage);

% Highest intensity level from bin count
intensityLevel = max(bins);

subplot(2, 2, 1);
imhist(inputImage), title('Original Histogram');
pixelCount = numel(inputImage);

% Histogram Equalization
normalizedCounts = counts/sum(counts);

subplot(2, 2, 2);

newIntensities = cumsum(normalizedCounts);

% Maps each value of inputImage to corresponding indexed value of
% newIntensities
eqImage = newIntensities(inputImage+1);

eqImage = uint8(eqImage*intensityLevel);

imhist(eqImage), title('Equalized Histogram')

subplot(2, 2, 3), imshow(inputImage), title('Input Image')
subplot(2, 2, 4), imshow(eqImage), title('Equalized Image')

% Histogram Matching
X = 0:255;
Y = ((X-127).^2);
Y = reshape(Y,[],1);
normalizedY = Y/sum(Y);
summedNormY = cumsum(normalizedY);
transformedIntensities = round(255*summedNormY);
specifiedIntensities = newIntensities*intensityLevel;

for i = 1:length(transformedIntensities)
    [x, specifiedIntensities(i)] = min(abs(transformedIntensities-specifiedIntensities(i)));
end

specifiedIntensities = specifiedIntensities - 1;
transformedImage = uint8(specifiedIntensities(inputImage+1));

figure
subplot(1, 3, 2), imhist(transformedImage), title('Transformed Histogram')
subplot(1, 3, 1), imshow(transformedImage), title('Transformed Image')
subplot(1, 3, 3), bar(normalizedY), title('Normalized Specified Hist.')

1 个答案:

答案 0 :(得分:1)

代码确实是正确的。请记住,通过直方图匹配,您将匹配两个图像之间的累积分布函数定义。这与实际概率质量函数(即直方图)的外观无关,因为可以存在多于一个满足累积分布函数的直方图。作为并行,请记住累积分布函数或多或少地找到概率分布函数下面的总面积。有多条曲线会产生相同的区域,因此无法保证直方图的形状与您指定的形状相同。例如,假设曲线下的总面积为6,这可能是由尺寸为2 x 3,尺寸为6 x 1等的矩形产生的。请注意,累积分布函数将匹配,因此感知,增强图像应遵循您指定的直方图。

要验证这是否正确,请绘制变换图像的累积分布以及抛物线规范,您将看到它们或多或少匹配:

H = imhist(transformedImage);
H = cumsum(H) / numel(transformedImage);
plot(0:255, H, 0:255, summedNormY);
legend('Transformed Image', 'Parabola');

前两行代码使用抛物线规范找到变换图像的直方图,然后计算累积分布,确保其标准化。我们绘制了这个以及抛物线的累积分布。

我们得到:

enter image description here

作为比较和验证的一种方法,您可以使用histeq执行直方图规范并指定所需的抛物线直方图,并查看结果的累积分布:

transformedImage = histeq(inputImage, normalizedY);
H = imhist(inputImage);
H = cumsum(H) / numel(inputImage);

您会看到histeq给出的累积分布与您的代码所给出的匹配。另外,如果您在此处参考我之前的帖子:Histogram matching of two Images without using histeq,您会看到您的实施与我的匹配。