function g = imageTranslate4e(f,tx,ty,mode)
% IMAGETRANSLATE Translates an image spatially
% g = imageTranslate4e(f,tx,ty,mode) translates image f by amounts tx and
% ty in the x (veritcal) and y (horizontal) directions. Tx and ty can be
% any real number. The output image is of the smae size as the original. If
% mode = 'black' the background left by the translated image will be black.
% This is the default. If mode = 'white' the background will be white. This
% function uses nearest-neighbor interpolation.
% Example usage:
% f = imread('cameraman.tif');
% figure; image(f)
% g = imageTranslate4e(f,0.5*size(f,1),0.25*size(f,2));
% figure; image(g)
% Convert input image to floating point. This will simplify making the
% background black or white wihtout having to check the class of the image.
%f = intScaling4e(f);
[M,N]=size(f);
% Check default
if nargin == 3
mode = 'black';
end
% Affine translation matrix
A = [1 0 tx; 0 1 ty; 0 0 1];
% Use functional meshgrid to formulate a vectorized solution. This function
% uses a [col,row] format:
[y,x]=meshgrid(1:N,1:M);
% Form the coordinates by adding a 1 to all coordinate pairs.
allones = ones(M*N,1);
origCoords = [x(:)';y(:)';allones']; % This is a 3-by-M*N array
% To get the primed (transformed) coordinates we multiply the original
% coordinates by A.
primeCoords = A*origCoords;
% Rounding the coordinate values implements nearest-neighbor interpolation.
primeCoords = round(primeCoords);
% primeCoords is a 3-by-M*N array also. But, because the original
% coordinates were multiplied by A, there may be some prime coordinates
% with values outside the valid M-by_N rectangle of the output image (the
% output image is required by design to be of the same size as the input).
% Identify all valid values of row coordinates (values of x between 1 and
% M), as well as invalid row coordinate values. [The row coordinates are in
% array newCoord(1,:)]. Do the same for all column coordinates (located in
% array newCoord(2,:)). No need to worry about the third row of the array
% primeCoords-- they are all 1's.
valrows = (primeCoords(1,:) > 0) & (primeCoords(1,:) <= M);
valcols = (primeCoords(2,:) > 0) & (primeCoords(2,:) <= N);
% The above are logical arrays with 1's at the location of individual valid
% row coordinates and 0's elsewhere; and similarly for col coordinates. We
% are interested only in corresponding PAIRS of valid coordinates, found by
% adding the two individual arrays.
validpairs = valrows & valcols;
% This is also a logical array with 1's at the location of the valid pairs
% and 0's for invalid pairs. Find the numerical locations of the 1's.
idx = find(validpairs == 1);
% All we have done so far is find correspodnece between input and output
% (transformed) coordinates. We still need to do the intensity assignments.
%
% Initialize the output image tohte background intensity. Make the array
% the same class as the input image (this will be needed in the next step,
% where we'll be selecting values from the input image).
switch mode
case 'black'
g = zeros(M,N,class(f));
case 'white'
g = ones(M,N,class(f));
end
% Assign intensities from the values of f at the valid original coordinates
% to the values of g at the prime coordinates.
for I = idx
g(primeCoords(1,I),primeCoords(2,I))=f(origCoords(1,I),origCoords(2,I));
end