Code covered by the BSD License  

Highlights from
Fill corners of rotated image

image thumbnail
from Fill corners of rotated image by Vlad Atanasiu
Rotate image without making black edges.

imregrotate(varargin)
function varargout = imregrotate(varargin)
%ROIROTATE Rotate & crop region of interest avoiding 'black corners'.
% 	B = ROIROTATE(A,ROI,ANGLE,METHOD) rotates the region of intererest ROI
% 	found in the image A by ANGLE degrees in a counter-clockwise direction, 
% 	using the specified interpolation method and gives the rotated 
% 	region as output in B cropped out of the original image.
% 	
% 	Usefulness
% 	----------
% 	ROIROTATE was designed to avoid the 'black corners' typical of
%   MATLAB's imrotate function, which are apearing from its behaviour
%   of padding by zeros the space outside the image borders prior to 
%   the rotation. This is possible if the image to be rotated is 
%   part of a bigger image - which is the definition of a 'region 
%   of interest' -, because there is enough information to fill 
%   the corners.
% 	
% 	Description
% 	-----------
% 	Apart of the first entry which is based on the IMCROP syntax, 
% 	all other are identical to the IMROTATE function.
% 	
%   ROI is a four-element vector with the form [xmin ymin width height];
%   these values are specified in spatial coordinates.
% 	
% 	xmin - starting pixel to be cut, x-th of the original image
% 	ymin - same on y-axis
% 	width - number of pixels to be cut minus one (width)
% 	height - same on height
% 	
% 	If you want to point the 5 pixel wide & 7 pixel heigh NW corner 
% 	of an image, replace R with [1,1,4,6].
% 	
%   Because ROI is specified in terms of spatial coordinates,
%   the WIDTH and HEIGHT of ROI do not always correspond exactly
%   with the size of the output image. For example, suppose ROI
%   is [20 20 40 30], using the default spatial coordinate
%   system. The upper left corner of the specified rectangle is
%   the center of the pixel (20,20) and the lower right corner is
%   the center of the pixel (50,60). The resulting output image
%   is 31-by-41, not 30-by-40, because the output image includes
%   all pixels in the input that are completely or partially
%   enclosed by the rectangle.
% 	
%         Note for IMCROP:
%         To cut the NW pixel only:
%             NWcornerPixel = imcrop(I, [1,1,0,0]);
%         
%         To cut the first top stripe of pixels:
%             topStripe = imcrop(I, [1,1,size(I,2)-1,0]);
% 	
% 	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, ROIROTATE uses the default
% 	method of 'nearest'.
%
%   To rotate the image clockwise, specify a negative angle.
% 	
% 	Class Support
% 	-------------
% 	The input image can be of class uint8, uint16, or double.
%   The output image is of the same class as the input image.
% 	
% 	Example
% 	-------
%        I = imread('circuit.tif');
%        J = imrotate(imcrop(I,[60 80 100 90]),-21,'bilinear','crop');
%        [K x y w h] = roirotate(I,[60 80 100 90],-21,'bilinear');
%        figure, subplot(1,3,1), imshow(I), title('roi')
%        rectangle('Position',[60 80 100 90],'EdgeColor','red');
%        rectangle('Position',[x y w h],'EdgeColor','green');
%        subplot(1,3,2), imshow(J), title('imrotate')
%        subplot(1,3,3), imshow(K), title('roirotate')
%
% 	See also IMROTATE, IMCROP, IMRESIZE, IMTRANSFORM, TFORMARRAY.

%   Vlad Atanasiu - 06/05/2002
%   Revisions: 3  > 01/11/2008



% check image input data
[A,dim,x,y,width,height,ang,method] = parseInputs(varargin{:});

% calculate padding borders
padX = abs(ceil(height*sin(ang*pi/180)/2));
padY = abs(ceil(width*sin(ang*pi/180)/2));

% padding zeros if extended region of interest coordinates outside image
if x-padX < 1   % left
    A = [zeros(size(A,1),padX-x+1,dim) A];
end
if y-padY < 1   % top
    A = [zeros(padY-y+1,size(A,2),dim);...
            A];
end
if x+width+padX > size(A,2)   % right
    A = [A zeros(size(A,1),x+width+padX-size(A,2),dim)];
end
if y+height+padY > size(A,1)   % bottom
    A = [A;...
            zeros(y+height+padY-size(A,1),size(A,2),dim)];
end

% cut extended region
ROI = imcrop(A,[x-padX y-padY width+padX*2 height+padY*2]);

% rotate extended region
ROI = imrotate(ROI,ang,method,'crop');

% cut region
varargout{1} = imcrop(ROI,[padX padY width height]);

% gives extended region coordinates
if nargout == 5
    varargout{2} = x-padX;
    varargout{3} = y-padY;
    varargout{4} = width+padX*2;
    varargout{5} = height+padY*2;
end


% ------------------------------------------------

function [A,dim,x,y,width,height,ang,method] = parseInputs(varargin)
% Input checkings

% Defaults
method = 'n';

% Check number of input parameters
error(nargchk(3,4,nargin));
switch nargin
case 3,             % regrotate(A,reg,ang,)
    A = varargin{1};
	x = varargin{2}(1);
	y = varargin{2}(2);
	width = varargin{2}(3);
	height = varargin{2}(4);
    ang = varargin{3};
case 4,             % regrotate(A,reg,ang,method) 
    A = varargin{1};
	x = varargin{2}(1);
	y = varargin{2}(2);
	width = varargin{2}(3);
	height = varargin{2}(4);
    ang = varargin{3};
    method = varargin{4};
otherwise,
    error('Invalid number of input arguments.');
end

% Check validity of the input parameters 
if ischar(method),
    strings = {'nearest','bilinear','bicubic'};
    idx = strmatch(lower(method),strings);
    if isempty(idx),
        error(sprintf('Unknown interpolation method: %s',method));
    elseif length(idx)>1,
        error(sprintf('Ambiguous interpolation method: %s',method));
    else
        method = strings{idx};
    end  
else
    error('Interpolation method have to be a string.');  
end

if size(varargin{2},2) ~= 4
    error('Region of interest should be defined by 4 arguments.');  
end

% transforms the format of A into an image if it is a filename
if (isstr(A))
    A = imread(A);
end

% gets the dimensions of A
dim = ndims(A);
if dim == 2, dim=1; end

% modifies if needed the region of interest coordinates if outside image
if x < 1, x = 1; end
if y < 1, y = 1; end
if x > size(A,2)-1, x = size(A,2)-1; end
if y > size(A,1)-1, y = size(A,1)-1; end
if x+width > size(A,2)-1, width = size(A,2)-x-1; end
if y+height > size(A,1)-1, height = size(A,1)-y-1; end


Contact us