Solution 1:

The problem occurs because the homography maps part of the image to negative x,y values which are outside the image area so cannot be plotted. what we wish to do is to offset the warped output by some number of pixels to 'shunt' the entire warped image into positive coordinates(and hence inside the image area).

Homographies can be combined using matrix multiplication (which is why they are so powerful). If A and B are homographies, then AB represents the homography which applies B first, and then A.

Because of this all we need to do to offset the output is create the homography matrix for a translation by some offset, and then pre-multiply that by our original homography matrix

A 2D homography matrix looks like this :

[R11,R12,T1]
[R21,R22,T2]
[ P , P , 1]

where R represents a rotation matrix, T represents a translation, and P represents a perspective warp. And so a purely translational homography looks like this:

[ 1 , 0 , x_offset]
[ 0 , 1 , y_offset]
[ 0 , 0 ,    1    ]

So just premultiply your homography by a matrix similar to the above, and your output image will be offset.

(Make sure you use matrix multiplication, not element wise multiplication!)

Solution 2:

The secret comes in two parts: the transform matrix (homography), and the resulting image size.

  • calculate a correct transform by using the getPerspectiveTransform(). Take 4 points from the original image, calculate their correct position in the destination, put them in two vectors in the same order, and use them to compute the perspective transform matrix.

  • Make sure the destination image size (third parameter for the warpPerspective()) is exactly what you want. Define it as Size(myWidth, myHeight).

Solution 3:

I have done one method... It is working.

  perspectiveTransform(obj_corners,scene_corners,H);
int maxCols(0),maxRows(0);

 for(int i=0;i<scene_corners.size();i++)
{
   if(maxRows < scene_corners.at(i).y)
        maxRows = scene_corners.at(i).y;
   if(maxCols < scene_corners.at(i).x)
        maxCols = scene_corners.at(i).x;
}

I just find the maximum of the x points and y points respectively and put it on

warpPerspective( tmp, transformedImage, homography, Size( maxCols, maxRows ) );