improfile.m
来自「有关matlab的电子书籍有一定的帮助希望有用」· M 代码 · 共 398 行
M
398 行
function varargout = improfile(varargin)
%IMPROFILE Compute pixel-value cross-sections along line segments.
% IMPROFILE computes the intensity values along a line or a
% multiline path in an image. IMPROFILE selects equally spaced
% points along the path you specify, and then uses
% interpolation to find the intensity value for each
% point. IMPROFILE works with grayscale intensity images and
% RGB images.
%
% If you call IMPROFILE with one of these syntaxes, it operates
% interactively on the image in the current axes:
%
% C = IMPROFILE
% C = IMPROFILE(N)
%
% N specifies the number of points to compute intensity values
% for. If you do not provide this argument, IMPROFILE chooses a
% value for N, roughly equal to the number of pixels the path
% traverses.
%
% You specify the line or path using the mouse, by clicking on
% points in the image. Press <BACKSPACE> or <DELETE> to remove
% the previously selected point. A shift-click, right-click, or
% double-click adds a final point and ends the selection;
% pressing <RETURN> finishes the selection without adding a
% point. When you finish selecting points, IMPROFILE returns
% the interpolated data values in C. C is an N-by-1 vector if
% the input is a grayscale intensity image, or an N-by-1-by-3
% array if the input image is an RGB image.
%
% If you omit the output argument, IMPROFILE displays a plot of
% the computed intensity values. If the specified path consists
% of a single line segment, IMPROFILE creates a two-dimensional
% plot of intensity values versus the distance along the line
% segment; if the path consists of two or more line segments,
% IMPROFILE creates a three-dimensional plot of the intensity
% values versus their x- and y-coordinates.
%
% You can also specify the path noninteractively, using these
% syntaxes:
%
% C = IMPROFILE(I,xi,yi)
% C = IMPROFILE(I,xi,yi,N)
%
% xi and yi are equal-length vectors specifying the spatial
% coordinates of the endpoints of the line segments.
%
% You can use these syntaxes to return additional information:
%
% [CX,CY,C] = IMPROFILE(...)
% [CX,CY,C,xi,yi] = IMPROFILE(...)
%
% CX and CY are vectors of length N, containing the spatial
% coordinates of the points at which the intensity values are
% computed.
%
% To specify a nondefault spatial coordinate system for the
% input image, use these syntaxes:
%
% [...] = IMPROFILE(x,y,I,xi,yi)
% [...] = IMPROFILE(x,y,I,xi,yi,N)
%
% x and y are 2-element vectors specifying the image XData and
% YData.
%
% [...] = IMPROFILE(...,METHOD) uses the specified
% interpolation method. METHOD is a string that can have one of
% these values:
%
% 'nearest' (default) uses nearest neighbor interpolation
%
% 'bilinear' uses bilinear interpolation
%
% 'bicubic' uses bicubic interpolation
%
% If you omit the METHOD argument, IMPROFILE uses the default
% method of 'nearest'.
%
% Class Support
% -------------
% The input image can be of class uint8 or double. All other
% inputs and outputs are of class double.
%
% Example
% -------
% I = imread('alumgrns.tif');
% x = [35 338 346 103];
% y = [253 250 17 148];
% improfile(I,x,y), grid on
%
% See also IMPIXEL, INTERP2
% Copyright 1993-1998 The MathWorks, Inc. All Rights Reserved.
% $Revision: 5.8 $ $Date: 1997/11/24 15:35:31 $
[xa,ya,a,n,method,prof,getn,getprof,u8in] = parse_inputs(varargin{:});
RGB_image = (ndims(a)==3);
% Parametric distance along segments
s = [0;cumsum(sqrt(sum((diff(prof).^2)')'))];
% Remove duplicate points if necessary.
killIdx = find(diff(s) == 0);
if (~isempty(killIdx))
s(killIdx+1) = [];
prof(killIdx+1,:) = [];
end
[ma,na,oa] = size(a);
xmin = min(xa(:)); ymin = min(ya(:));
xmax = max(xa(:)); ymax = max(ya(:));
if na>1
dx = max( (xmax-xmin)/(na-1), eps );
xxa = xmin:dx:xmax;
else
dx = 1;
xxa = xmin;
end
if ma>1
dy = max( (ymax-ymin)/(ma-1), eps );
yya = ymin:dy:ymax;
else
dy = 1;
yya = ymin;
end
if getn,
d = abs(diff(prof./(ones(size(prof,1),1)*[dx dy])));
n = max(sum(max(ceil(d)')),2); % In pixel coordinates
end
% Interpolation points along segments
if ~isempty(prof)
profi = interp1(s,prof,(0:n-1)*max(s)/(n-1));
xg = profi(:,1);
yg = profi(:,2);
else
profi = [];
xg = []; yg = [];
end
if ~isempty(a) & ~isempty(xg)
if RGB_image
% Image values along interpolation points - r,g,b planes separately
% Red plane
zr = interp2(xxa,yya,a(:,:,1),xg,yg,method);
% Green plane
zg = interp2(xxa,yya,a(:,:,2),xg,yg,method);
% Blue plane
zb = interp2(xxa,yya,a(:,:,3),xg,yg,method);
else
% Image values along interpolation points - the g stands for Grayscale
zg = interp2(xxa,yya,a,xg,yg,method);
end
% Get profile points in pixel coordinates
xg_pix = round(axes2pix(na, [xmin xmax], xg));
yg_pix = round(axes2pix(ma, [ymin ymax], yg));
% If the result is uint8, Promote to double and put NaN's in the places
% where the profile went out of the image axes (these are zeros because
% there is no NaN in UINT8 storage class)
if isa(zg, 'uint8')
prof_hosed = find( (xg_pix<1) | (xg_pix>na) | ...
(yg_pix<1) | (yg_pix>ma) );
if RGB_image
zr = double(zr); zg = double(zg); zb = double(zb);
zr(prof_hosed) = NaN;
zg(prof_hosed) = NaN;
zb(prof_hosed) = NaN;
else
zg = double(zg);
zg(prof_hosed) = NaN;
end
end
else
zg = [];
end
if nargout == 0 & ~isempty(zg) % plot it
oldgcf = gcf;
if getprof,
h = get(0,'children');
fig = 0;
for i=1:length(h),
if strcmp(get(h(i),'name'),'Profile'),
fig = h(i);
end
end
if ~fig, % Create new window
fig = figure('Name','Profile');
end
figure(fig)
else
fig = gcf;
end
if length(prof)>2
if RGB_image
plot3(xg,yg,zr,'r',xg,yg,zg,'g',xg,yg,zb,'b');
set(gca,'ydir','reverse');
xlabel X, ylabel Y;
else
plot3(xg,yg,zg,'b');
set(gca,'ydir','reverse');
xlabel X, ylabel Y;
end
else
if RGB_image
plot(sqrt((xg-xg(1)).^2+(yg-yg(1)).^2),zr,'r',...
sqrt((xg-xg(1)).^2+(yg-yg(1)).^2),zg,'g',...
sqrt((xg-xg(1)).^2+(yg-yg(1)).^2),zb,'b');
xlabel('Distance along profile');
else
plot(sqrt((xg-xg(1)).^2+(yg-yg(1)).^2),zg,'b');
xlabel('Distance along profile');
end
end
else
if RGB_image
zg = cat(3,zr(:),zg(:),zb(:));
else
zg = zg(:);
end
xi = prof(:,1);
yi = prof(:,2);
switch nargout
case 0, % If zg was [], we didn't plot and ended up here
return
case 1,
varargout{1} = zg;
case 3,
varargout{1} = xg;
varargout{2} = yg;
varargout{3} = zg;
case 5,
varargout{1} = xg;
varargout{2} = yg;
varargout{3} = zg;
varargout{4} = xi;
varargout{5} = yi;
otherwise
error('Invalid output arguments.');
end
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Function: parse_inputs
%
function [Xa,Ya,Img,N,Method,Prof,GetN,GetProf,u8in]=parse_inputs(varargin)
% Outputs:
% Xa 2 element vector for non-standard axes limits
% Ya 2 element vector for non-standard axes limits
% A Image Data
% N number of image values along the path (Xi,Yi) to return
% Method Interpolation method: 'nearest','bilinear', or 'bicubic'
% Prof Profile Indices
% GetN Determine number of points from profile if true.
% GetProf Get profile from user via mouse if true also get data from image.
% u8in True when the input is a uint8 image
% Set defaults
N = [];
GetN = 1;
GetProf = 0;
GetCoords = 1; % GetCoords - Determine axis coordinates if true.
Method = 'nearest';
switch nargin
case 0, % improfile
GetProf = 1;
GetCoords = 0;
case 1, % improfile(n) or improfile('Method')
if isstr(varargin{1})
Method = varargin{1};
else
N = varargin{1};
GetN = 0;
end
GetProf = 1;
GetCoords = 0;
case 2, % improfile(n,'method')
if isstr(varargin{2}),
Method = varargin{2};
N = varargin{1};
GetN = 0;
else
error('Wrong number of arguments or unknown interpolation method.');
end
GetProf = 1;
GetCoords = 0;
case 3, % improfile(a,xi,yi)
A = varargin{1};
Xi = varargin{2};
Yi = varargin{3};
case 4, % improfile(a,xi,yi,n) or improfile(a,xi,yi,'method')
A = varargin{1};
Xi = varargin{2};
Yi = varargin{3};
if isstr(varargin{4})
Method = varargin{4};
else
N = varargin{4};
GetN = 0;
end
case 5, % improfile(x,y,a,xi,yi) or improfile(a,xi,yi,n,'method')
if isstr(varargin{5}),
A = varargin{1};
Xi = varargin{2};
Yi = varargin{3};
N = varargin{4};
Method = varargin{5};
GetN = 0;
else
GetCoords = 0;
Xa = varargin{1};
Ya = varargin{2};
A = varargin{3};
Xi = varargin{4};
Yi = varargin{5};
end
case 6, % improfile(x,y,a,xi,yi,n) or improfile(x,y,a,xi,yi,'method')
Xa = varargin{1};
Ya = varargin{2};
A = varargin{3};
Xi = varargin{4};
Yi = varargin{5};
if isstr(varargin{6}),
Method = varargin{6};
else
N = varargin{6};
GetN = 0;
end
GetCoords = 0;
case 7, % improfile(x,y,a,xi,yi,n,'method')
if ~isstr(varargin{7}),
error('Method must be ''bilinear'',''bicubic'', or ''nearest''.');
end
Xa = varargin{1};
Ya = varargin{2};
A = varargin{3};
Xi = varargin{4};
Yi = varargin{5};
N = varargin{6};
Method = varargin{7};
GetN = 0;
GetCoords = 0;
otherwise
error('Invalid input arguments.');
end
if ~GetN,
if N<2, error('N must be > 1.'); end
end
if GetCoords & ~GetProf,
Xa = [1 size(A,2)];
Ya = [1 size(A,1)];
end
if GetProf, % Get profile from user if necessary using data from image
[Xa,Ya,A,state] = getimage;
if ~state,
error('Requires an image in the current axis.');
end
Prof = getline(gcf); % Get profile from user
else % We already have A, Xi, and Y
if prod(size(Xi))~=prod(size(Yi)),
error('Xi and Yi must have the same number of points');
end
Prof = [Xi(:) Yi(:)]; % [xi yi]
end
u8in = isa(A,'uint8');
% Promote the image to double if we aren't using nearest
if u8in & ~strcmp(Method,'nearest')
Img = double(A);
else
Img = A;
end
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?