imresize.m

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

M
336
字号
function [rout,g,b] = imresize(varargin)
%IMRESIZE Resize image.
%   IMRESIZE resizes an image of any type using the specified
%   interpolation method. Supported interpolation methods
%   include:
%
%        'nearest'  (default) nearest neighbor interpolation
%
%        'bilinear' bilinear interpolation
%
%        'bicubic'  bicubic interpolation
%
%   B = IMRESIZE(A,M,METHOD) returns an image that is M times the
%   size of A. If M is between 0 and 1.0, B is smaller than A. If
%   M is greater than 1.0, B is larger than A. If METHOD is
%   omitted, IMRESIZE uses nearest neighbor interpolation.
%
%   B = IMRESIZE(A,[MROWS MCOLS],METHOD) returns an image of size
%   MROWS-by-MCOLS. If the specified size does not produce the
%   same aspect ratio as the input image has, the output image is
%   distorted.
%
%   When the specified output size is smaller than the size of
%   the input image, and METHOD is 'bilinear' or 'bicubic',
%   IMRESIZE applies a lowpass filter before interpolation to
%   reduce aliasing. The default filter size is 11-by-11.
%
%   You can specify a different order for the default filter
%   using:
%
%        [...] = IMRESIZE(...,METHOD,N)
%
%   N is an integer scalar specifying the size of the filter,
%   which is N-by-N. If N is 0, IMRESIZE omits the filtering
%   step.
%
%   You can also specify your own filter H using:
%
%        [...] = IMRESIZE(...,METHOD,H)
%
%   H is any two-dimensional FIR filter (such as those returned
%   by FTRANS2, FWIND1, FWIND2, or FSAMP2).
%
%   Class Support
%   -------------
%   The input image can be of class uint8 or double. The output
%   image is of the same class as the input image.
%
%   See also INTERP2.

%   Grandfathered Syntaxes:
%
%   [R1,G1,B1] = IMRESIZE(R,G,B,M,'method') or 
%   [R1,G1,B1] = IMRESIZE(R,G,B,[MROWS NCOLS],'method') resizes
%   the RGB image in the matrices R,G,B.  'bilinear' is the
%   default interpolation method.

%   Clay M. Thompson 7-7-92
%   Copyright 1993-1998 The MathWorks, Inc.  All Rights Reserved.
%   $Revision: 5.12 $  $Date: 1997/11/24 15:35:32 $

[A,m,method,classIn,h,LogicalIn] = parse_inputs(varargin{:});

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

if threeD,
   r = resizeImage(A(:,:,1),m,method,h,0,classIn);
   g = resizeImage(A(:,:,2),m,method,h,0,classIn);
   b = resizeImage(A(:,:,3),m,method,h,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) = im2uint8(r);
         rout(:,:,2) = im2uint8(g);
         rout(:,:,3) = im2uint8(b);
      else
         rout = zeros([size(r),3]);
         rout(:,:,1) = r;
         rout(:,:,2) = g;
         rout(:,:,3) = b;
      end
   else % nargout==3
      if strcmp(classIn,'uint8')
         rout = im2uint8(r); 
         g = im2uint8(g); 
         b = im2uint8(b); 
      else
         rout = r;        % g,b are already defined correctly above
      end
   end
else 
   r = resizeImage(A,m,method,h,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: resizeImage
%

function b = resizeImage(A,m,method,h,LogicalIn,ClassIn)
% Inputs:
%         A       Input Image
%         m       resizing factor or 1-by-2 size vector
%         method  'nearest','bilinear', or 'bicubic'
%         h       the anti-aliasing filter to use.
%                 if h is zero, don't filter
%                 if h is an integer, design and use a filter of size h
%                 if h is empty, use default filter

if prod(size(m))==1,
   bsize = floor(m*size(A));
else
   bsize = m;
end

if any(size(bsize)~=[1 2]),
   error('M must be either a scalar multiplier or a 1-by-2 size vector.');
end

% values in bsize must be at least 1.
bsize = max(bsize, 1);

if (any((bsize < 4) & (bsize < size(A))) & ~strcmp(method, 'nea'))
   fprintf('Input is too small for bilinear or bicubic method;\n');
   fprintf('using nearest-neighbor method instead.\n');
   method = 'nea';
end

if isempty(h),
   nn = 11; % Default filter size
else
   if prod(size(h))==1, 
      nn = h; h = []; 
   else 
      nn = 0;
   end
end

[m,n] = size(A);

if nn>0 & method(1)=='b',  % Design anti-aliasing filter if necessary
   if bsize(1)<m, h1 = DesignFilter(nn-1,bsize(1)/m); else h1 = 1; end
   if bsize(2)<n, h2 = DesignFilter(nn-1,bsize(2)/n); else h2 = 1; end
   % if length(h1)>1 | length(h2)>1, h = h1'*h2; else h = []; end
   if length(h1)>1 | length(h2)>1, 
      a = filter2(h1',filter2(h2,A)); 
   else 
      a = A; 
   end
elseif method(1)=='b' & (prod(size(h)) > 1),
   a = filter2(h,A);
else
   a = A;
end

if method(1)=='n', % Nearest neighbor interpolation
   dx = n/bsize(2); dy = m/bsize(1); 
   uu = (dx/2+.5):dx:n+.5; vv = (dy/2+.5):dy:m+.5;
elseif all(method == 'bil') | all(method == 'bic'),
   uu = 1:(n-1)/(bsize(2)-1):n; vv = 1:(m-1)/(bsize(1)-1):m;
else
   error(['Unknown interpolation method: ',method]);
end

%
% Interpolate in blocks
%
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));
         % Interpolate points
         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');
         end
      end
   end
