imrotate.m

来自「有关matlab的电子书籍有一定的帮助希望有用」· M 代码 · 共 233 行

M
233
字号
function [rout,g,b] = imrotate(varargin)
%IMROTATE Rotate image.
%   B = IMROTATE(A,ANGLE,METHOD) rotates the image A by ANGLE
%   degrees in a counter-clockwise direction, using the specified
%   interpolation method. METHOD is a string that can have one of
%   these values:
%
%        'nearest'  (default) nearest neighbor interpolation
%
%        'bilinear' bilinear interpolation
%
%        'bicubic'  bicubic interpolation
%
%   If you omit the METHOD argument, IMROTATE uses the default
%   method of 'nearest'. To rotate the image clockwise, specify a
%   negative angle.
%
%   The returned image matrix B is, in general, larger than A to
%   include the whole rotated image. IMROTATE sets invalid values
%   on the periphery of B to 0.
%
%   B = IMROTATE(A,ANGLE,METHOD,'crop') rotates the image A
%   through ANGLE degrees and returns the central portion that
%   is the same size as A.
%
%   Class Support
%   -------------
%   The input image can be of class uint8 or double. The output
%   image is of the same class as the input image.
%
%   Example
%   -------
%        I = imread('ic.tif');
%        J = imrotate(I,-3,'bilinear','crop');
%        imshow(I), figure, imshow(J)
%
%   See also IMCROP, IMRESIZE.

%   Clay M. Thompson 8-4-92
%   Copyright 1993-1998 The MathWorks, Inc.  All Rights Reserved.
%   $Revision: 5.10 $  $Date: 1997/11/24 15:35:33 $

% Grandfathered:
%   Without output arguments, IMROTATE(...) displays the rotated
%   image in the current axis.  

[Image,Angle,Method,ClassIn,DoCrop,LogicalIn] = parse_inputs(varargin{:});

threeD = (ndims(Image)==3); % Determine if input includes a 3-D array

if threeD,
   r = rotateImage(Image(:,:,1),Angle,Method,DoCrop,0,ClassIn);
   g = rotateImage(Image(:,:,2),Angle,Method,DoCrop,0,ClassIn);
   b = rotateImage(Image(:,:,3),Angle,Method,DoCrop,0,ClassIn);
   if nargout==0, 
      imshow(r,g,b);
      return;
   elseif nargout==1,
      if strcmp(ClassIn,'uint8');
         rout = repmat(uint8(0),[size(r),3]);
         rout(:,:,1) = uint8(round(r*255));
         rout(:,:,2) = uint8(round(g*255));
         rout(:,:,3) = uint8(round(b*255));
      else
         rout = zeros([size(r),3]);
         rout(:,:,1) = r;
         rout(:,:,2) = g;
         rout(:,:,3) = b;
      end
   else % nargout==3
      if strcmp(ClassIn,'uint8')
         rout = uint8(round(r*255)); 
         g = uint8(round(g*255)); 
         b = uint8(round(b*255)); 
      else
         rout = r;        % g,b are already defined correctly above
      end
   end
else 
   r = rotateImage(Image,Angle,Method,DoCrop,LogicalIn,ClassIn);
   if nargout==0,
      imshow(r);
      return;
   end
   if strcmp(ClassIn,'uint8')
      if LogicalIn
         r = im2uint8(logical(round(r)));    
      else
         r = im2uint8(r); 
      end
   end
   rout = r;
end


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  Function: rotateImage
%

function b = rotateImage(A,ang,method,crop,LogicalIn,ClassIn)
% Inputs:
%         A       Input Image
%         ang     Angle to rotate image by
%         method  'nearest','bilinear', or 'bicubic'
%         crop    1 to crop image, 0 will output entire rotated image

