【图像处理】直方图灰度级变换,伽马变换,直方图均衡化,多次均衡化有无变化结果,matlab实现

1 图像直方图灰度级变换

        图像直方图,就是图像中各个灰度级出现的频率分布图,可以通过对其改变实现图像整体or局部的亮度、对比度调节,从而实现改善人眼的图片信息接收(tips:不会增加图片本身的信息量哦,甚至会削减一部分图片信息)

        于此同时,我们在学习了“GLT”这一概念,即"Gray Level Transformation" ,就是简单而有效的图像增强技术——灰度级变换

        而灰度级变换函数可以有多种形式,包括线性变换、对数变换、伽马变换等,每种变换都有其特定的应用场景和效果,如何选择取决于原始图像的特性以及期望达到的图像增强效果。

        下面就伽马变换和均衡化进行简要展示。

1.1 伽马变换

伽马变换也叫幂律变换,使直方图在某些区域拉伸而在其他区域压缩,同时改变图像的对比度。

γ = 0.7 时:

γ = 0.3 时:

(原图如下)

为了方便更改图片和γ值,将这一变换打包成函数

实现以上功能的代码如下:

I = imread('1.jpg');
gamma = 0.1;    %%调节gamma值
I_gamma_rescaled = gammaTransform(I, gamma);

%imwrite(I_gamma_rescaled, './2.jpg');

histogram_original = calculateHistogram(rgb2gray(I));
histogram_gamma = calculateHistogram(I_gamma_rescaled);

subplot(2,2,1);
imshow(rgb2gray(I));
title('Original Image');

%显示原图及直方图
subplot(2,2,1);
imshow(rgb2gray(I));
title('原图');

subplot(2,2,2);
bar(0:255, histogram_original);
title('原图直方图');
xlabel('灰度级');
ylabel('频次');

subplot(2,2,3);
imshow(I_gamma_rescaled);
% imwrite(I_gamma_rescaled, 'D:/DIP LESSON/exp_1/2.png');
title('伽马变换后图片');

subplot(2,2,4);
bar(0:255, histogram_gamma);
title('伽马变换后直方图');
xlabel('灰度级');
ylabel('频次');

%gamma变换函数
function I_gamma_rescaled = gammaTransform(I, gamma)
    if size(I, 3) == 3
        I_gray = rgb2gray(I);
    else
        I_gray = I;
    end
    %防溢出操作
    I_double = double(I_gray) / 255;
    I_gamma = I_double .^ gamma;
    I_gamma_rescaled = uint8(I_gamma * 255);
end

%直方图生成
function histogram = calculateHistogram(I)
    histogram = zeros(1, 256);
    for i = 1:size(I, 1)
        for j = 1:size(I, 2)
            grayLevel = I(i, j);
            histogram(grayLevel + 1) = histogram(grayLevel + 1) + 1;
        end
    end
end

1.2 直方图均衡化

        图像的直方图均衡化是一种增强图像对比度的方法,通过调整图像的直方图使其分布更加均匀,适用于背景和前景都太亮或太暗的图像。

        直方图均衡化的步骤可以分为以下几个主要部分:

1.2.1 计算原始图像的直方图

        对图像中的每个像素进行遍历,统计每个灰度级出现的次数。

1.2.2 计算累积分布函数(CDF)

        累积分布函数(CDF)是直方图的一个累积版本,表示每个灰度级及其以下所有灰度级的总频率。

        CDF的计算基于原始直方图,通过对直方图的每个值进行累加得到。CDF的第一个值是直方图的第一个值,CDF的第二个值是直方图的前两个值的和,以此类推,直到处理完所有灰度级。

1.2.3 使用CDF进行直方图均衡化

        直方图均衡化的核心步骤是使用CDF将原始图像映射到新的灰度级,以此来增强图像的对比度。

        对于图像中的每个像素,使用其灰度值作为索引查找CDF中对应的值。

        CDF值表示该灰度级(及更低灰度级)的相对频率。

1.2.4 映射回 [0, 255] 范围并显示结果

        均衡化后的图像可能需要进行一些后处理,以确保所有的灰度值都在合法的范围内(即0到255之间)。

        最后,可以显示均衡化后的图像及其直方图,以及与原始图像和直方图的对比,以直观地看到均衡化的效果。

        将输出的图片当做输入进行一次迭代,得到:

I = imread('1.jpg');
I_eq = histogramEqualization(I);
imwrite(I_eq, '2.jpg');

%生成直方图的函数,前文已说明
function histogram = calculateHistogram(I)
    histogram = zeros(1, 256);
    for i = 1:size(I, 1)
        for j = 1:size(I, 2)
            grayLevel = I(i, j);
            histogram(grayLevel + 1) = histogram(grayLevel + 1) + 1;
        end
    end
