直方图均衡与匹配

直方图均衡与匹配

一、直方图均衡

1.算法描述

直方图均衡目的是将一张灰度级数较集中、范围小的图片转化成一张灰度级数较分散、范围广的图片,增强图像对比度。当图像直方图完全均匀分布时,图像对比度是最大的。

直方图均衡的变换函数f(x)需要满足条件:

1.f(x)在0<=x<=L−1上单调递增,其中L表示灰度级

2.f(x)的范围是0至L-1

有一个重要的函数,能够满足上面的条件: y=f(x)=(L−1)∫px(t)dt

根据上述公式,这里我用到的主要算法思路如下:

1.先统计所用像素中0到255灰度级上的像素的数量

2.然后求出概率密度函数

3.再用概率密度函数求出累积分布函数

4.将累积分布函数值域转换到0至255的映射像素表

5.然后令原图像每个像素根据原先的像素值查表找到映射的像素值。

这样,我们就建立了一个直方图均衡的映射函数了。

2.Matlab代码

函数Equalization:

Equalization.m

function eql = Equalization(img)
    [height,width] = size(img);

    %Pixel counter
    Pixel_Num = zeros(1,256);
    for i = 1:height
        for j = 1: width
            Pixel_Num(img(i,j) + 1) = Pixel_Num(img(i,j) + 1) + 1;
        end
    end

    %Pixel PDF
    Pixel_PDF = Pixel_Num / (height * width);

    %Pixel CDF
    Pixel_CDF = zeros(1,256);
    Pixel_CDF(1) = Pixel_PDF(1);
    for i = 2:256
        Pixel_CDF(i) = Pixel_CDF(i - 1) + Pixel_PDF(i);
    end

    %255 * Pixel_CDF 
    Pixel_CDF = 255 * Pixel_CDF;

    %gray levels map
    for i = 1:height
        for j = 1: width
            img(i,j) = Pixel_CDF(img(i,j));
        end
    end
    eql = img;

二、直方图匹配

1.算法描述

直方图匹配,又称直方图规定化,即变换原图的直方图为规定的某种形式的直方图,从而使两幅图像具有类似的色调和反差。对于一些特殊的案例,直方图均衡化得到均匀直方图并不能达到效果,这类情况下,往往需要指定输出图像直方图的具体分布,这就需要用到直方图匹配。

要匹配图像A和图像C的直方图,通用的算法思想是,将图像A转化成均衡化图像B,也将图像C转化成均衡化图像B,然后再利用图像B到图像C的反函数,让图像A沿A->B->C这样的路线转化成匹配了直方图后的图像,和图像C有了一样的色调。

这里我用到的算法思路如下:

1.先将需要处理的图像A作直方图均衡,得到累计分布函数CDF_From

2.再将需要匹配的图像B作直方图均衡,得到累计分布函数CDF_To

3.建立一个映射表,对于每个灰度级,获得它在CDF_From上的一点上到CDF_To任意点的距离最小的位置,然后写入映射表

4.令原图像每个像素根据原先的像素值查表找到映射后新的像素值。

这样,我们就建立了一个直方图匹配的映射函数了。

这里还是会用到上面的直方图均衡,不过由于返回值不是我所需要的,并且我在网上找到了更简洁的累计分布函数的写法,所以就不调用我的Equalization函数了。

2.Matlab代码

函数Matching:

Matching.m

function match = Matching(Img_From, Img_To)
    Hist_From = imhist(Img_From); 
    Hist_To = imhist(Img_To);
    CDF_From = cumsum(Hist_From) / numel(Img_From);
    CDF_To  = cumsum(Hist_To) / numel(Img_To);

    index = zeros(1,256);
    for i = 1 : 256
        [~,index(i)] = min(abs(CDF_From(i) - CDF_To));
    end

    [height,width] = size(Img_From);
    for i = 1 : height
        for j = 1 : width
            Img_From(i, j) = index(Img_From(i, j) + 1) - 1;
        end
    end
    match = uint8(Img_From);

三、图像及其直方图

1.脚本main.m

这是调用了上述Equalization函数和Matching函数的脚本,可在matlab上直接运行,类似C语言里的主函数。运行后就会得到下面结果里的两个图像。

%Histogram Equalization
img = imread('river.jpg');
set(figure, 'name', 'Equalization');
subplot(2,2,1);
imshow(histeq(img));%histeq Image
title('Histeq Image');
subplot(2,2,2);
imhist(histeq(img));%histeq histogrm
subplot(2,2,3);
equal = Equalization(img);
imshow(equal);%Equalized Image
title('Equalized Image');
subplot(2,2,4);
imhist(equal);%Equalized Histogram

%Histogram Matching
Img_From = imread('EightAM.png');
Img_To = imread('LENA.png');
set(figure, 'name', 'Matching');
subplot(3,2,1);
imshow(Img_From);%Image To Be Matched
title('Raw Image');
subplot(3,2,2);
imhist(Img_From);%Histogrm To Be Matched
title('Raw Histogrm');
subplot(3,2,3);
imshow(Img_To);%Dest Image
title('Dest Image');
subplot(3,2,4);
imhist(Img_To);%Dest Histogram
title('Dest Histogrm');
subplot(3,2,5);
match = Matching(Img_From, Img_To);
imshow(match);%Matched Image
title('Matched Image');
subplot(3,2,6);
imhist(match);%Matched Histogram
title('Matched Histogrm');

2.处理结果

直方图均衡效果图对比(使用matlab函数histeq和使用自己编写的Equalization函数的对比):

这里写图片描述

直方图匹配效果图对比(使用自己编写的Matching函数前后以及匹配的LENA.png图像及直方图的对比):

这里写图片描述

猜你喜欢

转载自blog.csdn.net/jacknights/article/details/79438752