3

I am trying to find out how I can transform a coordinate Pxy within the green trapezoid below into the equivalent coordinate on the real ground plane.

I have the exact measures of the room, meaning I can exactly say how long A,B,C and D are in that room shown below. Also I know how long A,B,C and D are in that green triangle (coordinate wise).

I have already been reading about homography and matrix transformation, but can't really wrap my head around it. Any input steering me into the right direction would be appreciated.

Thanks!

enter image description here

Sebastian Borggrewe
  • 1,260
  • 4
  • 13
  • 25
  • I think I need to clarify, that I am not looking to transform an image here. I am looking for a method to transform A,B,C,D into a rectangle of known size and alongside transform Pxy into the known rectangle. – Sebastian Borggrewe Feb 12 '13 at 14:26
  • 2
    See http://stackoverflow.com/a/14178717/1832154, it presents code to find the coefficients for the homographic transform as well a link that explains it. By achieving this matrix, you can directly find to where your point `Pxy` will be mapped to. – mmgp Feb 12 '13 at 16:06

3 Answers3

2

There is the code computes the affine transformation matrix using the library Opencv (it shows how to trasform your trapezoid to rectangle and how to find transformation matrix for futher calculations):

//example from book
//   Learning OpenCV: Computer Vision with the OpenCV Library
//     by Gary Bradski and Adrian Kaehler
//     Published by O'Reilly Media, October 3, 2008

#include <cv.h>
#include <highgui.h>
#include <stdlib.h>
#include <stdio.h>

int main(int argc, char* argv[])
{
    IplImage *src=0, *dst=0;

    // absolute or relative path to image should be in argv[1]
    char* filename = argc == 2 ? argv[1] : "Image0.jpg";
    // get the picture
    src = cvLoadImage(filename,1);

    printf("[i] image: %s\n", filename);
    assert( src != 0 );


    // points (corners of )
    CvPoint2D32f srcQuad[4], dstQuad[4];
    // transformation matrix
    CvMat* warp_matrix = cvCreateMat(3,3,CV_32FC1);

    // clone image
    dst = cvCloneImage(src);

    // define all the points
    //here the coordinates of corners of your trapezoid 
    srcQuad[0].x = ??;   //src Top left
    srcQuad[0].y = ??;
    srcQuad[1].x = ??;   //src Top right
    srcQuad[1].y = ??;
    srcQuad[2].x = ??;   //src Bottom left
    srcQuad[2].y = ??;
    srcQuad[3].x = ??;   //src Bot right
    srcQuad[3].y = ??;
    //- - - - - - - - - - - - - -//
    //coordinates of rectangle in src image 
    dstQuad[0].x = 0;       //dst Top left
    dstQuad[0].y = 0;
    dstQuad[1].x = src->width-1;  //dst Top right
    dstQuad[1].y = 0;
    dstQuad[2].x = 0;     //dst Bottom left
    dstQuad[2].y = src->height-1;      
    dstQuad[3].x = src->width-1;  //dst Bot right
    dstQuad[3].y = src->height-1;

    // get transformation matrix that you can use to calculate 
    //coordinates of point Pxy  
    cvGetPerspectiveTransform(srcQuad,dstQuad,warp_matrix);
    // perspective transformation
    cvWarpPerspective(src,dst,warp_matrix);


    cvNamedWindow( "cvWarpPerspective", 1 );
    cvShowImage( "cvWarpPerspective", dst );

    cvWaitKey(0);

    cvReleaseMat(&warp_matrix);

    cvReleaseImage(&src);
    cvReleaseImage(&dst);

    cvDestroyAllWindows();
    return 0;

Hope it will be helpfull!

Ann Orlova
  • 1,338
  • 15
  • 24
  • Hi Ann, I am not really looking for an image to transform. However I understand that I get a transformation matrix from this example, but what do you exactly mean by "//coordinates of rectangle in src image". – Sebastian Borggrewe Feb 12 '13 at 14:25
  • Sorry, not rectangle,I meant the corners of your trapazoid in src image. – Ann Orlova Feb 13 '13 at 05:30
2

If I understand your question correctly, you are looking for the transform matrix that expresses the position and orientation (aka the "pose") of your camera in relation to the world. If you have this matrix - lets call it M - you could map any point from your camera coordinate frame to the world coordinate frame and vice versa. In your case you'll want to transform a rectangle onto the plane (0, 1, 0)^T + 0 in world coordinates.

There are several ways to derive this pose Matrix. First of all you'll need to know another matrix - K - which describes the internal camera parameters to convert positions in the camera coordinate frame to actual pixel positions. This involves a standard pinhole projection as well as radial distortion and a few other things.

To determine both K and M you have to calibrate your camera. This is usually done by taking a calibration pattern (e.g. a chessboard-pattern) for which the positions of the chessboard-fields are known. Then you can establish so called Point-Correspondences between the known positions on the pattern and the observed pixel-positions. Once you have enough of these point-pairs you can solve a Matrix H = KM. This is your Homography matrix you've mentioned already. Once you have that, you can reconstruct K and M.

So much for the theory. For the practical part I would suggest to have a look at the OpenCV-Documentations (e.g. you could start here: OpenCV Camera calibration and here: OpenCV Pose estimation).

I hope this will point you in the right directions ;)

1

Just for the sake of completion. I ended up looking at the thread suggested by @mmgp and implemented a solution that is equivalent to the one presented by Christopher R. Wren:

Perspective Transform Estimation

This turned out to work really well for my case, although there was some distortion from the camera.

Sebastian Borggrewe
  • 1,260
  • 4
  • 13
  • 25