图像处理 增强对比度方法_传统图像处理方法知道哪些,图像对比度增强说一下 - CSDN
  • 图像对比度增强算法

    2017-04-24 09:11:45
    论述了几种基于灰度直方图的图像对比度增强算法。

    一、全局对比度增强1

    1. 直方图均衡化 Histogram Equalization

    a. 基本思想

    对于图像中的灰度点做映射,使得整体图像的灰度大致符合均匀分布。增强图像的对比度。
    - 对于灰度值连续的情况,使用灰度的累积分布函数CDF做转换函数,可以使得输出图像的灰度符合均匀分布。
    - 对于灰度值不连续的情况,存在舍入误差,得到的灰度分布大致符合均匀分布。
    - 直观地理解,如果某一个灰度范围(如200-201)的像素点很少,那么它的概率密度值就会很小,所以CDF在200-201附近的增长变化就会很小;反之,如果某一个灰度范围(如100-101)的像素点很多,CDF在100-101附近的增长变化会很大。总体来看,以灰度为横轴,CDF为纵轴画曲线。这种向上凸的曲线,很像gamma变换: s=crγγ<1的情形。将灰度集中的部分拉伸,而将灰度不集中的部分压缩,达到提高对比度的效果。
    - 直方图均衡可以看做自适应的gamma变换或者分段变换。前者的优势在于,不需要指定任何参数,所有运算都是基于图像本身的。

    b. 算法
    1. 根据图像灰度计算灰度概率密度函数PDF
    2. 计算累积概率分布函数CDF
    3. CDF归一化到原图灰度取值范围,如[0,255]。
    4. 之后CDF四舍五入取整,得到灰度转换函数sk=T(rk)
    5. CDF作为转换函数,将灰度为rk的点转换为sk灰度
    c. matlab实验

    代码2

    %% 直方图均衡
    clear all;clc;close all;
    ImgFile='E:\图像处理\冈萨雷斯图片库\DIP3E_Original_Images_CH03\Fig0310(b)(washed_out_pollen_image).tif';
    ImgIn=imread(ImgFile);
    ImgHistEq=histeq(ImgIn,256);
    figure;subplot(121);imshow(uint8(ImgIn));title('原图');
    subplot(122);imshow(ImgHistEq);title('全局灰度增强 - 直方图均衡');
    figure;subplot(121);imhist(ImgIn,256);
    axis([0 255 0 1e5]);title('原图的直方图');
    subplot(122);imhist(ImgHistEq,256);axis([0 255 0 1e5]);title('直方图均衡化后的直方图');
    % 自定义直方图均衡
    [counts,x]=imhist(ImgIn,256);
    cum_counts=cumsum(counts);
    cum_counts=uint8(cum_counts/max(cum_counts)*255);% 转化函数
    figure;plot(x,cum_counts);axis([0 255 0 255]);
    xlabel('原图灰度');ylabel('转换后灰度');title('原图CDF转化的灰度映射函数');
    ImgOut=nan(size(ImgIn));
    for i=1:length(x)
        ImgOut(ImgIn==x(i))=cum_counts(i);
    end
    ImgOut=uint8(ImgOut);
    figure;imshow(uint8(ImgOut));title('自定义直方图均衡')
    figure;imhist(ImgOut,256);axis([0 255 0 1e5]);title('自定义直方图均衡的直方图')

    输出:
    原图和均衡化后的图
    图1. 原图和均衡化后的图。均衡后图像对比度明显增强,纹理和边缘更加清晰。

    原图和均衡化后的图的直方图
    图2. 原图和均衡化后的图的直方图。原图灰度分布在很狭窄的区间约[90,140]内。均衡化后灰度较为均匀的分布在整个[0, 255]区间内。

    cdf
    图3. 原图CDF归一化到[0, 255]后作为灰度变换函数。为了方便显示,画成连续曲线。

    自定义均衡的直方图
    图4. 自定义均衡的直方图。和Matlab自带histeq输出基本一致。

    2. 直方图匹配 Histogram Matching

    a. 基本思想

    我的理解:

    对于图像中的灰度点做映射,使得整体图像的灰度大致符合给定的分布。
    想要图像的直方图Hs和期望直方图Hd相同, 那么二者的CDF也是相同的.
    也就是说, 对于某一个灰度x, CDFs(x)=CDFd(x). 所以, 如果CDFs(x)=CDFd(y). 那么我们令x=y.
    也就是将原图的x灰度映射为y灰度. 相当于将图像直方图的横轴做了一个点对点的缩放操作.
    这个缩放操作的结果就是图像直方图向理想直方图靠近.
    在缩放过程中, 如果图像的直方图某一段灰度区间被拉长了, 因为灰度都是整数, 所以直方图的bin会变得稀疏.
    所以,
    最终的直方图匹配的结果就是直方图的bin变得稀疏了. 有的灰度区间没有灰度点.

    • 对于某些图像,灰度分布过于不均衡,例如背景很大且均匀。直接做直方图均衡会把前景“洗白”,效果很差。
    • 直方图匹配需要设定一个直方图分布。不同的图像,此分布可能不同。
    b. 算法
    1. 根据图像计算概率密度分布pr(r)
    2. 根据pr(r)计算累计分布函数sk=T(rk)
    3. 根据给定的目标分布pz(z)计算累计分布函数G(zq)
    4. 对于每一个k,找到一个q,使得G(zq)约等于sk
    5. 将原图中灰度为k的点变为灰度q
    c. Matlab实验
    clear all;clc;close all;
    ImgFile='E:\图像处理\冈萨雷斯图片库\DIP3E_Original_Images_CH03\Fig0323(a)(mars_moon_phobos).tif';
    ImgIn=imread(ImgFile);
    figure;subplot(121);imshow(ImgIn);title('原图')
    subplot(122);imhist(ImgIn);title('原图Hist')
    % histeq
    ImgHistEq=histeq(ImgIn);
    figure;subplot(121);imshow(ImgHistEq);title('Hist EQ');
    subplot(122);imhist(ImgHistEq,256);title('Hist EQ')
    % 根据3.35(a)估计的分布
    x=[0 8 16 180 200 255];
    Y=[0 70000 8000 0 3139 0];
    xi=0:255;
    yi = interp1q(x',Y',xi');
    figure;plot(xi,yi,'.');title('目标 Hist')
    ImgHistMatch = histeq(ImgIn, yi);
    figure;subplot(121);imshow(ImgHistMatch);title('histeq匹配')
    subplot(122);imhist(ImgHistMatch,256);title('histeq匹配直方图')

    输出:
    这里写图片描述
    图5. 原图和直方图

    这里写图片描述
    图6. 直方图均衡后图像及直方图

    这里写图片描述
    图7. 目标直方图

    这里写图片描述
    图8. 直方图匹配图像和直方图

    自定义直方图匹配

    %% 自定义匹配
    clear all;clc;close all;
    ImgFile='E:\图像处理\冈萨雷斯图片库\DIP3E_Original_Images_CH03\Fig0323(a)(mars_moon_phobos).tif';
    ImgIn=imread(ImgFile);
    x=[0 8 16 180 200 255];
    Y=[0 70000 8000 0 3139 0];
    xi=0:255;
    yi = interp1q(x',Y',xi');
    [counts, x]=imhist(ImgIn,256);
    cum_counts=cumsum(counts);% 累加CDF
    % 归一化到[0 255]
    cum_counts=cum_counts./numel(ImgIn);
    s_k=round(cum_counts*255);
    cum_yi=cumsum(yi);% 目标累加CDF
    g_z=round(cum_yi./sum(yi)*255); 
    figure;plot(s_k,'r');hold on;plot(g_z,'g');grid on;hold off;
    legend('s_k','g_z')
    axis([0 255 0 255]);title('原图累计CDF 和 目标累计CDF')
    map=nan(size(s_k));
    for k=1:length(s_k)
        delta=abs(g_z-s_k(k));
        [~,z]=min(delta);
        map(k)=z;
    end
    figure;plot(0:255,map);axis([0 255 0 255]);grid on;
    xlabel('输入灰度');ylabel('输出灰度');title('灰度映射曲线')
    
    ImgOut=zeros(size(ImgIn));
    for m=0:length(map)-1
        ImgOut(ImgIn==m)=map(m+1);
    end
    ImgOut=uint8(ImgOut);
    figure;imshow(ImgOut);title('直方图匹配')
    figure;imhist(ImgOut,256);title('直方图匹配');

    输出:只列出转换函数
    这里写图片描述
    转换函数映射图

    二、局部对比度增强

    1. 邻域直方图均衡

    将全局直方图均衡的思想应用于邻域直方图处理中。

    2. 邻域直方图匹配

    将全局直方图匹配的思想应用于邻域直方图处理中。

    3. 邻域统计方法

    a. 基本思想

    对于一幅图像,灰度的均值MG表示平均光照,灰度的方差(或标准差)σG表示对比度的强弱。
    对于图像某一个像素,邻域的灰度均值ML表征邻域光照强度,邻域的方差或者标准差σL表示邻域对比度的强弱。
    根据MLσL的大小自主选择想要增强的点做增强(例如乘以某一个常数E)。

    b. 算法
    1. 初始化:增强常数E,灰度下阈值k0,标准差下阈值 k1,标准差上阈值 k2,窗口半宽s
    2. 计算图像灰度均值MG和灰度标准差σG
    3. 对于每一个像素,计算邻域(大小为2step+1的方块)内灰度均值ML和标准差σL
    4. 如果ML<=k0MG并且k1σG<=σL<=k2σG,将像素灰度乘以E
    c. matlab代码

    测试脚本LocalEnhancement_test.m

    %% 局部对比度增强
    clear all;clc;close all;
    ImgFile='E:\图像处理\冈萨雷斯图片库\DIP3E_Original_Images_CH03\tungsten_original.tif';
    step=1;
    para.E=4.0;
    para.k0=0.4; % 均值下阈值
    para.k1=0.02; % 标准差下阈值
    para.k2=0.4; % 标准差上阈值
    ImgIn=imread(ImgFile);
    ImgHistEq=histeq(ImgIn,256);
    ImgIn=double(ImgIn);
    % ImgIn=double(rgb2gray(ImgIn));
    [ MeanLocal,VarLocal ] = LocalStatistics( ImgIn, step );
    [ ImgOut ] = LocalEnhancement( ImgIn, MeanLocal, VarLocal,para );
    
    figure;imshow(uint8(ImgIn));title('原图');
    figure;imshow(uint8(ImgOut));title('局部统计增强');
    figure;imshow(ImgHistEq);title('全局灰度增强 - 直方图均衡');

    函数LocalEnhancement.m

    function [ ImgOut ] = LocalEnhancement( ImgIn, MeanLocal, VarLocal,para )
    %LOCALENHANCEMENT Summary of this function goes here
    % 使用局部均值和局部标准差实现局部图像增强
    %   Detailed explanation goes here
    [rows, cols]=size(ImgIn);
    MeanGlobal=mean(ImgIn(:));
    VarGlobal=std(ImgIn(:));
    for i=1:rows
        for j=1:cols
            if MeanLocal(i,j)<=para.k0*MeanGlobal...
                    &&VarLocal(i,j)>=para.k1*VarGlobal...
                    &&VarLocal(i,j)<=para.k2*VarGlobal
                ImgIn(i,j)=para.E*ImgIn(i,j);
            end
        end
    end
    ImgOut=ImgIn;
    end
    

    函数LocalStatistics.m

    function [ MeanLocal,VarLocal ] = LocalStatistics( ImgIn, step )
    %LOCALSTATISTICS Summary of this function goes here
    % 求局部的灰度均值灰度方差
    % ImgIn - 输入灰度图,double
    % step  - 窗口大小为2*step+1,step越大,细节越少
    %   Detailed explanation goes here
    % 矩阵边缘补齐
    ImgIn=padarray(ImgIn,[step, step],'replicate');
    [rows, cols] = size(ImgIn);
    MeanLocal=zeros(size(ImgIn));
    VarLocal=zeros(size(ImgIn));
    for i = step+1:1:rows-step
        for j = step+1:1:cols-step
            LocalNeighbor=ImgIn(i-step:i+step,j-step:j+step);
            MeanLocal(i,j)=mean(LocalNeighbor(:));
            VarLocal(i,j)=std(LocalNeighbor(:));
        end
    end
    % 切割成和原图相同的大小
    MeanLocal=MeanLocal(2:end-1,2:end-1);
    VarLocal=VarLocal(2:end-1,2:end-1);
    
    end

    结果输出:
    目的是想要增强右下方的纹理,而不改变中间较亮的纹理。全局灰度增强不但不能增强右下方的纹理,而且改变了中间较亮的纹理。局部统计增强达到了目的,但是产生了一些不想要的假边缘(如左上方)和奇异点(一些散乱的白点)。
    源图像全局HistEQ
    图9. 原图和全局灰度增强的图。全局histeq对右下角纹理的增强效果不明显,而且改变了中间较亮区域的灰度。

    LocalStatistics
    图10. 局部统计增强。右下方纹理得到明显的增强,而且不改变中间较亮区域的纹理。但是产生了一些边缘失真。


    2017.4.24补充:


    直方图均衡和其他的均衡方法都会把图像的直方图尽量调整的分布均匀一些. 尽量不会出现较高的尖峰和较大的灰度空档.这是因为这些算法不知道要增强哪些部分的灰度, 也不知道要去抑制哪些部分的灰度. 而某一部分灰度的增强必然意味着另外一部分灰度的压缩. 所以这些算法只能”雨露均沾”, 把hist中所有的灰度都调整到较为均匀的分布. 雨露均沾的结果, 可能是细节的增强和提升. 也有可能是背景被增强, 造成背景噪声放大, 还不如不增强. 针对后一种情况, 就有了CLAHE等限制对比度的算法.


    1. 本文主要参考冈萨雷斯《数字图像处理》第三版英文版
    2. 如果matlab读入*.tif图片出错,参见:
      http://jingyan.baidu.com/article/aa6a2c14f9441b0d4c19c4b0.html
    展开全文
  • 关于图像增强必须清楚的基本概念 1.图像增强的目的: 1)改善图像的视觉效果, ...2,图像增强方法分类: 1)从处理对象分类:灰度图像,(伪)彩色图像 2)从处理策略分类:全局处理,局部处理(ROI

    关于图像增强必须清楚的基本概念

    1.图像增强的目的:

    1)改善图像的视觉效果,
    2)转换为更适合于人或机器分析处理的形式
    3)突出对人或机器分析有意义的信息
    4)抑制无用信息,提高图像的使用价值
    5)增强后的图像并不一定保真


    2,图像增强的方法分类:

    1)从处理对象分类:灰度图像,(伪)彩色图像
    2)从处理策略分类:全局处理,局部处理(ROI ROI,Region of Interest Interest)
    3)从处理方法分类:空间域(点域运算,即灰度变换;邻域方法,即空域滤波),频域方法
    4)从处理目的分类:图像锐化,平滑去噪,灰度调整(对比度增强)


    3,图像增强的方法之对比度增强

    1)灰度变换法

    线性变换(已实现)
    对数变换(已实现)
    指数变换(已实现)

    2)直方图调整法
    直方图均衡化(已实现)
    直方图匹配(未实现)



    一,直方图均衡化 

    直方图均衡化的英文名称是Histogram Equalization. 

      图像对比度增强的方法可以分成两类:一类是直接对比度增强方法;另一类是间接对比度增强方法。直方图拉伸和直方图均衡化是两种最常见的间接对比度增强方法。直方图拉伸是通过对比度拉伸对直方图进行调整,从而“扩大”前景和背景灰度的差别,以达到增强对比度的目的,这种方法可以利用线性或非线性的方法来实现;直方图均衡化则通过使用累积函数对灰度值进行“调整”以实现对比度的增强。
      直方图均衡化处理的“中心思想”是把原始图像的灰度直方图从比较集中的某个灰度区间变成在全部灰度范围内的均匀分布。直方图均衡化就是对图像进行非线性拉伸,重新分配图像像素值,使一定灰度范围内的像素数量大致相同。直方图均衡化就是把给定图像的直方图分布改变成“均匀”分布直方图分布。
      缺点: 
      1)变换后图像的灰度级减少,某些细节消失; 
      2)某些图像,如直方图有高峰,经处理后对比度不自然的过分增强。 
      直方图均衡化是图像处理领域中利用图像直方图对对比度进行调整的方法。 
      这种方法通常用来增加许多图像的局部对比度,尤其是当图像的有用数据的对比度相当接近的时候。通过这种方法,亮度可以更好地在直方图上分布。这样就可以用于增强局部的对比度而不影响整体的对比度,直方图均衡化通过有效地扩展常用的亮度来实现这种功能。
      这种方法对于背景和前景都太亮或者太暗的图像非常有用,这种方法尤其是可以带来X光图像中更好的骨骼结构显示以及曝光过度或者曝光不足照片中更好的细节。这种方法的一个主要优势是它是一个相当直观的技术并且是可逆操作,如果已知均衡化函数,那么就可以恢复原始的直方图,并且计算量也不大。这种方法的一个缺点是它对处理的数据不加选择,它可能会增加背景杂讯的对比度并且降低有用信号的对比度。
      

    关于编程实现,同样是不调用matlab库函数,自己编程实现。这样可以更深刻地理解直方图均衡化技术,提高编程能力。

    实现代码(matlab):


    1. clc;  
    2. close all;  
    3. clear all;  
    4.    
    5. src_img = imread('flyman_gray.bmp');    
    6.   
    7. figure (1)   
    8. subplot(321),imshow(src_img),title('原图像');%显示原始图像    
    9. subplot(322),imhist(src_img),title('原图像直方图');%显示原始图像直方图    
    10.   
    11. matlab_eq=histeq(src_img);         %利用matlab的函数直方图均衡化  
    12. subplot(323),imshow(matlab_eq),title('matlab直方图均衡化原图像');%显示原始图像    
    13. subplot(324),imhist(matlab_eq),title('matlab均衡化后的直方图');%显示原始图像直方图   
    14.   
    15. dst_img=myHE(src_img);             %利用自己写的函数直方图均衡化  
    16. subplot(325),imshow(dst_img),title('手写均衡化效果');%显示原始图像    
    17. subplot(326),imhist(dst_img),title('手写均衡化直方图');%显示原始图像直方图   

    直方图均衡化函数的实现:


    1. function dst_img=myHE(src_img)    
    2.   
    3. [height,width] = size(src_img);  
    4. dst_img=uint8(zeros(height,width));  
    5. %进行像素灰度统计;      
    6. NumPixel = zeros(1,256);%统计各灰度数目,共256个灰度级      
    7. for i = 1:height      
    8.     for j = 1: width      
    9.         NumPixel(src_img(i,j) + 1) = NumPixel(src_img(i,j) + 1) + 1;%对应灰度值像素点数量增加一      
    10.     end      
    11. end      
    12. %计算灰度分布密度      
    13. ProbPixel = zeros(1,256);      
    14. for i = 1:256      
    15.     ProbPixel(i) = NumPixel(i) / (height * width * 1.0);      
    16. end      
    17. %计算累计直方图分布      
    18. CumuPixel = zeros(1,256);      
    19. for i = 1:256      
    20.     if i == 1      
    21.         CumuPixel(i) = ProbPixel(i);      
    22.     else      
    23.         CumuPixel(i) = CumuPixel(i - 1) + ProbPixel(i);      
    24.     end      
    25. end      
    26.     
    27. % 指定范围进行均衡化    
    28. % pixel_max=max(max(I));    
    29. % pixel_min=min(min(I));    
    30. pixel_max=255;    
    31. pixel_min=0;    
    32. %对灰度值进行映射(均衡化)      
    33. for i = 1:height      
    34.     for j = 1: width      
    35.         dst_img(i,j) = CumuPixel(src_img(i,j)+1)*(pixel_max-pixel_min)+pixel_min;      
    36.     end      
    37. end      
    38. return;  



    为什们和matlab的直方图不一样呢???



    二,指数变换

    指数变换(Power-Law )的公式:S=c*R^r,通过合理的选择c和r可以压缩灰度范围,算法以c=1.0/255.0, r=2实现。
    要做该图像增强变换需要先做归一化,再指数变换,最后反归一化
    增强效果展示:可以看见,改增强算法并不能很好的将像素尽可能的碾平。
    指数增强参考程序为:
    1. clc;  
    2. close all;  
    3. clear all;   
    4.      
    5. % -------------Gamma Transformations-----------------    
    6. %f = imread('Fig0316(4)(bottom_left).tif');     
    7. f = imread('seed.tif');     
    8. Gamma = 0.4;    
    9. g2 = myExpEnhance(f,Gamma);    
    10.   
    11. figure();    
    12. subplot(221);  imshow(f);  xlabel('a).Original Image');    
    13. subplot(222),imhist(f),title('原图像直方图');%显示原始图像直方图    
    14. subplot(223);  imshow(g2);  xlabel('b).Gamma Transformations \gamma = 0.4');    
    15. subplot(224),imhist(g2),title('增强图像直方图');%显示原始图像直方图   
    指数增强核心函数为:
    1. function dst_img=myExpEnhance(src_img,Gamma)    
    2. src_img = mat2gray(src_img,[0 255]);%将图像矩阵A中介于amin和amax的数据归一化处理, 其余小于amin的元素都变为0, 大于amax的元素都变为1。    
    3. C = 1;    
    4. g2 = C*(src_img.^Gamma);   
    5. %反归一化  
    6. max=255;  
    7. min=0;  
    8. dst_img=uint8(g2*(max-min)+min);  




    三,对数变换

           对数变换主要用于将图像的低灰度值部分扩展,将其高灰度值部分压缩,以达到强调图像低灰度部分的目的。变换方法由下式给出。

    这里的对数变换,底数为(v+1),实际计算的时候,需要用换底公式。其输入范围为归一化的【0-1】,其输出也为【0-1】。对于不同的底数,其对应的变换曲线如下图所示。

    底数越大,对低灰度部分的强调就越强,对高灰度部分的压缩也就越强。相反的,如果想强调高灰度部分,则用反对数函数就可以了。看下面的实验就可以很直观的理解,下图是某图像的二维傅里叶变换图像,其为了使其灰度部分较为明显,一般都会使用灰度变换处理一下。

    效果图:


    参考代码:
    1. clc;  
    2. close all;  
    3. clear all;   
    4.   
    5. %-------------Log Transformations-----------------  
    6. f = imread('seed.tif');  
    7.   
    8. g_1 = myLogEnhance(f,10);  
    9. g_2 = myLogEnhance(f,100);  
    10. g_3 = myLogEnhance(f,200);  
    11.   
    12. figure();  
    13. subplot(2,2,1);  
    14. imshow(f);xlabel('a).Original Image');  
    15.   
    16. subplot(2,2,2);  
    17. imshow(g_1);xlabel('b).Log Transformations v=10');  
    18.   
    19. subplot(2,2,3);  
    20. imshow(g_2);xlabel('c).Log Transformations v=100');  
    21.   
    22. subplot(2,2,4);  
    23. imshow(g_3);  
    24. xlabel('d).Log Transformations v=200');  

    对数变换核心函数
    1. function dst_img=myLogEnhance(src_img,v)   
    2. c=1.0;  
    3. src_img = mat2gray(src_img,[0 255]);  
    4. g =c*log2(1 + v*src_img)/log2(v+1);  
    5. %反归一化  
    6. max=255;  
    7. min=0;  
    8. dst_img=uint8(g*(max-min)+min);  





    四,灰度拉伸

    灰度拉伸也用于强调图像的某个部分,与伽马变换与对数变换不同的是,灰度拉升可以改善图像的动态范围。可以将原来低对比度的图像拉伸为高对比度图像。实现灰度拉升的方法很多,其中最简单的一种就是线性拉伸。而这里介绍的方法稍微复杂一些。灰度拉伸所用数学式如下所示。

    同样的,其输入r为【0-1】,其输出s也为【0-1】。这个式子再熟悉不过了,跟巴特沃斯高通滤波器像极了,其输入输出关系也大致能猜到是个什么形状的。但是,这里就出现一个问题了,输入为0时候,式子无意义了。所以,在用Matlab计算的时候,将其变为如下形式。

    这里的eps,就是Matlab里面,一个很小数。如此做的话,式子变得有意义了。但是,其输入范围为【0-1】的时候,其输出范围变为了。输出范围大致为【0-1】,为了精确起见,使用mat2gray函数将其归一化到精确的[0-1]。调用格式如下。



    五,线性拉伸

    为了突出感兴趣的目标或者灰度区间,相对抑制那些不感兴趣的灰度区域,可采用分段线性法,常用的是三段线性变换




    参考程序:

    1. clc;  
    2. close all;  
    3. clear all;   
    4.   
    5. I=imread('seed.tif');   
    6. [m,n,k]=size(I);  
    7. figure (1)  
    8. imshow('seed.tif');title(' 原图像');   
    9. mid=mean(mean(I));  
    10. %横轴  
    11. fa=20; fb=80;  
    12. %纵轴  
    13. ga=50; gb=230;  
    14.   
    15. J=myLinearEnhance(I,fa,fb,ga,gb);  
    16. figure (2)  
    17. imshow(J);title(' 线性拉伸图像');   
    18.   
    19. pixel_f=1:256;  
    20. pixel_g=zeros(1,256);  
    21.   
    22. %三段斜率,小于1表示该段将会被收缩  
    23. k1=double(ga/fa);   
    24. k2=(gb- ga)/(fb- fa);  
    25. k3=(256- gb)/(256- fb);  
    26. for i=1:256  
    27.     if i <= fa  
    28.         pixel_g(i)= k1*i;  
    29.     elseif fa < i && i <= fb  
    30.         pixel_g(i)= k2*( i- fa)+ ga;  
    31.     else  
    32.         pixel_g(i)= k3*( i - fb)+ gb;  
    33.     end  
    34. end  
    35. figure (3)  
    36. plot(pixel_f,pixel_g);  


    核心函数:

    1. function dst_img=myLinearEnhance(src_img,fa,fb,ga,gb)    
    2.   
    3. [height,width] = size(src_img);  
    4. dst_img=uint8(zeros(height,width));  
    5.   
    6. src_img=double(src_img);  
    7.   
    8. %三段斜率  
    9. k1=ga/fa;   
    10. k2=(gb- ga)/(fb- fa);  
    11. k3=(255- gb)/(255- fb);  
    12. for i=1:height  
    13.     for j=1:width  
    14.             if src_img(i,j) <= fa  
    15.                 dst_img(i,j)= k1*src_img(i,j);  
    16.             elseif fa < src_img(i,j) && src_img(i,j) <= fb  
    17.                 dst_img(i,j)= k2*( src_img(i,j)- fa)+ ga;  
    18.             else  
    19.                 dst_img(i,j)= k3*( src_img(i,j)- fb)+ gb;  
    20.             end  
    21.     end  
    22. end  
    23. dst_img=uint8(dst_img);   




    附录:

    附录网上的另一份讲解:
    直方图均衡化算法分为三个步骤,第一步是统计直方图每个灰度级出现的次数,第二步是累计归一化的直方图,第三步是计算新的像素值。
    第一步:
    for(i=0;i<height;i++)
    for(j=0;j<width;j++)
    n[s[i][j]]++;

    for(i=0;i<L;i++)
    p[i]=n[i]/(width*height);

    这里,n[i]表示的是灰度级为i的像素的个数,L表示的是最大灰度级,width和height分别表示的是原始图像的宽度和高度,所以,p[i]表示的就是灰度级为i的像素在整幅图像中出现的概率(其实就是p[]这个数组存储的就是这幅图像的归一化之后的直方图)。
    第二步:
    for(i=0;i<=L;i++)
    for(j=0;j<=i;j++)
    c[i]+=p[j];

    c[]这个数组存储的就是累计的归一化直方图。
    第三步:
    max=min=s[0][0];
    for(i=0;i<height;i++)
    for(j=0;j<width;j++)
    if(max<s[i][j]){
    max=s[i][j];
    }else if(min>s[i][j]){
    min=s[i][j];
    }

    找出像素的最大值和最小值。
    for(i=0;i<height;i++)
    for(j=0;j<width;j++)
    t[i][j]=c[s[i][j]]*(max-min)+min;

    t[][]就是最终直方图均衡化之后的结果。


    收录优秀代码:

    这份代码写得不错,学习了,原博客地址见参考资源【3】!

    1. #include <stdio.h>  
    2. #include <iostream>  
    3. #include "fftw3.h"  
    4. #include "string"  
    5. #include "vector"  
    6. #include <windows.h>  
    7. #include <opencv2/legacy/legacy.hpp>  
    8. #include <opencv2/nonfree/nonfree.hpp>//opencv_nonfree模块:包含一些拥有专利的算法,如SIFT、SURF函数源码。   
    9. #include "opencv2/core/core.hpp"  
    10. #include "opencv2/features2d/features2d.hpp"  
    11. #include "opencv2/highgui/highgui.hpp"  
    12. #include <opencv2/nonfree/features2d.hpp>  
    13.   
    14. using namespace cv;  
    15. using namespace std;  
    16.   
    17. class hisEqt  
    18. {  
    19. public:  
    20.     hisEqt::hisEqt();  
    21.     hisEqt::~hisEqt();  
    22. public:  
    23.     int w;  
    24.     int h;  
    25.     int nlen;  
    26.   
    27.     int *pHis;  
    28.     float *pdf;  
    29.   
    30.     //=====求像素分布概率密度====    
    31.     void  getPdf();  
    32.   
    33.     //======统计像素个数=======    
    34.     void getHis(unsigned char*imgdata);  
    35.   
    36.     //==========画统计分布直方图===============    
    37.     void drawHistogram(const float*pdf,Mat &hist1);    
    38.   
    39.     //===========直方图均衡化==========    
    40.     void hisBal();  
    41.   
    42.     //====直方图均衡化后的图像===    
    43.     void imgBal(unsigned char* img);  
    44. };  
    45.   
    46.   
    47. hisEqt::hisEqt() :nlen(0){  
    48.     pHis = new int[256 * sizeof(int)];  
    49.     memset(pHis, 0, 256 * sizeof(int));  
    50.     pdf = new float[255 * sizeof(float)];  
    51.     memset(pdf, 0, 255 * sizeof(float));  
    52. }  
    53.   
    54. hisEqt::~hisEqt(){  
    55.     delete[]pHis;  
    56.     delete[]pdf;  
    57. }  
    58.   
    59.   
    60. //======统计像素个数=======    
    61. void hisEqt::getHis(unsigned char*imgdata){  
    62.     for (int i = 0; i<nlen; i++)  
    63.     {  
    64.         pHis[imgdata[i]]++;  
    65.     }  
    66. }  
    67.   
    68.   
    69. //=====求像素分布概率密度====    
    70. void hisEqt::getPdf(){  
    71.     for (int k = 0; k<256; k++)  
    72.     {  
    73.         pdf[k] = pHis[k] / float(nlen);  
    74.     }  
    75. }  
    76.   
    77. //===========直方图均衡化==========    
    78. void hisEqt::hisBal(){  
    79.     for (int k = 1; k<256; k++)  
    80.     {  
    81.         pdf[k] += pdf[k - 1];  
    82.     }  
    83.     for (int k = 0; k<256; k++)  
    84.     {  
    85.         pHis[k] = 255 * pdf[k];  
    86.     }  
    87. }  
    88.   
    89. //====直方图均衡化    
    90. void hisEqt::imgBal(unsigned char* img){  
    91.     for (int i = 0; i<nlen; i++)  
    92.     {  
    93.         img[i] = pHis[img[i]];  
    94.     }  
    95. }  
    96.   
    97.   
    98. void hisEqt::drawHistogram(const float *pdf, Mat& hist1){  
    99.     for (int k = 0; k<256; k++)  
    100.     {  
    101.         if (k % 2 == 0)  
    102.         {  
    103.             Point a(k, 255), b(k, 255 - pdf[k] * 2550);  
    104.             line(hist1,  
    105.                 a,  
    106.                 b,  
    107.                 Scalar(0, 0, 255),  
    108.                 1);  
    109.         }  
    110.         else  
    111.         {  
    112.             Point a(k, 255), b(k, 255 - pdf[k] * 2550);  
    113.             line(hist1,  
    114.                 a,  
    115.                 b,  
    116.                 Scalar(0, 255, 0),  
    117.                 1);  
    118.         }  
    119.     }  
    120. }  
    121.   
    122.   
    123. int main()  
    124. {  
    125.     Mat image = imread("Fig0651(a)(flower_no_compression).tif");  
    126.     if (!image.data)  
    127.         return -1;  
    128.   
    129.     Mat hist2(256, 256, CV_8UC3, Scalar(0, 0, 0));  
    130.     Mat hist1(256, 256, CV_8UC3, Scalar(0, 0, 0));  
    131.   
    132.     Mat imgOut = Mat(image.rows, image.cols, CV_8UC3, Scalar(0, 0, 0));  
    133.     vector<Mat> planes;  
    134.     int chn = image.channels();  
    135.     if (chn == 3)  
    136.     {  
    137.         split(image, planes);  
    138.     }  
    139.     while (chn)  
    140.     {  
    141.         chn--;  
    142.         unsigned char* imageData = new unsigned char[sizeof(unsigned char)*(image.cols*image.rows)];  
    143.         memcpy(imageData, planes[chn].data, planes[chn].cols*planes[chn].rows);  
    144.         hisEqt his;//自定义的类  
    145.         his.nlen = image.rows*image.cols;  
    146.         his.getHis(imageData);  
    147.         his.getPdf();  
    148.   
    149.         //  //======画原图直方图并保存============    
    150.         his.drawHistogram(his.pdf, hist1);  
    151.         string pic_name = "hisline";  
    152.         pic_name = pic_name + to_string(chn);  
    153.         pic_name=pic_name+  ".jpg";  
    154.         imwrite(pic_name, hist1);  
    155.   
    156.         his.hisBal();  
    157.         his.getPdf();  
    158.         //  //======画均衡化后直方图并保存============    
    159.         his.drawHistogram(his.pdf, hist2);  
    160.         string pic_name0 = "his_balanceline";  
    161.         pic_name0 = pic_name0 + to_string(chn);  
    162.         pic_name0 = pic_name0 + ".jpg";  
    163.         imwrite(pic_name0, hist2);  
    164.   
    165.         //  //=====图像均衡化===    
    166.         his.imgBal(imageData);  
    167.         memcpy(planes[chn].data, imageData, planes[chn].cols*planes[chn].rows);  
    168.         delete[] imageData;  
    169.         imageData = NULL;  
    170.     }  
    171.     merge(planes, imgOut);//单通道合并  
    172.     imwrite("result.jpg", imgOut);  
    173.     return 0;  
    174. }  
    展开全文
  • 对比度增强 提前规定:输入图像

    对比度增强

    提前规定:输入图像为?,宽为?,高为?,输出图像?,??,?为输入图像?的 ?行?列像素灰度级,??,?为输出图像?的?行?列像素灰度级,0≤?≤?,0≤?≤?

     

    灰度直方图

    灰度直方图描述了一幅图像中每个灰度级在图像中占据的像素个数或者是比率,利用灰度直方图,通过数学方法,我们可以很容易的实现图像的处理

    1.1线性变换

    输入图像为?,宽为?,高为?,输出图像? ,图像的线性变换可以表示为

    ??,?=?∗??,?+?,0≤?≤?,0≤?≤?

    优点:简单易懂

    缺点:通过该方法可以调整图像的对比度,但是参数?,?需要根据自己实际图像进行多次测试来确定,比较繁琐

     

    1.2直方图正则化

    直方图正则化,依据了统计学原理,来进行图像的对比度调整:

    一般规定????=255;????=0

     

    优点:直方图正规化自动选取?,?的线性变换

    缺点:1.变换后图像的灰度级减少,某些细节消失;2.某些图像,如直方图有高峰,经处理后对比度不自然的过分增强

     

     

    1.3 伽马变换

     

    伽马变换的方法,首先将灰度值诡异到[0.1]范围,??,?表示归一化之后的像素值

    ??,?=??,??,0≤?≤?,0≤?≤?

    输出图像不变:伽马=1

    输入图像整体过暗,可以调整令 0<γ<1, 来增加对比度

    输入图像整体过暗,  可以调整令   γ>1对比度

    优点:提升对比度效果比较好

    缺点:需要手动调整γ值

     

    1.4 全局直方图均衡

    原图 ? 的直方图是各个像素级分布不均匀,导师对比度出现问题,全局直方图均衡使得输出图像?的像素均匀分布在每一像素级别,输出图像?的对比度达到一个比较好的效果。

    全局直方图均衡就是在做这个工作,找出亮度级别为p的输入像素到亮度级别为q的输出像素的映射,最终使得输出图像?的像素均匀分布在每一像素级别。

    所以推得:

    1.5限制对比度的自适应直方图均衡化

    将图形划分为不重叠的区域,单独对每个区域做直方图均衡化。为了避免每个区域中的噪声被放大,使用限制对比度的方法,某点像素值超过了该区域的限制对比度,则将起均匀分配给该区域中其他的像素点。

    展开全文
  • 对比度拉伸是图像增强的一种方法,也属于灰度变换操作。我们看如下图像: 可以看到,这张图片非常灰暗。我们查看下其直方图。 import cv2 import matplotlib.pyplot as plt farina = cv2.imread("far...

    我们前面提到过图像二值化,图像反转,本质上是对图像的所有像素点的灰度进行操作,属于灰度变换的内容。灰度变换的主要目的是用于图像增强

    而对比度拉伸是图像增强的一种方法,也属于灰度变换操作。我们看如下图像:
    这里写图片描述
    可以看到,这张图片非常灰暗。我们查看下其直方图。

    import cv2
    import matplotlib.pyplot as plt
    
    farina = cv2.imread("farina.png", 0)
    
    hist_full = cv2.calcHist([farina], [0], None, [256], [0, 256])
    
    plt.plot(hist_full)
    plt.show()
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    这里写图片描述
    可以看到所有像素的灰度值大部分集中在20-50之间,这使得整个图像很暗淡。也就是说对比度不高。如果我们通过灰度变换,将灰度值拉伸到整个0-255的区间,那么其对比度显然是大幅增强的。可以用如下的公式来将某个像素的灰度值映射到更大的灰度空间:

    I(x,y=I(x,y)IminImaxImin(MAXMIN)+MIN I(x, y)=\frac {I(x,y)-Imin}{Imax-Imin}(MAX-MIN)+MIN

    其中Imin,Imax是原始图像的最小灰度值和最大灰度值,MIN和MAX是要拉伸到的灰度空间的灰度最小值和最大值。

    Imax = np.max(farina)
    Imin = np.min(farina)
    MAX = 255
    MIN = 0
    farina_cs = (farina - Imin) / (Imax - Imin) * (MAX - MIN) + MIN
    cv2.imshow("farina_cs", farina_cs.astype("uint8"))
    cv2.waitKey()
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    这里写图片描述

    可以看出,对比度提升了很多。我们再看看其直方图,可以看到已经充满了整个灰度空间。
    这里写图片描述

    除了上述方法,对比度拉伸还有其它方法吗?当然是有的。例如直方图位移法(Histogram shifting)。公式如下:,

    I(x,y)=I(x,y)+offset I(x,y)=I(x,y)+offset

    在每个像素位置的灰度值增加一个偏移量offset。注意,这个offset可以是正数,也可以是负数。正的话,整体亮度变亮,负的话,整体亮度变暗。需要注意的是控制offset的值大小,不要越界。

    farina_cs = farina + 100
    cv2.imshow("farina_offset", farina_cs.astype("uint8"))
    cv2.waitKey()
    hist_full = cv2.calcHist([farina_cs.astype("uint8")], [0], None, [256], [0, 256])
    plt.plot(hist_full)
    plt.show()
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    下面分别是使用直方图位移方法后的图像和其直方图。
    这里写图片描述
    这里写图片描述

    可以看出直方图与原始直方图形状一模一样,只是在横轴上有所偏移。这种方法的图像增强效果并没有上一种方法好。

    转载自:https://blog.csdn.net/saltriver/article/details/79677199

    展开全文
  • 1)改善图像的视觉效果,2)转换为更适合于人或机器分析处理的形式3)突出对人或机器分析有意义的信息4)抑制无用信息,提高图像的使用价值5)增强后的图像并不一定保真2,图像增强方法分类:1)从处理对象分类:...
  • 点运算又称为对比度增强对比度拉伸或灰度变换,是一种通过图像中的每一个像素值进行运算的图像处理方式。。它将输入图像映射为输出图像,输出图像每个像素点的灰度值仅有对应的输入像素点的灰度值决定,运算结果...
  •   提到图像增强,第一印象就是直方图均衡与直方图规定化,这是最常见的也是非常有效的全局图像增强方法。在前不久的一次组会讨论中,课题组的一位同学提到了“自适应图像增强”,虽然自己以前也用过,但是一时间...
  • Python 图像对比度增强的几种方法图像处理工具——灰度直方图 图像处理工具——灰度直方图 灰度直方图时图像灰度级的函数,用来描述每个灰度级在图像矩阵中的像素个数或者占有率。 例子: I={abcdefghijklmnopqrst}I...
  • 对比度增强一直是图像处理中的一个恒久话题,一般来说都是基于直方图的,比如直方图均衡化。冈萨雷斯的书里面对这个话题讲的比较透彻。 关于图像增强必须清楚的基本概念 1.图像增强的目的: 1)改善图像的视觉...
  • 本章主要总结了图像增强技术中的点处理技术,包括灰度直方图的获取、直方图均衡化、直方图规范化和对比度调整等内容。C++和Python语言环境下,使用OpenCV工具实现上述图像增强操作。 OpenCV 简介: 1、OpenCV的...
  • 通过使用matlab将图片的对比度提升。程序如下:% 通过灰度直方图的数据显示该图像的灰度值整体偏高,图像过于明亮, % 所以选用 γ &gt; 1 的伽马变换 % 降低图像的亮度,提升图片的对比度。 clc img1 = imread...
  • 最近学习了一些图像处理的知识,对其有大概的了解,这次我简单简述下增强图像对比度方法——直方图均衡化。  直方图均衡化处理的“中心思想”是把原始图像的灰度直方图从比较集中的某个灰度区间变成在全部灰度...
  • 图像对比度增强

    2014-12-15 10:01:17
    图像对比度增强 1、图像增强处理并不能增加原始图像的信息,只能增强对某种信息的辨别能力,而这种处理肯定会损失一些其它信息; 2、强调根据具体应用而言,更“好”更“有用”的视觉效果图像; 3、图像增强处理...
  • 对比度拉伸是图像增强的一种方法,也属于灰度变换操作。我们看如下图像: 可以看到,这张图片非常灰暗。我们查看下其直方图。 import cv2 import matplotlib.pyplot as plt farina = cv2.imread(...
  • 图像增强方法分类:1 从处理...邻域方法,即空域滤波),频域方法4 从处理目的分类:图像锐化,平滑去噪,灰度调整(对比度增强)二 图像增强方法对比度增强1 灰度变换法线性变换(已实现)对数变换(已实...
  • 处理图像经常会对图像色彩进行增强,这就是改变图像的亮度和对比度。本章基于opencv对图像的亮度和对比度进行处理操作。其实,这是对图像的每一个像素点进行相应的操作。 上面这个公式可以很好的解释对图像的亮度...
  • 对于拍摄的图像,目标物的颜色与...很难提取出封闭的轮廓区域,所以想问一下,有什么好的方法可以增强对比度方法吗? 使得前景与背景的颜色辨识度高,以便于后期的边缘提取,直方图均衡化已经尝试过。 效果并不是好。
  • 下图是典型的对比度拉伸变换。点(r1,s1)和(r2,s2)的位置控制变换函数的...处理一幅8bit低对比度图像,(r1,s1)=(r_min,0),(r2,s2)=(r_max,L-1);其中r_min,r_max是图像中最小和最大灰度级; 因此,变换函数把灰度级由...
1 2 3 4 5 ... 20
收藏数 21,420
精华内容 8,568
关键字:

图像处理 增强对比度方法