end

%均衡化的计算
function I_eq = histogramEqualization(I)
    if size(I, 3) == 3
        I = rgb2gray(I);
    end
    I = double(I);
    histogram = calculateHistogram(I);
    
    %最关键的一步,可以求得一个累计分布函数的数组
    cdf = cumsum(histogram) / numel(I);

    I_eq = zeros(size(I));
    for i = 1:size(I, 1)
        for j = 1:size(I, 2)
            I_eq(i, j) = cdf(I(i, j) + 1);
        end
    end
    
    I_eq = uint8(I_eq * 255);
    
    histogram_eq = calculateHistogram(I_eq);
    
    %显示累积分布函数、原图和均衡化后的图及各自的直方图
    figure;
    subplot(3, 2, 1);
    bar(0:255, histogram, 'FaceColor', [0, 0, 1]);
    title('原始直方图');
    xlim([0 255]);
    
    subplot(3, 2, 2);
    plot(0:255, cdf, 'LineWidth', 2, 'Color', [1, 0, 0]);
    title('累积分布函数');
    xlim([0 255]);
    
    subplot(3, 2, 3);
    imshow(uint8(I));
    title('原始图像');
    
    subplot(3, 2, 4);
    imshow(I_eq);
    title('均衡化后的图像');
    
    % 显示均衡化后图像的直方图
    subplot(3, 2, [5,6]);
    bar(0:255, histogram_eq, 'FaceColor', [0, 0, 1]);
    title('均衡化后的直方图');
    xlim([0 255]);
end

        经对比稍有差距(灰度级15左右的空缺、以及100~250之间的部分空缺等),由于显示布图有些不易对比,将显示顺序稍作改变,可以更明显地观察到区别,以及分布函数并不是直线。

(第一次迭代)

(第二次迭代)

(第三次迭代)

(第四次迭代)

(第五次迭代)

       进行了五次迭代以后,发现了几个问题:

发现问题

  1. 每次将带有灰度级缺口的输出当做输入时,灰度级就不再有缺口
  2. 图片噪点越来越多,有些边界逐渐模糊
  3. 分布函数大致样子趋于稳定,是否相同还没有验证

可能原因

  1. 转成图片输出后,再次读出灰度值时,由于储存精度等问题,会自动补全缺失灰度级
  2. 在均衡化的过程中,细节被更多展现的同时,噪声也不断被放大
  3. 后面接近均匀图像了,每次补齐灰度级的方式相似导致函数样子相近

        此刻才意识到,可能将输出的图片进行迭代会有一些格式转换、储存读取时的“瑕疵”存在,所以直接将直方图进行迭代,代码如下:

figure;
    for n = 1:10
        I_eq = histogramEqualization(I_eq);
        histogram_eq = calculateHistogram(I_eq);
        
        subplot(2, 5, n);
        bar(0:255, histogram_eq, 'FaceColor', [0, 0, 1]);
        title(['迭代 ' num2str(n) ' 次后的直方图']);
        xlim([0 255]);
    end

        最终得到:


        可以明显看到图像的一致性

        证实完毕,理想情况下多次均衡化的结果的确是趋于稳定的

        同时暴露了均衡化的一部分问题:

        在图像某些对比度较低的区域,均衡化后这些细微的灰度级差异会被过度放大,某些灰度级可能会被映射到相同的新灰度级(合并),而某些原本相同或相近的灰度级可能会被映射到不同的灰度级(分离),这种分分合合可能会导致图像细节的丢失或导致噪声变得更加明显。

        为何不能完全均匀?

直方图均衡化的效果很大程度上依赖于原始图像的直方图分布。如果原始图像的某些灰度级非常密集,而其他灰度级则几乎没有像素,那么即使经过均衡化,最终的直方图也可能无法达到完全均匀,仅可以改善直方图的整体分布。

1.3* 直方图均衡化的进一步改进

        由于直方图均衡化是对整个图像的统一处理,有时反而会对比度调节过量,使得一些局部细节不能更好地展现。于是有人提出了一种适应直方图均衡化方法(AHE,Adaptive Histogram Equalization),具体做法为把图像划分为大小相等的一些矩形网格,对这些分出图块分别进行直方图均衡化。这种“多走一步”的更全面周到的处理方法使得直方图均衡化被更好地利用,也让图片的细节尽可能地被人们欣赏到。

        但这也可能使得部分噪音被放大,于是又有人提出了 CLAHE(Contrast Limited Adaptive histgram equalization),对每个图块都使用对比度限幅。(如图所示)

(此图为网图,侵删)

望建议与补充内容,及时更改,一起完善!!!【抱拳】【抱拳】【抱拳】

第一次写帖子,希望能对您有帮助~~如果有什么意见建议欢迎交流~~

  • 33
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值