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.