首页 技术 正文
技术 2022年11月15日
0 收藏 572 点赞 3,488 浏览 3828 个字

在看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;
endtol_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
endif ( 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]

相关推荐
python开发_常用的python模块及安装方法
adodb:我们领导推荐的数据库连接组件bsddb3:BerkeleyDB的连接组件Cheetah-1.0:我比较喜欢这个版本的cheeta…
日期:2022-11-24 点赞:878 阅读:9,033
Educational Codeforces Round 11 C. Hard Process 二分
C. Hard Process题目连接:http://www.codeforces.com/contest/660/problem/CDes…
日期:2022-11-24 点赞:807 阅读:5,520
下载Ubuntn 17.04 内核源代码
zengkefu@server1:/usr/src$ uname -aLinux server1 4.10.0-19-generic #21…
日期:2022-11-24 点赞:569 阅读:6,368
可用Active Desktop Calendar V7.86 注册码序列号
可用Active Desktop Calendar V7.86 注册码序列号Name: www.greendown.cn Code: &nb…
日期:2022-11-24 点赞:733 阅读:6,148
Android调用系统相机、自定义相机、处理大图片
Android调用系统相机和自定义相机实例本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显…
日期:2022-11-24 点赞:512 阅读:7,781
Struts的使用
一、Struts2的获取  Struts的官方网站为:http://struts.apache.org/  下载完Struts2的jar包,…
日期:2022-11-24 点赞:671 阅读:4,862