Lauren Smith

November 9, 2010

CS342

Homography

For Assignment Three, we chose to implement part II: Homography. Homography is the relationship between two images of a translation. In this instance, we have used homography to project an image onto a planar region. The idea of this project is to select a two regions in a set of two images with user inputted mouse clicks. Then, the selected region from image 1 will be inserted into the region created by the mouse clicks in image 2, with correct scaling and rotation.

The code compH is the piece to compute the homography between the images. Building off of this, the homography.m file uses the calculated homography and translates the image from one to the next. The code works by first saving the regions defined by the user input. By defining a meshgrid, we can separate the X and Y coordinates of each and create vectors. Using the inverse function, we use backwards mapping to fill in the region in the second image with a reshaped version of image one.

**Results**

** **

*Homography
can be used to decorate bland home interiors. Should we go with a Monet or a Van Gogh?*

* *

* *

* *

* *

* *

*Homography
can be used to transform your home into a beach house, without going
anywhere! Or perhaps you prefer
urban living..?*

* *

* *

* *

*Homography
can even be used to create your own rules of the road.*

* *

* *

* *

**Conclusion**

** **

This implementation of Homography is
very effective for projecting images onto planes in a photo. As seen from the
examples above, it works with any region with four vertices, from squares to
rectangles, to projecting parallelograms and rhombuses on the walls in the
final photos. This code is also
robust in that it allows for image rotation, as seen in the last image. By clicking on the input points
deliberately to align the top of the smiley face to the bottom of the street
sign, it is even possible to project the image at a rotation. The time complexity of this is very
efficient as well, running very quickly for the images inputted. An extension of this would be to allow
multiple projections conveniently, (without saving the edited image and
repeating it again). This would be
helpful for images like the window view, if the window had 3 panes of glass, we
could substitute the image of the beach into all three. Overall though, this code provides a
very quick and effective way to manipulate the images, producing interesting
results.

**Code**

** **

homography.m

** **

im2 =
imread('speedlimit.jpg');

im1 =
imread('smily.jpg');

im1 =
im2double(im1);

im2 =
im2double(im2);

figure(1);

imshow(im1);

hold on;

figure(2);

imshow(im2);

xx1 = [];
yy1 = [];

xx2 = [];
yy2 = [];

hold on;

% read
in 4 user inputs

for n = 1: 4

figure(1);

[x1,y1] = ginput(1);

plot(x1, y1, 'r.', 'markersize', 20);

drawnow;

xx1 = [xx1; x1];

yy1 = [yy1; y1];

figure(2);

[x2,y2] = ginput(1);

plot(x2, y2, 'r.', 'markersize', 20);

drawnow; xx2 = [xx2; x2];
yy2 = [yy2; y2];

end

H =
compH(xx1, yy1, xx2, yy2);

% get
sizes

[h,W, d] =
size(im2);

[x,y] =
meshgrid(1:W, 1:h);

[b,a, d2] =
size(im1);

%
create vectors

x = x(:);

y = y(:);

%
inverse

Z =
inv(H)*[x'; y' ; ones(size(x'))];

% find
u v

u = Z(1,:)
./ Z(3,:);

v = Z(2,:)
./ Z(3,:);

%reshape
u and v

u =
reshape(u,h,W);

v =
reshape(v,h,W);

% pad
the rest of the photo, if edge, stretch values further

u(u<1) =
1;

u(u>a) =
a;

v(v<1) =
1;

v(v>b) =
b;

%
create meshgrid 2

[uu,vv] =
meshgrid(1:a, 1:b);

%interp

J =
interp2(uu,vv,im1(:,:,1),u,v, 'linear');

JG =
interp2(uu,vv,im1(:,:,2),u,v,'linear');

JB =
interp2(uu,vv,im1(:,:,3),u,v,'linear');

%
create mask

mask =
roipoly(im2, xx2,yy2);

im =
im2(:,:,1).*(1-mask) + J.*mask;

imG =
im2(:,:,2).*(1-mask) + JG.*mask;

imB =
im2(:,:,3).*(1-mask) + JB.*mask;

imshow(cat(3,
im, imG,imB));

compH.m

* *

function H = compH(x1, y1, x2, y2)

%
function compH finds the homography H

%
(x1,y1) and (x2,y2) are matching points

ax = [-x1,
-y1, -ones(size(x1)), zeros(size(x1)), zeros(size(x1)),zeros(size(x1)), x2.*x1,
x2.*y1, x2];

ay =
[zeros(size(x1)), zeros(size(x1)), zeros(size(x1)), -x1, -y1, -ones(size(x1)),
y2.*x1, y2.*y1, y2];

A = [ax;
ay];

[U,S,V] =
svd(A);

H =
reshape(V(:,9), 3, 3);

H = H';

* *

* *