Contents

A naive way to stitch two images

Let's load a pair of images, taken from the same point of view. We want to stitch them.

im1=imread('im1.jpg');
im2=imread('im2.jpg');
im1f=figure; imshow(im1);
im2f=figure; imshow(im2);
Warning: Image is too big to fit on screen; displaying at 67%
Warning: Image is too big to fit on screen; displaying at 67%

Data entry

We manually :-( pick four points in the first image, and four corresponding points on the second image

figure(im1f), [x1,y1]=getpts
figure(im2f), [x2,y2]=getpts
figure(im1f), hold on, plot(x1,y1,'or');
figure(im2f), hold on, plot(x2,y2,'or');
x1 =
   1.0e+03 *
    0.8860
    1.5505
    1.5835
    1.3225
y1 =
  371.7500
  386.7500
  833.7500
  881.7500
x2 =
   41.5000
  697.0000
  724.0000
  482.5000
y2 =
   1.0e+03 *
    0.5563
    0.5668
    0.9823
    1.0588

Homography estimation

The matlab maketform function returns an homography given four points and their transformed ones, which is the minimal information which defines an homography. A naive algorithm which solves this problem is in "Multiple View Geometry", page 35. Better algorithms are in chapter 4 of the same book.

T=maketform('projective',[x2 y2],[x1 y1]);
T.tdata.T
ans =
    0.7050   -0.0779   -0.0002
    0.1273    1.0167    0.0001
  816.7405 -177.6329    1.0000

this is the computed homography, a 3x3 matrix. It transforms the second image to match the first.

Transformations

Let's not transform the images, and place both on the same reference frame. There are some hacks with xdata and ydata here, check the imtransform docs if you are interested in the details.

[im2t,xdataim2t,ydataim2t]=imtransform(im2,T);
% now xdataim2t and ydataim2t store the bounds of the transformed im2
xdataout=[min(1,xdataim2t(1)) max(size(im1,2),xdataim2t(2))];
ydataout=[min(1,ydataim2t(1)) max(size(im1,1),ydataim2t(2))];
% let's transform both images with the computed xdata and ydata
im2t=imtransform(im2,T,'XData',xdataout,'YData',ydataout);
im1t=imtransform(im1,maketform('affine',eye(3)),'XData',xdataout,'YData',ydataout);

Visualizations

now im1t and im2t are equal-size images ready to be merged. Let's average them

ims=im1t/2+im2t/2;
figure, imshow(ims)
Warning: Image is too big to fit on screen; displaying at 33%

if we want to better analyze the match quality, let's difference the images and look at the absolute value

imd=uint8(abs(double(im1t)-double(im2t)));
% the casts necessary due to the images' data types
imshow(imd);
Warning: Image is too big to fit on screen; displaying at 33%

you can get a decent composite by picking the maximum at each pixel: however, note that the seam is visible, because the exposure in the two images is not equal. Real stitching software compensates for this.

ims=max(im1t,im2t);
imshow(ims);
Warning: Image is too big to fit on screen; displaying at 33%

Notes

real stitching software do a lot more than this. And, they pick matching points automatically. :-) The full panorama (which is from Cima Comer, on Lago di Garda) is found here: http://www.leet.it/home/lale/files/Garda-pano.jpg It was made using Hugin and panotools: http://hugin.sourceforge.net/ Note that exposure has been compensated between images.