% Catch and speed up 90 degree rotations
if rem(ang,90)==0 & nargin<4,
   phi = round(ang - 360*floor(ang/360));
   if phi==90,
      b = rot90(A);
   elseif phi==180,
      b = rot90(A,2);
   elseif phi==270,
      b = rot90(A,-1);
   else
      b = A;
   end
   if nargout==0, imshow(b), else bout = b; end
   return
end

phi = ang*pi/180; % Convert to radians

% Rotation matrix
T = [cos(phi) -sin(phi); sin(phi) cos(phi)];

% Coordinates from center of A
[m,n,o] = size(A);
if ~crop, % Determine limits for rotated image
   siz = ceil(max(abs([(n-1)/2 -(m-1)/2;(n-1)/2 (m-1)/2]*T))/2)*2;
   uu = -siz(1):siz(1); vv = -siz(2):siz(2);
else % Cropped image
   uu = (1:n)-(n+1)/2; vv = (1:m)-(m+1)/2;
end
nu = length(uu); nv = length(vv);

blk = bestblk([nv nu]);
nblks = floor([nv nu]./blk); nrem = [nv nu] - nblks.*blk;
mblocks = nblks(1); nblocks = nblks(2);
mb = blk(1); nb = blk(2);

rows = 1:blk(1); b = zeros(nv,nu);
for i=0:mblocks,
   if i==mblocks, rows = (1:nrem(1)); end
   for j=0:nblocks,
      if j==0, cols = 1:blk(2); elseif j==nblocks, cols=(1:nrem(2)); end
      if ~isempty(rows) & ~isempty(cols)
         [u,v] = meshgrid(uu(j*nb+cols),vv(i*mb+rows));
         % Rotate points
         uv = [u(:) v(:)]*T'; % Rotate points
         u(:) = uv(:,1)+(n+1)/2; v(:) = uv(:,2)+(m+1)/2;
         if method(1)=='n', % Nearest neighbor interpolation
            b(i*mb+rows,j*nb+cols) = interp2(A,u,v,'*nearest');
         elseif all(method=='bil'), % Bilinear interpolation
            b(i*mb+rows,j*nb+cols) = interp2(A,u,v,'*linear');
         elseif all(method=='bic'), % Bicubic interpolation
            b(i*mb+rows,j*nb+cols) = interp2(A,u,v,'*cubic');
         else
            error(['Unknown interpolation method: ',method]);
         end
      end
   end
end

b(isnan(b)) = 0;

if strcmp(ClassIn, 'uint8')
   b = min(255, max(0, b));
end

if LogicalIn
   b = logical(b);
end


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  Function: parse_inputs
%

function [A,Angle,Method,Class,CropIt,LogicalIn] = parse_inputs(varargin)
% Outputs:  A       the input image
%           Angle   the angle by which to rotate the input image
%           Method  interpolation method (nearest,bilinear,bicubic)
%           Class   storage class of A
%           CropIt  this is 1 if we should crop before we output the image
%           LogicalIn  this is 1 if we got a logical image on the input

A = varargin{1};
Angle = varargin{2};
Class = class(A);
LogicalIn = islogical(A);

switch nargin
case 2,             % imrotate        
   Method = 'nea'; 
   CropIt = 0;
case 3,
   if isstr(varargin{3}),
      Method = [lower(varargin{3}),'   ']; % Protect against short method
      Method = Method(1:3);
      if Method(1)=='c', % Crop string
         Method = 'nea';
         CropIt = 1;
      else
         CropIt = 0;
      end
   else
      error('''METHOD'' must be a string of at least three characters.');
   end
case 4,
   if isstr(varargin{3}),
      Method = [lower(varargin{3}),'   ']; % Protect against short method
      Method = Method(1:3);
   else
      error('''METHOD'' must be a string of at least three characters.');
   end
   CropIt = 1;
otherwise,
   error('Invalid input arguments');
end

if isa(A, 'uint8'),     % Convert A to Double grayscale for filtering & interpolation
   if LogicalIn
      A = double(A);
   else
      A = double(A)/255;
   end
end

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?