精华内容
参与话题
问答
  • Retinex图像增强算法

    万次阅读 2016-02-18 17:35:36
    Retinex图像增强算法 前一段时间研究了一下图像增强算法,发现Retinex理论在彩色图像增强、图像去雾、彩色图像恢复方面拥有很好的效果,下面介绍一下我对该算法的理解。 Retinex理论 Retinex理论始于Land和...

    转自:http://www.cnblogs.com/sleepwalker/p/3676600.html?utm_source=tuicool&utm_medium=referral

    Retinex图像增强算法

    前一段时间研究了一下图像增强算法,发现Retinex理论在彩色图像增强、图像去雾、彩色图像恢复方面拥有很好的效果,下面介绍一下我对该算法的理解。

    Retinex理论

    Retinex理论始于Land和McCann于20世纪60年代作出的一系列贡献,其基本思想是人感知到某点的颜色和亮度并不仅仅取决于该点进入人眼的绝对光线,还和其周围的颜色和亮度有关。Retinex这个词是由视网膜(Retina)和大脑皮层(Cortex)两个词组合构成的.Land之所以设计这个词,是为了表明他不清楚视觉系统的特性究竟取决于此两个生理结构中的哪一个,抑或是与两者都有关系。

    Land的Retinex模型是建立在以下的基础之上的:

    一、真实世界是无颜色的,我们所感知的颜色是光与物质的相互作用的结果。我们见到的水是无色的,但是水膜—肥皂膜却是显现五彩缤纷,那是薄膜表面光干涉的结果;

    二、每一颜色区域由给定波长的红、绿、蓝三原色构成的;

    三、三原色决定了每个单位区域的颜色。

    Retinex 理论的基本内容是物体的颜色是由物体对长波(红)、中波(绿)和短波(蓝)光线的反射能力决定的,而不是由反射光强度的绝对值决定的;物体的色彩不受光照非均性的影响,具有一致性,即Retinex理论是以色感一致性(颜色恒常性)为基础的。如下图所示,观察者所看到的物体的图像S是由物体表面对入射光L反射得到的,反射率R由物体本身决定,不受入射光L变化。

    clip_image002[4]

    图1.Retinex理论中图像的构成

    Retinex理论的基本假设是原始图像S是光照图像L和反射率图像R的乘积,即可表示为下式的形式:

    clip_image004[4]

    基于Retinex的图像增强的目的就是从原始图像S中估计出光照L,从而分解出R,消除光照不均的影响,以改善图像的视觉效果,正如人类视觉系统那样。在处理中,通常将图像转至对数域,即clip_image006[4],从而将乘积关系转换为和的关系:

    clip_image008[4]

    Retinex方法的核心就是估测照度L,从图像S中估测L分量,并去除L分量,得到原始反射分量R,即:

    clip_image010[4]

    函数clip_image012[4]实现对照度L的估计(可以去这么理解,实际很多都是直接估计r分量)。

    Retinex理论的理解

    如果大家看论文,那么在接下去的篇幅当中,肯定会介绍两个经典的Retinex算法:基于路径的Retinex以及基于中心/环绕Retinex。在介绍两个经典的Retinex算法之前,我先来讲一点个人的理解,以便第一次接触该理论的朋友能够更快速地理解。当然,如果我的理解有问题,也请大家帮忙指出。

    Retinex理论就我理解,与降噪类似,该理论的关键就是合理地假设了图像的构成。如果将观察者看到的图像看成是一幅带有乘性噪声的图像,那么入射光的分量就是一种乘性的,相对均匀,且变换缓慢的噪声。Retinex算法所做的就是合理地估计图像中各个位置的噪声,并除去它。

    在极端情况下,我们大可以认为整幅图像中的分量都是均匀的,那么最简单的估计照度L的方式就是在将图像变换到对数域后对整幅图像求均值。因此,我设计了以下算法来验证自己的猜想,流程如下:

    (1) 将图像变换到对数域clip_image014[4] ;

    (2) 归一化去除加性分量clip_image016[4] ;

    (3) 对步骤3得到的结果求指数,反变换到实数域clip_image018[4]

    这里为了简化描述,省略了对图像本身格式的变换,算法用Matlab实现:

    复制代码
    % ImOriginal:原始图像
    % type:'add'表示分量是加性的,如雾天图像;'mult'表示分量是乘性的,如对照度的估计
    [m,n,z] = size(ImOriginal);
    ImOut = uint8(zeros(m,n,z));
    for i = 1:z
        if strcmp(type,'add')
            ImChannel = double(ImOriginal(:,:,i))+eps;
        elseif strcmp(type,'mult')
            ImChannel = log(double(ImOriginal(:,:,i))+eps);
        else
            error('type must be ''add'' or ''mult''');
        end
        ImOut(:,:,i) = EnhanceOneChannel(ImChannel);
    end
    ImOut = max(min(ImOut,255), 0);
    end
    
    function ImOut = EnhanceOneChannel(ImChannel)
    % 计算计算单个通道的反射分量
    % 1.对全图进行照射分量估计
    % 2.减去照射分量
    % 3.灰度拉伸
    ImChannel = ImChannel./max(ImChannel(:));
    ImRetinex = round(exp(ImChannel.*5.54));
    ImOut = uint8(ImRetinex);
    end
    复制代码

    为了验证算法的有效性,这里使用经典的Retinex算法与我所用的算法进行对比试验,效果如下:

    clip_image002[6]

    图2.测试原图

    clip_image004[6]

    图3.经典Retinex算法结果

    clip_image006[6]

    图4.上述方法结果

    从对比中可以看到,对于去除照度,还原图像本身来讲,效果还可以,并且不会在边缘位置产生光晕现象。缺点就是在去除照度分量L过程中,保留的反射分量R我在上述算法中使用归一化后直接进行反变换。这一步的作用可以近似看成去除一个均匀的直流分量,即均匀的照度分量。由于操作都是全局的,这里默认假设了所有位置的照射分量都是相同的,因此在灰度拉伸的时候没有照顾到局部的特性,图像整体亮度偏暗。当然,全局的照度估计对于图像的增强肯定有相当的局限性,其增强效果在色彩的还原和亮度处理等方面还是有一定缺陷的。

    个人认为,Retinex算法的关键还是正确的分析了噪声的性质。相信很多人都看到利用基于Retinex的图像水下增强、基于Retinex的图像去雾等等,我也好奇,那就试试吧。大雾图片嘛谁没有,前一阵子大雾天,没事拍了几张照片,终于用上了,请看对比图:

    clip_image008[6]

    图5.有雾原图

    clip_image010[6]

    图6.经典Retinex去雾效果

    clip_image012[6]

    图7.上述方法去雾效果

    还是老规矩,这时候对比试验还是最能说明效果的,为此选了一幅干扰很大的图像。基本上各位要是显示器比较差一点,从原图当中是很难看出大雾后面的东西。从去雾效果来看,上述方法的效果并不比经典算法要差,至少在去雾的效果上,本实验结果从主观上给人的感觉还是不错的。

    在上述案例中,最重要的就是正确分析有雾图像的结构,与Retinex理论一开始的核心思想有区别的是,在针对这种加性的干扰时,经典的Retinex算法在处理过程中,其实仅仅是利用其估计加性的干扰分量;当然,抛开Retinex理论对照度、反射率对最终图像形成的核心思想(如图1),后续最重要的就是对这个加性的干扰的估计了。

    对于有雾的图像,我们大可以看作透过一块磨砂玻璃去看一幅清晰的图像,这样大家就能很好理解为什么认为在这个案例中,将雾的干扰认为是一个加性的了。诸如后面两个经典的算法,所有的这类算法归根结底就是更好地利用原图像中的像素点去估计原始照度。从上面例程上可以看出,使用一个全局估计对局部的增强是比较差的,如果存在照度不均匀(雾的浓度不均匀),或者背景颜色亮度很高等情况时,处理结果会趋向恶劣,效果比较差。

    当然,经典也不是完美,从图3中可以看到,经典的算法容易出现光晕效果(蓝色书本文字周围一圈白色),因此后续对于照度估计和去除光晕等问题又有很多基于Retinex理论的变体算法,这里暂不进行介绍。下面开始介绍两个经典的算法,查看Matlab代码下载点击:

    http://www.cs.sfu.ca/~colour/publications/IST-2000/

    McCann Retinex算法

    McCann Retinex 算法是McCann和Frankle一起提出的一种Retinex算法,该算法是一种基于多重迭代策略的Retinex算法,单个点的像素值取决于一条特定路径的环绕的结果,经过多次迭代逼近理想值。通过比较螺旋式路径上的各像素点的灰度值来估计和去除图像的照度分量。

    clip_image002[8]

    图8.McCann Retinex算法路径选择示意图

    这个图是参照人家论文的,不过我准备像论文那样讲,因为太复杂了,不容易懂。从图中我们可以看到,算法沿着这个螺旋式的路径选取用于估计的点,并且越靠近预测的中心点选取的点数越多。这个从实际物理上也解释的通,靠的近的像素点与中心像素点的相关性肯定要要比远处的点要高。

    该算法估测图像经过以下几个步骤:

    1. 将原图像变换到对数域clip_image004[8],彩色图像对各通道都进行对数变换;

    2. 初始化常数图像矩阵clip_image006[8],该矩阵作为进行迭代运算的初始值;

    3. 计算路径,如上图8所示,这里令clip_image008[8]为路径上的点,从远到近排列;

    4. 对路径上的像素点按照如下公式运算:

    clip_image010[8]

    clip_image012[8]

    公式所表示的大致意思为:从远到近,中心点像素值减去路径上的像素值得到的差值的一半与前一时刻的估计值之间的和。最终,中心像素点的像素大致的形式为

    clip_image014[6]

    其中clip_image016[6]表示中心位置最终的反射率估计,clip_image018[6]为常数值为转换后的图像中的最大值,在步骤2中被确定。从这里将clip_image020按照Retinex理论进行分解,最终公式中可以看到,最终照度分量被去除了,而中心位置的反射率由路径上各点的反射率之间的差值进行估计,并且从轨迹上可以看到,靠的越近的在最终估计的时候所占比重越大。

    就我个人理解,这类估计算法,实质是将中心位置和周围亮度之间的差异作为最终中心位置的反射率的估计。如果中心位置亮度本身高,那么最终的结果还是高亮度的;如果中心位置亮度低,那么中心与其它点的差肯定是负值,最终的结果clip_image016[7]就比较小,亮度就比较低。这就要求路径上的点需要能够很好地代表整幅图像的特性,如果图像本身很规则,那么可能中央与周围计算的结果无法估测该点像素本身的灰度特性,结果就与预期的可能不一样了。如下图9可以看到,算法实质是估计中心和周边的差值,因此图中原本黑色区域的图像由于与周边差别很小,因此呈现高亮度;而在小型的矩形周围随着距离的增大,差别渐渐变小,因此亮度逐渐升高,无法体现原本黑色像素点处原本的亮度特性。

    clip_image022

    图9.算法的测试图(来自Retinex in Matlab)

    从原始算法中可以看到,还有一个重要的步骤,就是迭代。迭代的作用是尽可能保留中央周边差的分量,原本每次只保留中央周边差的一半(见步骤4中最后的除2的处理),迭代次数越多,保留的分量就越多,迭代n次保留的分量就是clip_image024,这样局部的信息就更多,相当于降低动态范围的压缩。这样的操作可以使图像更加自然,但是会增加运算量,下图可以更加明显地看出迭代次数的影响:

    clip_image026

    图10.迭代次数的影响

    为了方便各位自己研究,下面我给出该算法源码供大家参考:

    复制代码
    function Retinex = retinex_frankle_mccann(L, nIterations)
    
    % RETINEX_FRANKLE_McCANN: 
    %         Computes the raw Retinex output from an intensity image, based on the
    %         original model described in:
    %         Frankle, J. and McCann, J., "Method and Apparatus for Lightness Imaging"
    %         US Patent #4,384,336, May 17, 1983
    %
    % INPUT:  L           - logarithmic single-channel intensity image to be processed
    %         nIterations - number of Retinex iterations
    %
    % OUTPUT: Retinex     - raw Retinex output
    %
    % NOTES:  - The input image is assumed to be logarithmic and in the range [0..1]
    %         - To obtain the retinex "sensation" prediction, a look-up-table needs to
    %         be applied to the raw retinex output
    %         - For colour images, apply the algorithm individually for each channel
    %
    % AUTHORS: Florian Ciurea, Brian Funt and John McCann. 
    %          Code developed at Simon Fraser University.
    %
    % For information about the code see: Brian Funt, Florian Ciurea, and John McCann
    % "Retinex in Matlab," by Proceedings of the IS&T/SID Eighth Color Imaging 
    % Conference: Color Science, Systems and Applications, 2000, pp 112-121.
    %
    % paper available online at http://www.cs.sfu.ca/~colour/publications/IST-2000/
    %
    % Copyright 2000. Permission granted to use and copy the code for research and 
    % educational purposes only.  Sale of the code is not permitted. The code may be 
    % redistributed so long as the original source and authors are cited.
    
    global RR IP OP NP Maximum
    RR = L;
    Maximum = max(L(:));                                 % maximum color value in the image
    [nrows, ncols] = size(L);
    
    shift = 2^(fix(log2(min(nrows, ncols)))-1);          % initial shift
    OP = Maximum*ones(nrows, ncols);                     % initialize Old Product
    
    while (abs(shift) >= 1)
       for i = 1:nIterations
          CompareWith(0, shift);                         % horizontal step
          CompareWith(shift, 0);                         % vertical step
       end
       shift = -shift/2;                                 % update the shift
    end
    Retinex = NP;
    
    function CompareWith(s_row, s_col)
    global RR IP OP NP Maximum
    IP = OP;
    if (s_row + s_col > 0)
       IP((s_row+1):end, (s_col+1):end) = OP(1:(end-s_row), 1:(end-s_col)) + ...
       RR((s_row+1):end, (s_col+1):end) - RR(1:(end-s_row), 1:(end-s_col));
    else
       IP(1:(end+s_row), 1:(end+s_col)) = OP((1-s_row):end, (1-s_col):end) + ...
       RR(1:(end+s_row),1:(end+s_col)) - RR((1-s_row):end, (1-s_col):end);
    end
    IP(IP > Maximum) = Maximum;                          % The Reset operation
    NP = (IP + OP)/2;                                    % average with the previous Old Product
    OP = NP;                                             % get ready for the next comparison
    复制代码

    McCann99 Retinex算法

    McCann99 Retinex算法本质上与McCann Retinex算法没有区别,两者不同的就是在McCann99算法中,不再是使用螺旋式的路径来选取估计像素点,而是使用图像金字塔的方式逐层选取像素。算法同样经取点、比较、平均这几步进行迭代运算。

    图像金字塔的概念很简单,就是对图像进行下采样,以多分辨率的形式表示图像。最顶层的图像分辨率最低,底层的最高(一般为原图)。

    clip_image001

    图11.图像金字塔示意图(来自网络)

    如上图所示,McCann99算法就是从顶层开始让每一个像素点与其8个相邻的像素进行比较,估计反射率分量clip_image003;前一层计算结束之后对估计的反射率分类进行插值运算,使上一层估计的结果clip_image003[1]的图像与金字塔下一层图像尺寸相同,并再一次进行相同的比较运算;最终,对原始图像进行8邻域的比较结束后就能得到最终的结果,即增强后的图像了。其中,比较操作与McCann算法相同,都是相减后求平均,见上一节步骤4中描述。

    因此,McCann99算法,此处简化描述为以下几步:

    1. 将原图像变换到对数域clip_image005,彩色图像对各通道都进行对数变换;

    2. 初始化(计算图像金字塔层数;初始化常数图像矩阵clip_image007,该矩阵作为进行迭代运算的初始值);

    3. 从顶层开始,到最后一层进行8邻域比较运算,运算规则与MccCann Retinex算法相同,见上一节步骤4;

    4. 第n层运算结束后对第n层的运算结果clip_image009进行插值,变成原来的两倍,与n+1层大小相同(此处默认n越大越靠近底层);

    5. 当最底层计算完毕得到的clip_image011即最终增强后的图像。

    为了方便各位自己研究,下面我给出该算法源码供大家参考:

    复制代码

    function Retinex = retinex_mccann99(L, nIterations)


    global OPE RRE Maximum
    [nrows ncols] = size(L)
    ;                             % get size of the input image
    nLayers = ComputeLayers(nrows, ncols);               % compute the number of pyramid layers
    nrows = nrows/(2^nLayers);                           % size of image to process for layer 0
    ncols = ncols/(2^nLayers);
    if (nrows*ncols > 25)                                % not processing images of area > 25
      error(
    'invalid image size.')                       % at first layer
    end
    Maximum = max(L(:))
    ;                                 % maximum color value in the image
    OP = Maximum*ones([nrows ncols]);                    % initialize Old Product
    for layer = 0:nLayers
       RR = ImageDownResolution(L, 
    2^(nLayers-layer));   % reduce input to required layer size
       
       OPE = [zeros(nrows,
    1) OP zeros(nrows,1)];         % pad OP with additional columns
       OPE = [zeros(1,ncols+2); OPE; zeros(1,ncols+2)];  % and rows
       RRE = [RR(:,1) RR RR(:,end)];                     % pad RR with additional columns
       RRE = [RRE(1,:); RRE; RRE(end,:)];                % and rows
       
       for iter = 
    1:nIterations
         CompareWithNeighbor(-
    10);                     % North
         CompareWithNeighbor(-11);                     % North-East
         CompareWithNeighbor(01);                      % East
         CompareWithNeighbor(11);                      % South-East
         CompareWithNeighbor(10);                      % South
         CompareWithNeighbor(1, -1);                     % South-West
         CompareWithNeighbor(0, -1);                     % West
         CompareWithNeighbor(-1, -1);                    % North-West
       end
       NP = OPE(
    2:(end-1), 2:(end-1));
       OP = NP(:, [fix(1:0.5:ncols) ncols]);             %%% these two lines are equivalent with 
       OP = OP([fix(1:0.5:nrows) nrows], :);             %%% OP = imresize(NP, 2) if using Image
       nrows = 2*nrows; ncols = 2*ncols;                 % Processing Toolbox in MATLAB
    end
    Retinex = NP
    ;

    function CompareWithNeighbor(dif_row, dif_col)
    global OPE RRE Maximum

    % Ratio-Product operation
    IP = OPE(
    2+dif_row:(end-1+dif_row), 2+dif_col:(end-1+dif_col)) + ...
         RRE(
    2:(end-1),2:(end-1)) - RRE(2+dif_row:(end-1+dif_row), 2+dif_col:(end-1+dif_col));
         
    IP(IP > Maximum) = Maximum
    ;                          % The Reset step

    % ignore the results obtained 
    in the rows or columns for which the neighbors are undefined
    if (dif_col == -
    1) IP(:,1) = OPE(2:(end-1),2); end
    if (dif_col == +1) IP(:,end) = OPE(2:(end-1),end-1); end
    if (dif_row == -1) IP(1,:) = OPE(22:(end-1)); end
    if (dif_row == +1) IP(end,:) = OPE(end-12:(end-1)); end
    NP = (OPE(2:(end-1),2:(end-1)) + IP)/2;              % The Averaging operation
    OPE(2:(end-1), 2:(end-1)) = NP;

    function Layers = ComputeLayers(nrows, ncols)
    power = 
    2^fix(log2(gcd(nrows, ncols)));              % start from the Greatest Common Divisor
    while(power > 1 & ((rem(nrows, power) ~= 0) | (rem(ncols, power) ~= 0)))
       power = power/
    2;                                  % and find the greatest common divisor
    end                                                  % that is a power of 2
    Layers = log2(power)
    ;

    function Result = ImageDownResolution(A, blocksize)
    [rows, cols] = size(A)
    ;                              % the input matrix A is viewed as
    result_rows = rows/blocksize;                        % a series of square blocks
    result_cols = cols/blocksize;                        % of size = blocksize
    Result = zeros([result_rows result_cols]);
    for crt_row = 1:result_rows                          % then each pixel is computed as
       for crt_col = 
    1:result_cols                       % the average of each such block
          Result(crt_row, crt_col) = mean2(A(
    1+(crt_row-1)*blocksize:crt_row*blocksize, ...
                                           
    1+(crt_col-1)*blocksize:crt_col*blocksize));
       end
    en
    复制代码

    总结

          在上述两个经典的估计算法之后经过反对数变换就可以恢复成原格式的图像。通过试验可以发现,这些算法都还是有一定缺陷的,对于照度的估计后续还有很多算法如:单尺度Retinex (SSR)、多尺度Retinex (MSR)、可变框架的Retinex等等;还有针对增强后的光晕现象先用进行照度分割,然后在再计算等等方法,本质上都大同小异。这些改进算法这里不再进行介绍,有兴趣的朋友可以去下载些论文看看。有不明白的或者本文有错误的地方也希望各位能够指出,以免误导后面的读者。
    展开全文
  • Retinex算法详解

    万次阅读 多人点赞 2013-07-26 23:47:25
    Retinex是一种常用的建立在科学实验和科学分析基础上的图像增强方法,它是Edwin.H.Land于1963年提出的。就跟Matlab是由Matrix和Laboratory合成的一样,Retinex也是由两个单词合成的一个词语,他们分别是retina 和...

    Retinex是一种常用的建立在科学实验和科学分析基础上的图像增强方法,它是Edwin.H.Land1963年提出的。就跟Matlab是由MatrixLaboratory合成的一样,Retinex也是由两个单词合成的一个词语,他们分别是retina cortex,即:视网膜和皮层。Landretinex模式是建立在以下三个假设之上的:

    (1)真实世界是无颜色的,我们所感知的颜色是光与物质的相互作用的结果。我们见到的水是无色的,但是水膜肥皂膜却是显现五彩缤纷,那是薄膜表面光干涉的结果。

    (2)每一颜色区域由给定波长的红、绿、蓝三原色构成的;

    (3)三原色决定了每个单位区域的颜色。

    Retinex理论的基础理论是物体的颜色是由物体对长波(红色)、中波(绿色)、短波(蓝色)光线的反射能力来决定的,而不是由反射光强度的绝对值来决定的,物体的色彩不受光照非均匀性的影响,具有一致性,即retinex是以色感一致性(颜色恒常性)为基础的。不同于传统的线性、非线性的只能增强图像某一类特征的方法,Retinex可以在动态范围压缩、边缘增强和颜色恒常三个方面打到平衡,因此可以对各种不同类型的图像进行自适应的增强。

    40多年来,研究人员模仿人类视觉系统发展了Retinex算法,从单尺度Retinex算法改进成多尺度加权平均的Retinex算法,再发展成彩色恢复多尺度Retinex算法。

    一、单尺度SSR(Single Scale Retinex)

    一幅给定的图像S(x,y)可以分解为两个不同的图像:反射图像R(x,y)和亮度图像(也有人称之为入射图像)L(x,y),其原理如下图所示:




    展开全文
  • Retinex图像增强算法

    万次阅读 多人点赞 2018-07-22 15:57:39
    Retinex图像增强算法   Retinex是一种常用的建立在科学实验和科学分析基础上的图像增强方法,它是Edwin.H.Land于1963年提出的。就跟Matlab是由Matrix和Laboratory合成的一样,Retinex也是由两个单词合成的一个...

                                                Retinex图像增强算法

     

    Retinex是一种常用的建立在科学实验和科学分析基础上的图像增强方法,它是Edwin.H.Land于1963年提出的。就跟Matlab是由Matrix和Laboratory合成的一样,Retinex也是由两个单词合成的一个词语,他们分别是retina 和cortex,即:视网膜和皮层。Land的retinex模式是建立在以下三个假设之上的:

    • 真实世界是无颜色的,我们所感知的颜色是光与物质的相互作用的结果。我们见到的水是无色的,但是水膜—肥皂膜却是显现五彩缤纷,那是薄膜表面光干涉的结果。
    • 每一颜色区域由给定波长的红、绿、蓝三原色构成的;
    • 三原色决定了每个单位区域的颜色。

    Retinex理论的基础理论是物体的颜色是由物体对长波(红色)、中波(绿色)、短波(蓝色)光线的反射能力来决定的,而不是由反射光强度的绝对值来决定的,物体的色彩不受光照非均匀性的影响,具有一致性,即retinex是以色感一致性(颜色恒常性)为基础的。不同于传统的线性、非线性的只能增强图像某一类特征的方法,Retinex可以在动态范围压缩、边缘增强和颜色恒常三个方面达到平衡,因此可以对各种不同类型的图像进行自适应的增强。

    40多年来,研究人员模仿人类视觉系统发展了Retinex算法,从单尺度Retinex算法,改进成多尺度加权平均的MSR算法,再发展成彩色恢复多尺度MSRCR算法

    一. 单尺度SSR(Single Scale Retinex)

    1. 原理

    一幅给定的图像S(x,y)可以分解为两个不同的图像:反射图像R(x,y)和入射图像(也有人称之为亮度图像)L(x,y),其原理图如下所示:
     

    如上图所示,图像可以看做是入射图像和反射图像构成,入射光照射在反射物体上,通过反射物体的反射,形成反射光进入人眼。最后形成的图像可以如下公式表示:

                                                      I(x,y)=L(x,y)*R(x,y) (乘,非卷积)  (1-1)

      式中: I(x,y)代表被观察或照相机接收到的图像信号;L(x,y)代表环境光的照射分量 ;R(x,y)表示携带图像细节信息的目标物体的反射分量 。

      将(1-1)式两边取对数,则可抛开入射光的性质得到物体的本来面貌,即有关系式 :

                                                   Log[R(x,y)] = Log[I(x,y)]-Log[L(x,y)];      (1-2)

    要求得R(x,y)只需得到L(x,y)即可,但是根据数学的理论,L(x,y)是不能够求得的,只能近似求出。我们用I(x,y)和一个高斯核的卷积来近似表示L(x,y)。所以R(x,y)可用下式表示:

                                                      Log(R(x,y))=(Log(I(x,y))-Log(I(x,y)*G(x,y)))  (1-3)

    上式中*代表卷积,G(x,y)代表高斯核,最后我们看到的图像是对R(x,y)映射到[0,255]上的结果,一般取线性映射。

    所以,笼统的讲,Retinex算法是去掉光照的影响,还原图像的本来面目。

    对上面的理论的进行一个简单的注释吧。把这个技术运用到图像处理上,就是针对我们现在已经获得的一副图像数据I(x,y),计算出对应的R(x,y),则R(x,y)认为是增强后的图像,现在的关键是如何得到L(X,Y)。Retinex理论的提出者指出这个L(x,y)可以通过对图像数据I(x,y)进行高斯模糊而得到,很多论文中都列出了那个中心/围绕函数以及需要归一化的K值,搞的很多新手都不明白是什么了,其实就是一个模糊而已。从实际运用的角度来说,也可以用均值模糊来代替高斯模糊。

         因此这个算法的细路就很简单了,具体步骤如下:

         1、输入: 原始图像数据I(x,y),尺度(也就是所谓的模糊的半径)

         2、处理:(1) 计算原始图像按指定尺度进行模糊后的图像 L(x,y);

                  (2) 按照2-2式的计算方法计算出 Log[R(x,y)]的值。

                  (3) 将 Log[R(x,y)]量化为0到255范围的像素值,作为最终的输出。

    可以看得出,算法很简单,其核心的东西还是在于高斯模糊的实现。关于高斯模糊,网上有很多快速优化的文章参考,具体的参考代码可能很少有好人提供的。

    注意到一点,似乎在量化的时候没有谁会将 Log[R(x,y)]进行Exp函数的运算而直接得到R(x,y),至于为什么,我无法给出明确的答案。

    量化的方式其实有很多种,而这个方法在很大的程度上对处理的效果有着决定性的影响。至今我没看到有哪一篇论文对这一块讲的很清楚,也不知道他们的那些结果是如何取得的,一种最简单的方式就是计算出Log[R(x,y)]的最大值Max和最小值Min,然后对每一个值Value,进行线性量化,公式为:

                                                R(x,y) = ( Value - Min ) / (Max - Min) * (255-0)      (1-4)

    SSR:

    #SSR
    
    def replaceZeroes(data):
        min_nonzero = min(data[nonzero(data)])
        data[data == 0] = min_nonzero
        return data
    
    
    def SSR(img,size):
        L_blur = cv2.GaussianBlur(img,(size,size),0)
        eps = float(1e-10)
    
        h,w = img.shape[:2]
        dst_img = zeros((h,w),dtype = float32)
        dst_Lblur = zeros((h, w),dtype=float32)
        dst_R = zeros((h, w), dtype=float32)
    
        img = replaceZeroes(img)
        L_blur = replaceZeroes(L_blur)
        cv2.log(img,dst_img)
        cv2.log(L_blur,dst_Lblur)
        log_R = cv2.subtract(dst_img,dst_Lblur)
    
        cv2.normalize(log_R,dst_R,0,255,cv2.NORM_MINMAX)
        log_uint8 = cv2.convertScaleAbs(dst_R)
     
    
        minvalue,maxvalue,minloc,maxloc = cv2.minMaxLoc(log_R)
        for i in range(h):
            for j in range(w):
                log_R[i,j] = (log_R[i,j]-minvalue)*255.0/(maxvalue-minvalue)
        log_uint8 = cv2.convertScaleAbs(log_R)
        return log_uint8

    二. 多尺度MSR(Multi-Scale Retinex)

    MSR是在SSR基础上发展来的,优点是可以同时保持图像高保真度与对图像的动态范围进行压缩的同时,MSR也可实现色彩增强、颜色恒常性、局部动态范围压缩、全局动态范围压缩,也可以用于X光图像增强。

    为了得到更好的效果,人们又开发出所谓的多尺度视网膜增强算法(MSR, Multi-Scale Retinex),最为经典的就是3尺度的,大、中、小,既能实现图像动态范围的压缩,又能保持色感的一致性较好。同单尺度相比,该算法有在计算Log[R(x,y)]的值时步骤有所不同:

    (1)需要对原始图像进行每个尺度的高斯模糊,得到模糊后的图像Li(x,y),其中小标i表示尺度数。

    (2) 对每个尺度下进行累加计算

    Log[R(x,y)] =  Log[R(x,y)] + Weight(i)* ( Log[Ii(x,y)]-Log[Li(x,y)]);  

    其中Weight(i)表示每个尺度对应的权重,要求各尺度权重之和必须为1,经典的取值为等权重。

    其他的步骤和单尺度的没有区别。

    为表述方便,还是贴出其基本的计算原理:

    上式中,I为原始输入图像,F是滤波函数,一般为高斯函数,N为尺度的数量,W为每个尺度的权重,一般都为1/N, R表示在对数域的图像的输出。

    MSR

    #MSR
    def replaceZeroes(data):
        min_nonzero = min(data[nonzero(data)])
        data[data == 0] = min_nonzero
        return data
    
    
    def MSR(img, scales):
        weight = 1/3.0
        scales_size = 3
    
        h, w = img.shape[:2]
        dst_img = zeros((h, w), dtype=float32)
        dst_Lblur = zeros((h, w), dtype=float32)
        dst_R = zeros((h, w), dtype=float32)
        log_R = zeros((h, w), dtype=float32)
    
        for i in range(0,scales_size):
            img = replaceZeroes(img)
            L_blur = cv2.GaussianBlur(img, (scales[i], scales[i]), 0)
            L_blur = replaceZeroes(L_blur)
            cv2.log(img, dst_img)
            cv2.log(L_blur, dst_Lblur)
            log_R += weight*cv2.subtract(dst_img, dst_Lblur)
    
    
        cv2.normalize(log_R, dst_R, 0, 255, cv2.NORM_MINMAX)
        log_uint8 = cv2.convertScaleAbs(dst_R)
    
        return log_uint8

    三. 带色彩恢复的多尺度MSR(Multi-Scale Retinex with Color Restoration)

      由于R是对数域的输出,要转换为数字图像,必须将他们量化为[0,255]的数字图像范畴,关于这个量化的算法,有这极为重要的意义,他的好坏直接决定了最终输出的图像的品质。

      目前,结合上述文章中提出的一些过程,有4种方式进行处理:

      第一种,也是最容易想到的就是,直接线性量化,即采用下式进行处理:

      这种方式,由于Retinex数据处理后的高动态特性,数据分布很广,会出现严重的两极化现象,一般难以获得满意的结果。

      第二种,就是在经典的MSRCR文章《A Multiscale Retinex for Bridging the Gap Between Color Images and the Human Observation of Scenes》中提出的Canonical Gain/set 算法。计算公式如:

        

        

      其中G和b为经验参数。

      第三种,实在上述文章中提到的Simplest Color Balance(我简写为SCR)方式,这种方式的处理类似于Photoshop中的自动色阶,他把数据按照一定的百分比去除最小和最大的部分,然后中间的部分重新线性量化到0和255之间。

      第四种,就是GIMP的Retinex算法,这个可详见 带色彩恢复的多尺度视网膜增强算法(MSRCR)的原理、实现及应用 一文的描述。

      还有一种方式,就是大家知道HDR的过程吧,他也是将高动态的数据量化到图像的可视范围,因此可以直接将这类算法应用与这个问题上。我也做了实验,效果似乎一般。

      在用第二种或第三种方式处理时,最好还需要有个Color Restoration的过程,因为如果直接对MSR处理的结果进行量化,得到的图像往往整体偏灰度,这是由于原始的彩色值经过log处理后的数据范围就比较小了,这样各通道之间的差异也很小,而之后的线性量化比log曲线要平滑很多,因此整体就丧失了彩色。

    论文中提出了修正方式如下:

              

              

              

     

       其中β=46,α=125为经验参数,但是最终我的分析认为β不可能取这么大,取1试验表明效果还不错。

       对于一些原始图像HUE较为合理的图,如果用经典的MSRCR算法,会导致处理后的图容易偏色,上述论文提出了对图像的Intensity数据进行Retinex处理,然后再把数据根据原始的RGB的比例映射到每个通道,这样就能在保留原始颜色分布的基础上增强图像,文章中称其为MSRCP。

    MSRCR算法步骤:

    MSRCR实现

    #MSRCR
    def replaceZeroes(data):
        min_nonzero = min(data[nonzero(data)])
        data[data == 0] = min_nonzero
        return data
    
     #simple color balance
    def simple_color_balance(input_img,out_img,s1,s2):
        h,w = input_img.shape[:2]
        sort_img = input_img.copy()
        one_dim_array = sort_img.flatten()#转化为一维数组
        sort_array = sorted(one_dim_array)#对一维数组按升序排序
    
        per1 = int((h*w)*s1/100)
        minvalue = sort_array[per1]
    
        per2 = int((h*w)*s2/100)
        maxvalue = sort_array[(h*w)-1-per2]
    
        #实施简单白平衡算法
        if(maxvalue<=minvalue):
            for i in range(h):
                for j in range(w):
                    out_img[i,j] = maxvalue
        else:
            scale = 255.0/(maxvalue-minvalue)
            for m in range(h):
                for n in range(w):
                    if(input_img[m,n] < minvalue):
                        out_img[m,n] = 0
                    elif(input_img[m,n] > maxvalue):
                        out_img[m, n] = 255
                    else:
                        out_img[m, n] = scale*(input_img[m,n]-minvalue)#映射中间段的图像像素
    
        out_img= cv2.convertScaleAbs(out_img)
    
    
    def MSRCR(img,MSRCR_Out,scles,s1,s2):
        h,w = img.shape[:2]
        scles_size = 3
        epc = float(1e-4)
        B = img[:,:,0]
        G = img[:, :, 1]
        R = img[:, :, 2]
    
    
        dst_img = zeros((h, w), dtype=float32)
        dst_Lblur = zeros((h, w), dtype=float32)
        log_R = zeros((h, w), dtype=float32)
        I =  zeros((h, w), dtype=float32)
    
        I = (B+G+R)
        I = replaceZeroes(I)
    
        for j in range(3):
            img[:, :, j] = replaceZeroes(img[:, :, j])
            for i in range(0, scles_size):
                L_blur = cv2.GaussianBlur(img[:, :, j], (scales[i], scales[i]), 0)
                L_blur = replaceZeroes(L_blur)
                cv2.log(img[:, :, j], dst_img)
                cv2.log(L_blur, dst_Lblur)
                log_R += cv2.subtract(dst_img, dst_Lblur)
            MSR = log_R / 3.0
            MSRCR = MSR*(cv2.log(125.0*img[:, :, j]) - cv2.log(I))
            simple_color_balance(MSRCR,MSRCR_Out[:,:,j],s1,s2)
    

    MSRCP算法:

    MSRCP实现:

    ##MSRCP
    def replaceZeroes(data):#这个函数主要是防止取对数的时候,出现去穷小的结果
        min_nonzero = min(data[nonzero(data)])
        data[data == 0] = min_nonzero
        return data
    
     #simple color balance
    def simple_color_balance(input_img,out_img,s1,s2):
        h,w = input_img.shape[:2]
        sort_img = input_img.copy()
        one_dim_array = sort_img.flatten()#转化为一维数组
        sort_array = sorted(one_dim_array)#对一维数组按升序排序
    
        per1 = int((h*w)*s1/100)
        minvalue = sort_array[per1]
    
        per2 = int((h*w)*s2/100)
        maxvalue = sort_array[(h*w)-1-per2]
    
        #实施简单白平衡算法
        if(maxvalue<=minvalue):
            for i in range(h):
                for j in range(w):
                    out_img[i,j] = maxvalue
        else:
            scale = 255.0/(maxvalue-minvalue)
            for m in range(h):
                for n in range(w):
                    if(input_img[m,n] < minvalue):
                        out_img[m,n] = 0
                    elif(input_img[m,n] > maxvalue):
                        out_img[m, n] = 255
                    else:
                        out_img[m, n] = scale*(input_img[m,n]-minvalue)#映射中间段的图像像素
    
    
    
    def MSRCP(img,scles,s1,s2):
        h,w = img.shape[:2]
        scles_size = 3
        epc = float(1e-4)
        B_chan = img[:,:,0]
        G_chan = img[:, :, 1]
        R_chan = img[:, :, 2]
    
    
        dst_img = zeros((h, w), dtype=float32)
        dst_Lblur = zeros((h, w), dtype=float32)
        log_R = zeros((h, w), dtype=float32)
        I =  zeros((h, w), dtype=float32)
        Int1 = zeros((h, w), dtype=float32)
        R_channel_out = zeros((h, w), dtype=float32)
        G_channel_out = zeros((h, w), dtype=float32)
        B_channel_out = zeros((h, w), dtype=float32)
        MSRCP_Out_img = zeros(img.shape, dtype=float32)
        MSRCP_Out = zeros(img.shape, dtype=uint8)
    
        I = (B_chan+G_chan+R_chan)/3.0
        I = replaceZeroes(I)
    
    
        for i in range(0, scles_size):
            L_blur = cv2.GaussianBlur(I, (scales[i], scales[i]), 0)
            L_blur = replaceZeroes(L_blur)
            cv2.log(I, dst_img)
            cv2.log(L_blur, dst_Lblur)
            log_R += (dst_img - dst_Lblur)
        MSR = log_R / 3.0
        simple_color_balance(MSR,Int1,s1,s2)
    
    
        for i in range(h):
            for j in range(w):
                maxtmp = max(B_chan[i,j],G_chan[i,j])
                B = max(maxtmp,R_chan[i,j])
                if(I[i,j] == 0):
                    I[i, j] = 1
                A = min(255/B,Int1[i,j]/I[i,j])
                R_channel_out[i,j] = A*R_chan[i,j]
                G_channel_out[i, j] = A * G_chan[i, j]
                B_channel_out[i, j] = A * B_chan[i, j]
    
        MSRCP_Out_img = cv2.merge([B_channel_out,G_channel_out,R_channel_out])
        MSRCP_Out = cv2.convertScaleAbs(MSRCP_Out_img)
    
        return MSRCP_Out

    四. 图像效果

     

    Original

    SSR

     

    MSR

                  从上到下分别是原始图、SSR、MSR、MSRCR、MSRCP,其中多尺度图像中的尺度因子都是15,101,301

     参考文献:

    关于Retinex图像增强算法的一些新学习。作者: laviewpbt   时间: 2014.6.26    联系QQ:  1664462947

    Retinex图像增强算法(SSR, MSR, MSRCR)详解及其OpenCV源码

    msrcr(Multi-Scale Retinex with Color Restoration) 带色彩恢复的多尺度视网膜增强算法 整理

    Multiscale Retinex

     

     

     

     

     

    展开全文
  • 低照度图像增强之卷积神经网络RetinexNet

    万次阅读 热门讨论 2019-03-07 11:14:57
    转载请标注:... 目录 一丶Retinex理论——图像分解 二丶RetinexNet卷积神经网络 1.训练数据说明 ... 低照度图像增强一直是计算机视觉领域的一个热门研究方向,之前传统的基于Retinex理论的研究方法已经...

    转载请标注:https://blog.csdn.net/weixin_38285131

     

    目录

    一丶Retinex理论——图像分解

    二丶RetinexNet卷积神经网络

    1.训练数据说明

    2.分解网络——Decom

    3.增强网络——Relight

    4.结果展示

             低照度图像增强一直是计算机视觉领域的一个热门研究方向,之前传统的基于Retinex理论的研究方法已经出现很多,比如:MSR,MSRCR,MSRCP等,这些方法在低照度图像增强方面效果有明显提升,上一篇博客主要介绍了基于Retinex理论的集中图像增强方法,并给出了python代码。博客链接如下:   
    [图像增强Retinex算法之python实现——MSR,MSRCR,MSRCP,autoMSRCR](https://blog.csdn.net/weixin_38285131/article/details/88097771)
            但是基于传统的图像图像处理方法处理每一张图像会比较耗时,一副4000*8000的图像需要耗时十几分钟,这样就没法批量处理低照度图像,因此本文介绍一种基于Retinex理论的卷积神经网络模型——RetinexNet,该模型是北大的童鞋在2018年发表在BMVC上的,论文名字是——Deep Retinex Decomposition for Low-Light Enhancement
         [论文PDF]
        RetinexNet项目介绍,数据集,PPT等

    一丶Retinex理论——图像分解

    这个理论在上一篇博客中已有介绍,任何一幅图像可以分解为光照图像(illumination)和反射图像(reflectance),反射图像是物体的本身性质决定的即为不变的部分,光照图则受外界影响比较到,可以去除光照影响或者对光照图像进行校正,则可以达到增强图像的目的。如下图所示:

    左边即为低照度图像,中间即为光照图,右边即为反射图像,原图S(x,y)=I(x,y)*R(x,y),将图像变换到log域则变成了相减,然后将光照图像减去即可达到增强图像的目的。

    二丶RetinexNet卷积神经网络

    摘抄自论文摘要:

    Retinex理论是一种有效的微光图像增强工具。假设观测图像可以分解为反射图像和照度图像。大多数现有的基于Retinex卢纶的方法都为这种高度不适定的分解精心设计了手工约束和参数,当应用于各种场景时,这些约束和参数可能会受到模型容量的限制。Retinex包括一个用于分解的分解网络(Decom)和一个用于照明调节(Relight)的增强网络。在分解网络的训练过程中,没有分解反射和光照的地面真值。该网络的学习只有关键的约束条件,包括低/正常光图像共享的一致反射率,以及光照的平滑度。在分解的基础上,利用增强网络增强网对光照进行后续的亮度增强,联合去噪对反射率进行去噪操作。视网膜网是端到端可训练的,学习分解的性质有利于亮度的调节。

    理论整体路线即为下图所示:

    输入:低照度图像

    分解网络(Decom):对图像进行分解

    增强网络(Relight):对图像进行增强和调整

    输出:校正之后的图像

    1.训练数据说明

    数据主要是利用单反相机不同的光圈值和感光度拍摄同一个场景,作为图像对进行训练,也就是说同一场景拍摄一个低照度图像,然后在拍摄一个正常图像进行训练,具体数据如下图所示:

    作图为正常拍摄图像,右图为低照度图像,大概拍摄了500张图像对作为训练数据

    2.分解网络——Decom

    文中的分解网络应该是一个五层的卷积神经网络,代码中是利用relu函数进行激活,没有什么特别的处理,具体结构如下:

    可以看到将图像对中的低照度图像和正常图像作为输入数据送入卷积神经网络进行分解,最后得到光照图像和反射图像,根据Retinex理论反射图像基本接近,但是两者光照图像相差很大,这样把每一张训练图像进行分解,然后再送入后面的增强网络进行训练。

    3.增强网络——Relight

    增强网络,我看代码应该是一个九层的卷积神经网络,利用relu进行激活,中间还进行最邻近差值的resize操作,具体如下图:


    对刚才分解的反射图像进行去噪音操作,他中间用了平滑,但是我觉得用了平滑之后降低了图像本身的锐度,图像变得模糊,个人觉得这一步还应该做一下增强处理,回头看看能不能修改一下这个中间处理操作。应该可以用拉普拉斯进行一下图像恢复吧,我觉得这一步降低图像锐度不太好,重建图像稍显模糊。

    4.结果展示

    中间即为校正之后的,右边为正常光照图像,虽然和正常图像比不了,但是已经很不错了,

    最后与其他算法做了一些对比工作,感觉各有千秋吧,不过都有一定的亮度提升,还是很值得研究一哈的 做一下改进。

    下一步,我准备用这个神经网络训练一下自己的数据,然后测试一下增强效果。

    数据集百度网盘地址

    github地址

     

    转载请注明地址:https://blog.csdn.net/weixin_38285131

     


     

    展开全文
  • Retinex

    万次阅读 2017-05-05 10:19:31
    Retinex图像增强算法 前一段时间研究了一下图像增强算法,发现Retinex理论在彩色图像增强、图像去雾、彩色图像恢复方面拥有很好的效果,下面介绍一下我对该算法的理解。 Retinex理论 Retinex理论始于Land和...
  • retinex算法原理

    千次阅读 2018-08-25 15:55:20
    https://blog.csdn.net/carson2005/article/details/9502053 https://blog.csdn.net/ajianyingxiaoqinghan/article/details/71435098
  • OpenCV—Python Retinex图像增强算法

    千次阅读 多人点赞 2019-07-02 15:05:37
    Retinex图像增强算法一、Retinex理论二、Retinex理论的理解三、Retinex理论应用 一、Retinex理论 Retinex理论始于Land和McCann于20世纪60年代作出的一系列贡献,其基本思想是人感知到某点的颜色和亮度并不仅仅取决于...
  • 《数字图像处理高级应用》中的代码,注意是单尺度的Retinex呦~
  • Retinex理解

    千次阅读 2018-08-27 22:02:11
    Retinex是一种常用的建立在科学实验和科学分析基础上的图像增强方法,它是Edwin.H.Land于1963年提出的。就跟Matlab是由Matrix和Laboratory合成的一样,Retinex也是由两个单词合成的一个词语,他们分别是retina 和...
  • Retinex

    2019-09-28 19:27:34
    http://dragon.larc.nasa.gov/retinex/ Retinex Image processing NASA Langley Research Center(让图像象你实际看见的...RETINEX: 解释发音're-tin-ex, 'ret-nex;名词noun;复数形式(pl) retinexes; 解释:from Medi...
  • 1、Retinex理论 Retinex 是两个单词合成的,它们分别是 retina (视网膜)和 cortex (皮层),因此 Retinex 理论很多时候也被称为是视网膜皮层理论。 最初的基于 Retinex 理论的模型提出了一个人眼视觉系统 (HVS, ...
  • retinex

    千次阅读 2017-08-26 15:41:29
    网上关于Retinex的资料很多,在Github上下载的代码跑了一下,效果还不错,见下图(图像拼接方法见我的代码段 转自http://blog.csdn.net/CSDNMicrosoftCSDN/article/details/50207101?locationNum=3&fps=1...1.“Retinex
  • Retinex

    千次阅读 2014-05-29 08:28:58
    Retinex是一种常用的建立在科学实验和科学分析基础上的图像增强方法,它是Edwin.H.Land于1963年提出的。就跟Matlab是由Matrix和Laboratory合成的一样,Retinex也是由两个单词合成的一个词语,他们分别是retina 和...
  • 图像去雾(二)Retinex图像增强算法

    万次阅读 2019-07-23 14:47:16
    前一段时间研究了一下图像增强算法,发现Retinex理论在彩色图像增强、图像去雾、彩色图像恢复方面拥有很好的效果,下面介绍一下我对该算法的理解。 Retinex理论 Retinex理论始于Land和McCann于20世纪60年代作出的...
  • Retinex图像增强算法代码

    千次阅读 2016-10-23 17:13:37
    http://www.cnblogs.com/sleepwalker/p/3676600.html?utm_source=tuicool ...     Retinex理论 Retinex理论始于Land和McCann于20世纪60年代作出的一系列贡献,其基本思想是
  • 在http://write.blog.csdn.net/postedit/78212814中介绍了同态滤波算法,本片继续总结retinex算法,不过开始之前先介绍一下色彩恒常性的概念: 色彩恒常性 在人体生物学领域中,颜色恒常性是指当照射物体表面的...
  • Retinex图像增强算法

    千次阅读 2019-02-28 16:05:26
    amp;utm_medium=referral ...前段时间看了些图像增强的问题,查看了一些比较实用的评论文章,这篇文章作者发现Retinex理论在彩色图像增强、图像去雾、彩色图像恢复方面拥有很好的效果,下面就介绍一下作者对该算...
  • retinex ("Retinex by two bilateral filters" by M. Elad, 2005) shape from shading algorithm by Horn and Ikeuchi ("The Variational Approach to Shape from Shading" by B. Horn and M. Brooks, 1985) optical...
  • Retinex图像增强算法(SSR, MSR, MSRCR)详解及其OpenCV源码

    万次阅读 多人点赞 2017-05-08 20:54:26
    Retinex图像增强算法(SSR, MSR, MSRCR)详解及其OpenCV源码Retinex是一种常用的建立在科学实验和科学分析基础上的图像增强方法,它是Edwin.H.Land于1963年提出的。就跟Matlab是由Matrix和Laboratory合成的一样,...
  • Retinex图像增强算法代码

    万次阅读 2015-03-26 16:09:59
    http://www.cnblogs.com/sleepwalker/p/3676600.html?utm_source=tuicool ...    Retinex理论 Retinex理论始于Land和McCann于20世纪60年代作出的一系列贡献,其基本思想是人感知到某点的颜色和

空空如也

1 2 3 4 5 ... 20
收藏数 1,042
精华内容 416
关键字:

retinex