# Projective Transform - matlab code

i can't use any toolbox function i need to build it from scratch.

% load images img1 = readImage('roadSign.tif'); img2 = readImage('lena.tif'); % call the main function mapIntoImage(img1,img2) function [newImage] = mapIntoImage(imageA,imageB) % Input: imageA, imageB - a grayscale image in the range [0..255]. % % Output: newImage – imageA into which image B has been mapped. % showImage(imageA) hold on % Initially, the list of points is empty. xy = []; % Loop, picking up the points. disp('Please enter corners of place to insert image in clockwise order.') for j = 1:4 [xi,yi] = ginput(1); %draw a yellow dot plot(xi,yi,'yo') xy(:,j) = [xi;yi]; end % get x1 y1 cordinates - xy(:, 1) imgRow = size(imageB,1); imgCol = size(imageB,2); [X,Y] = meshgrid(1:imgCol,1:imgRow); imgBcords = [0 size(imageB, 1) size(imageB,1) 0 ; 0 0 size(imageB,2) size(imageB,2)]; coefs = findCoefficients(xy, imgBcords); A = [coefs(1) coefs(2) coefs(5);coefs(3) coefs(4) coefs(6); coefs(7) coefs(8) 1]; temp = zeros(size(X,1), size(X,2), 3); new = ones(256); for i = 1:size(X,1) for j = 1:size(X,2) temp(i,j,:) =A*[X(i,j); Y(i,j); new(i,j)]; end end end function [ result ] = findCoefficients( imageA, imageB ) % finds coefficients for inverse mapping algorithem % takes 2 X 2d vectors each consists of 4 points x,y % and returns the coef accroding to reverse mapping function % % x y 0 0 1 0 -xx' -yx' % 0 0 x y 0 1 -xy' -yy' % y' and x' are in the destenation picture; A = [imageB(1,1) imageB(2,1) 0 0 1 0 -imageB(1,1)*imageA(1,1) -imageB(2,1)*imageA(1,1); 0 0 imageB(1,1) imageB(2,1) 0 1 -imageB(1,1)*imageA(2,1) -imageB(2,1)*imageA(2,1); imageB(1,2) imageB(2,2) 0 0 1 0 -imageB(1,2)*imageA(1,2) -imageB(2,2)*imageA(1,2); 0 0 imageB(1,2) imageB(2,2) 0 1 -imageB(1,2)*imageA(2,2) -imageB(2,2)*imageA(2,2); imageB(1,3) imageB(2,3) 0 0 1 0 -imageB(1,3)*imageA(1,3) -imageB(2,3)*imageA(1,3); 0 0 imageB(1,3) imageB(2,3) 0 1 -imageB(1,3)*imageA(2,3) -imageB(2,3)*imageA(2,3); imageB(1,4) imageB(2,4) 0 0 1 0 -imageB(1,4)*imageA(1,4) -imageB(2,4)*imageA(1,4); 0 0 imageB(1,4) imageB(2,4) 0 1 -imageB(1,4)*imageA(2,4) -imageB(2,4)*imageA(2,4)]; B = [imageB(1,1); imageB(2,1); imageB(1,2); imageB(2,2); imageB(1,3); imageB(2,3); imageB(1,4); imageB(2,4)]; result = pinv(A)*B; end

i want to build now the transform [x' y' 1] = A*[X Y 1]; i have figured out that i would need to use repmat, but i can't seem to get to the real syntax without loops. what's the most efficient way to do it?

## Answers

A projective transform has the form of

$ x' = \frac {a_{11}x+a_{12}y+a_{13}}{a_{13}x+a_{23}y+a_{33}} \\ y' = \frac {a_{21}x+a_{22}y+a_{23}}{a_{13}x+a_{23}y+a_{33}} $

Where the coefficients are defined up to some scale factor. One of the ways to ensure a constant scale factor is to set $a_{33}=1$. One easy way to think about it is to use the homogenous coordinates:

$ \left( \begin{array}{ccc} x'\\y'\\S\end{array} \right) = \left( \begin{array}{ccc} a_{11} & a_{12} & a_{13}\\a_{21} & a_{22} & a_{23}\\ a_{31} & a_{32} & a_{33}\end{array} \right) \left( \begin{array}{ccc} x\\y\\1\end{array} \right) $

These coordinates are defined up to scale. That is,

$ \left( \begin{array}{ccc} x'/S\\y'/S\\1\end{array} \right) \equiv \left( \begin{array}{ccc} x'\\y'\\S\end{array} \right)$

Thus, in your case you should do: (Assuming that x and y are column vectors, and A is the transpose of the matrix that I described above:

XY = A * [x y ones(size(x))]; XY(:,1) = XY(:,1)./XY(:,3); XY(:,2) = XY(:,2)./XY(:,3);