首页 > 其他 > 详细

stretchlim函数分析

时间:2015-06-30 14:26:40      阅读:265      评论:0      收藏:0      [点我收藏+]

在看imadjust代码时,看到stretchlim函数,特此分析一下,代码注释如下

function lowhigh = stretchlim(varargin)
%STRETCHLIM Find limits to contrast stretch an image.
%   LOW_HIGH = STRETCHLIM(I,TOL) returns a pair of gray values that can be
%   used by IMADJUST to increase the contrast of an image.
%
%   TOL = [LOW_FRACT HIGH_FRACT] specifies the fraction of the image to
%   saturate at low and high pixel values.
%
%   If TOL is a scalar, TOL = LOW_FRACT, and HIGH_FRACT = 1 - LOW_FRACT,
%   which saturates equal fractions at low and high pixel values.
%
%   If you omit the argument, TOL defaults to [0.01 0.99], saturating 2%.
%
%   If TOL = 0, LOW_HIGH = [min(I(:)); max(I(:))].
%
%   LOW_HIGH = STRETCHLIM(RGB,TOL) returns a 2-by-3 matrix of pixel value
%   pairs to saturate each plane of the RGB image. TOL specifies the same
%   fractions of saturation for each plane.
%
%   Class Support
%   -------------
%   The input image can be uint8, uint16, int16, double, or single, and must
%   be real and nonsparse. The output limits are double and have values
%   between 0 and 1.
%
%   Note
%   ----
%   If TOL is too big, such that no pixels would be left after saturating
%   low and high pixel values, then STRETCHLIM returns [0; 1].
%
%   Example
%   -------
%       I = imread(pout.tif);
%       J = imadjust(I,stretchlim(I),[]);
%       figure, imshow(I), figure, imshow(J)
%
%   See also BRIGHTEN, DECORRSTRETCH, HISTEQ, IMADJUST.

%   Copyright 1999-2005 The MathWorks, Inc.
%   $Revision: 1.7.4.8 $ $Date: 2005/11/15 01:02:11 $

[img,tol] = ParseInputs(varargin{:});

if isa(img,uint8)
    nbins = 256;
else
    nbins = 65536;
end

tol_low = tol(1);
tol_high = tol(2);
 
 % 获取第三维的维数
p = size(img,3);

if tol_low < tol_high
    ilowhigh = zeros(2,p);
    % 对于第三维的每一层进行寻找
    for i = 1:p                          % Find limits, one plane at a time
        N = imhist(img(:,:,i),nbins);
        cdf = cumsum(N)/sum(N); %cumulative distribution function
        ilow = find(cdf > tol_low, 1, first);        %找到满足累计频率>tol_low的下标
        ihigh = find(cdf >= tol_high, 1, first);    %找到满足累计频率>=tol_low的下标
        if ilow == ihigh   % this could happen if img is flat
            ilowhigh(:,i) = [1;nbins];
        else
            ilowhigh(:,i) = [ilow;ihigh];
        end
    end
    lowhigh = (ilowhigh - 1)/(nbins-1);  % convert to range [0 1]

else
    %   tol_low >= tol_high, this tolerance does not make sense. For example, if
    %   the tolerance is .5 then no pixels would be left after saturating
    %   low and high pixel values. In all of these cases, STRETCHLIM
    %   returns [0; 1]. See gecks 278249 and 235648.
    lowhigh = repmat([0;1],1,p);
end


%-----------------------------------------------------------------------------
function [img,tol] = ParseInputs(varargin)

iptchecknargin(1, 2, nargin, mfilename);

img = varargin{1};
iptcheckinput(img, {uint8, uint16, double, int16, single}, {real, ...
    nonsparse}, mfilename, I or RGB, 1);
if (ndims(img) > 3)
    msgId = Images:stretchlim:dimTooHigh;
    error(msgId,STRETCHLIM only supports individual images.);
end

% 默认值
tol = [.01 .99]; %default
if nargin == 2
    tol = varargin{2};
    switch numel(tol)    %判断tol数组元素个数
        case 1
            tol(2) = 1 - tol;

        case 2
            if (tol(1) >= tol(2))
                msgId = Images:stretchlim:invalidTolOrder;
                error(msgId,TOL(1) must be less than TOL(2).);
            end
        otherwise
            msgId = Images:stretchlim:invalidTolSize;
            error(msgId,TOL must have 1 or 2 elements.);
    end
end

if ( any(tol < 0) || any(tol > 1) || any(isnan(tol)) )
    msgId = Images:stretchlim:tolOutOfRange;
    error(msgId,TOL must be in the range [0 1].);
end

主函数为stretchlim,其中子函数ParseInputs用于获取参数。

 

主函数中关键部分为

if tol_low < tol_high
    ilowhigh = zeros(2,p);
    % 对于第三维的每一层进行寻找
    for i = 1:p                          % Find limits, one plane at a time
        N = imhist(img(:,:,i),nbins);
        cdf = cumsum(N)/sum(N); %cumulative distribution function
        ilow = find(cdf > tol_low, 1, first);        %找到满足累计频率>tol_low的下标
        ihigh = find(cdf >= tol_high, 1, first);    %找到满足累计频率>=tol_low的下标
        if ilow == ihigh   % this could happen if img is flat
            ilowhigh(:,i) = [1;nbins];
        else
            ilowhigh(:,i) = [ilow;ihigh];
        end
    end
    lowhigh = (ilowhigh - 1)/(nbins-1);  % convert to range [0 1]

函数imhist是用于获取图像数据直方图,返回值是个一维矩阵,保存着图像中每个灰度等级的像素个数,如上,如果nbins等于256,代表灰度范围为0~255,则imhist获取图像img中符合每个灰度等级的像素个数,例如灰度等级3对应数组N下标4,图像中灰度等级为3的像素个数为5,则N(4)=5。

 

cdf = cumsum(N)/sum(N);

这一行中cumsum(N)计算一个数组各个元素的累加值,例如数组 N = [1 3 5],则cumsum(N) = [1 4 9],sum(N)获取数组N的元素个数,因此这个式子代表意思是每个灰度等级的累积频率,例子中sum(N)=3,则cdf=[1/3 4/3 9/3]。

 

ilow = find(cdf > tol_low, 1, first);        %找到满足累计频率>tol_low的下标
ihigh = find(cdf >= tol_high, 1, first);    %找到满足累计频率>=tol_low的下标

找到下标ilow和ihigh,可对应满足条件的灰度等级,因为cdf数组中下标也就是对应灰度等级的值加1。

 

lowhigh = (ilowhigh - 1)/(nbins-1);  % convert to range [0 1]

归一化,将范围[ilow ihigh]映射到[0 1]

 

stretchlim函数分析

原文:http://www.cnblogs.com/cpointer/p/4610101.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!