end

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

if LogicalIn
   b = logical(b);
end

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

function [A,m,method,classIn,h,LogicalIn] = parse_inputs(varargin)
% Outputs:  A       the input image
%           m       the resize scaling factor or the new size
%           method  interpolation method (nearest,bilinear,bicubic)
%           class   storage class of A
%           h       if 0, skip filtering; if non-zero scalar, use filter 
%                   of size h; otherwise h is the anti-aliasing filter.

switch nargin
case 2,                        % imresize(A,m)
   A = varargin{1};
   m = varargin{2};
   method = 'nearest';
   classIn = class(A);
   h = [];
case 3,                        % imresize(A,m,method)
   A = varargin{1};
   m = varargin{2};
   method = varargin{3};
   classIn = class(A);
   h = [];
case 4,
   if isstr(varargin{3})       % imresize(A,m,method,h)
      A = varargin{1};
      m = varargin{2};
      method = varargin{3};
      classIn = class(A);
      h = varargin{4};
   else                        % imresize(r,g,b,m)
      for i=1:3
         if isa(varargin{i},'uint8')
            error('Please use 3-d RGB array syntax with uint8 image data');
         end
      end
      A = zeros([size(varargin{1}),3]);
      A(:,:,1) = varargin{1};
      A(:,:,2) = varargin{2};
      A(:,:,3) = varargin{3};
      m = varargin{4};
      method = 'nearest';
      classIn = class(A);
      h = [];
   end
case 5,                        % imresize(r,g,b,m,'method')
   for i=1:3
      if isa(varargin{i},'uint8')
         error('Please use 3-d RGB array syntax with uint8 image data');
      end
   end
   A = zeros([size(varargin{1}),3]);
   A(:,:,1) = varargin{1};
   A(:,:,2) = varargin{2};
   A(:,:,3) = varargin{3};
   m = varargin{4};
   method = varargin{5};
   classIn = class(A);
   h = [];
case 6,                        % imresize(r,g,b,m,'method',h)
   for i=1:3
      if isa(varargin{i},'uint8')
         error('Please use 3-d RGB array syntax with uint8 image data');
      end
   end
   A = zeros([size(varargin{1}),3]);
   A(:,:,1) = varargin{1};
   A(:,:,2) = varargin{2};
   A(:,:,3) = varargin{3};
   m = varargin{4};
   method = varargin{5};
   classIn = class(A);
   h = varargin{6};
otherwise,
   error('Invalid input arguments.');
end

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

method = [lower(method),'   ']; % Protect against short method
method = method(1:3);


function b = DesignFilter(N,Wn)
% Code from SPT v3 fir1.m and hanning.m

N = N + 1;
odd = rem(N,2);
wind = .54 - .46*cos(2*pi*(0:N-1)'/(N-1));
fl = Wn(1)/2;
c1 = fl;
if (fl >= .5 | fl <= 0)
    error('Frequency must lie between 0 and 1')
end 
nhlf = fix((N + 1)/2);
i1=1 + odd;

if odd
   b(1) = 2*c1;
end
xn=(odd:nhlf-1) + .5*(1-odd);
c=pi*xn;
c3=2*c1*c;
b(i1:nhlf)=(sin(c3)./c);
b = real([b(nhlf:-1:i1) b(1:nhlf)].*wind(:)');
gain = abs(polyval(b,1));
b = b/gain;

⌨️ 快捷键说明

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