Reputation: 47
I am working with the baboon image and what I want is to obtain an image like this:
I have tried with fitgeotrans
, projective2d
and affine2d
without success, maybe I don't understand correctly the behavior of these functions.
Thank you for your help.
Upvotes: 3
Views: 3577
Reputation: 104504
Just a warning that fitgeotrans
is part of MATLAB R2013b and so this won't work for any versions below this.
The process to warp the image to a "trapezoid" is quite simple. What you need to do is create a transformation object that takes the four corner points of the image and places them to the corresponding corners of the trapezoid that you want. Once you find this transformation, you warp the image with this transformation object, but make sure that you specify the coordinate system so that the origin is with respect to the top-left corner of the original image. If you don't, then the origin is with respect to the new image which will be cropped. Once you find this warped image, we display it on an image frame with respect to the original image coordinate system.
You are using the infamous Mandrill image from the University of Southern California's SIPI (Signal and Image Processing Institute) Image Database and MATLAB has this as part of the image processing toolbox. First load the dataset and because this is an indexed image with a specified colour map, ind2rgb
is required to convert this to a colour image.
%// Load in the image
load mandrill;
img = ind2rgb(X,map);
The Mandrill image is stored in img
, and we get:
Now the next part is to create a transformation object to warp the four corner points of the image to the trapezoid coordinates. fitgeotrans
does this perfectly. You need to specify a set of "moving points", which are the points that you want to transform. In this case, these are the four corner points of the original image you want to transform. You place this into a 4 x 2
matrix where the first column is the column / x
coordinates and the second column is the row / y
coordinates. I'm going to specify the top-left, top-right, bottom-left and bottom-right coordinates respectively. Next, you need to specify a set of "fixed points" which are the points that you would like the moving points to move to in the end. Again, this will be in a 4 x 2
matrix and these are the coordinates of the trapezoid. I had to fool around with the coordinates to get it right but you're more than welcome to modify this for your liking. You also want to specify a projective transformation because of the sheer experienced in the trapezoid.
%// Create perspective transformation that warps the original
%// image coordinates to the trapezoid
movingPoints = [1 1; size(img,2) 1; 1 size(img,1); size(img,2) size(img,1)];
fixedPoints = [180 100; 340 100; 50 300; 450 300];
tform = fitgeotrans(movingPoints, fixedPoints, 'Projective');
tform
stores the transformation object. Next, we need to create a reference coordinate system for warping our image. We want to do this with respect to the original image coordinate system. You can use imref2d
to do that. The first input is the size of the image, which is the rows and columns respectively in a vector, then you specify the x
/column limits and the y
/row limits. We want this to be with respect to the original image.
%// Create a reference coordinate system where the extent is the size of
%// the image
RA = imref2d([size(img,1) size(img,2)], [1 size(img,2)], [1 size(img,1)]);
RA
stores this reference frame. The last thing you need to do is warp the image with this new transformation object. Use imwarp
to achieve this warping. To use the function, you specify the image to warp, the transformation object and you want to make sure that the warping is with respect to the original image frame coordinate system, so you must specify the 'OutputView'
flag to be what was created above.
%// Warp the image
[out,r] = imwarp(img, tform, 'OutputView', RA);
out
contains the warped image and r
contains the coordinate system that the image is with respect to. r
should equal RA
for the purposes of this questions.
Now if you want to see the image, use imshow
with this new coordinate system to finally display the image. When you do this, you'll see the axes displayed, so turn that off:
%// Show the image and turn off the axes
imshow(out, r);
axis off;
.... and we get:
For your copying and pasting pleasure, here's the code in full:
%// Load in the image
load mandrill;
img = ind2rgb(X,map);
%// Create perspective transformation that warps the original
%// image coordinates to the trapezoid
movingPoints = [1 1; size(img,2) 1; 1 size(img,1); size(img,2) size(img,1)];
fixedPoints = [180 100; 340 100; 50 300; 450 300];
tform = fitgeotrans(movingPoints, fixedPoints, 'Projective');
%// Create a reference coordinate system where the extent is the size of
%// the image
RA = imref2d([size(img,1) size(img,2)], [1 size(img,2)], [1 size(img,1)]);
%// Warp the image
[out,r] = imwarp(img, tform, 'OutputView', RA);
%// Show the image and turn off the axes
imshow(out, r);
axis off;
Upvotes: 9