Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

opencv update homography matrix to fit on an image double the size

Tags:

opencv

I'm doing video stabilization using optical flow. To make calcOpticalFlowPyrLK work faster I'm downscaling the original image 2x and running the function on that.

How can I modify the homograph matrix (retrieved via findHomography) to be able to warpPerspective the original, larger, image.

like image 550
MB. Avatar asked May 29 '12 21:05

MB.


People also ask

What is homography matrix in OpenCV?

Homography is a transformation that maps the points in one point to the corresponding point in another image. The homography is a 3×3 matrix : If 2 points are not in the same plane then we have to use 2 homographs. Similarly, for n planes, we have to use n homographs.

How do you apply a homography matrix to a point?

This spatial relationship is represented by a transformation known as a homography, H, where H is a 3 x 3 matrix. To apply homography H to a point p, simply compute p' = Hp, where p and p' are (3-dimensional) homogeneous coordinates. p' is then the transformed point.

What is the difference between fundamental matrix and homography?

The essential matrix is a more generalized form of a homography. Whereas a homography relates coplanar image space points, the essential matrix relates any set of points in an image to points in another image taken by the same camera.

What is homography matrix?

The homography matrix is a 3x3 matrix but with 8 DoF (degrees of freedom) as it is estimated up to a scale. It is generally normalized (see also 1) with h_{33} = 1 or h_{11}^2 + h_{12}^2 + h_{13}^2 + h_{21}^2 + h_{22}^2 + h_{23}^2 + h_{31}^2 + h_{32}^2 + h_{33}^2 = 1 .


1 Answers

This is a little late and the answer you have works fine but I have one thing to add. I don't like taking functions like getPerspectiveTransform for granted. In this case it is easy to just make the matrix yourself. Image reductions that are powers of 2 are easy. Suppose you have a point and you want to move it to an image with twice the resolution.

float newx = (oldx+.5)*2 - .5;
float newy = (oldy+.5)*2 - .5;

conversely, to go to an image of half the resolution...

float newx = (oldx+.5)/2 - .5;
float newy = (oldy+.5)/2 - .5;

Draw yourself a diagram if you need to and convince yourself it works, remember 0 indexing. Instead of thinking about making your transformation work on other resolutions, think about moving every point to the resolution of your transform, then using your transform, then moving it back. Fortunately you can do all of this in 1 matrix, we just need to build that matrix! First build a matrix for each of the three steps

//move point to an image of half resolution, note it is equivalent to the above equation
project_down=(.5,0,-.25,
               0,.5,-.25,
               0, 0,  1)

//move point to an image of twice resolution, these are inverses of one another
project_up=(2,0,.5,
            0,2,.5,
            0, 0,1)

To make your final transformation just combine them

final_transform = [project_up][your_homography][project_down];

The nice thing is you only have to do this once for any given homography. This should work the same as getPerspectiveTransform (and probably run faster). Hopefully understanding this will help you deal with other questions you may run into regarding image resolution changes.

like image 174
Hammer Avatar answered Jan 02 '23 20:01

Hammer