Ask Your Question
2

Runnig cv::warpPerspective on points

asked 2013-07-25 02:55:45 -0500

engine gravatar image

updated 2013-07-25 04:54:37 -0500

Hi !

I'm running the cv::warpPerspective() function on a image and what to get the position of the some points of result image the I get in the source image, here how far I came :

    cv::Point2f srcQuad[4],dstQuad[4];
    cv::Mat warpMatrix;
    cv::Mat inverseMatrix;
    cv::Mat src, dst,src2;
    src = cv::imread("blue.jpg",1);
    srcQuad[0].x = 0; //src Top left
    srcQuad[0].y = 0;
    srcQuad[1].x = src.cols - 1; //src Top right
    srcQuad[1].y = 0;
    srcQuad[2].x = 0; //src Bottom left
    srcQuad[2].y = src.rows - 1;
    srcQuad[3].x = src.cols -1; //src Bot right
    srcQuad[3].y = src.rows - 1;
    dstQuad[0].x = src.cols*0.05; //dst Top left
    dstQuad[0].y = src.rows*0.33;
    dstQuad[1].x = src.cols*0.9; //dst Top right
    dstQuad[1].y = src.rows*0.25;
    dstQuad[2].x = src.cols*0.2; //dst Bottom left
    dstQuad[2].y = src.rows*0.7;
    dstQuad[3].x = src.cols*0.8; //dst Bot right
    dstQuad[3].y = src.rows*0.9;
    std::vector<cv::Point2f> mySrcPoints;
    cv::Mat mydst;

    mySrcPoints.push_back(cvPoint(5,10));
    mySrcPoints.push_back(cvPoint(50,20));     
    cv::rectangle(
            src,
            cv::Point(5,10),
            cv::Point(20,30),
            cv::Scalar(255,255,255)
       );        
    warpMatrix =cv::getPerspectiveTransform(srcQuad,dstQuad);
    cv::warpPerspective(cv::Mat(mySrcPoints),mydst,warpMatrix,src.size(),CV_WARP_INVERSE_MAP);
    for( int r = 0 ; r < mydst.rows ; ++r )
{
    for( int c = 0 ; c < mydst.cols ; ++c )
    {
        if(mydst.at< float >( r, c )!=0)
         std::cout << "Point at " << r << "," << c << " is wrap at " << mydst.at< float >( r, c ) << std::endl;
    }
}

    //cv::imshow("my dst ", mydst);
    //cv::Point x = converting(poi,warpMatrix);
    //std::cout <<"Converting for the first time  \n "<<x<< std::endl;
    cv::invert(warpMatrix,inverseMatrix);
    //cv::Point y = converting(poi,inverseMatrix);
    //std::cout <<"Converting for the second time  \n "<<y<< std::endl;
    cv::warpPerspective(src,dst,warpMatrix,src.size());
    cv::imshow("source", src);
    cv::imshow("destination", dst);
    cv::warpPerspective(dst,src2,warpMatrix,dst.size(),CV_WARP_INVERSE_MAP);
    cv::imshow("srouce 2 ", src2);
    cv::waitKey();
    return 0;

my problem is that if I select a point from dst how can get its coordinates in * src or src2 * since the cv::warpPerspective function doesn't take cv::Point as parameter ??

edit retag flag offensive close merge delete

3 answers

Sort by ยป oldest newest most voted
1

answered 2013-07-25 03:41:00 -0500

SR gravatar image

updated 2013-07-25 03:44:09 -0500

Use cv::perspectiveTransform().

You might need to convert your array of points into a matrix.

edit flag offensive delete link more
0

answered 2017-06-01 03:15:32 -0500

franc gravatar image
cv::Matx33f M = cv::getPerspectiveTransform(srcQuad, dstQuad);
cv::Point3f p(x, y, 1);

p = M.inv() * p; // dst -> src
// p = M * p; // src -> dst
p = p * (1.0 / p.z);

cv::Point2f point(p.x, p.y);
edit flag offensive delete link more
0

answered 2013-07-25 03:52:16 -0500

The matrix in parameter is working like a set of point (you could use a vector of point to init a matrix).

std::vector< cv::Point2f > mySrcPoints;
... // fill the vector
cv::Mat dst;
cv::warpPerspective( cv::Mat( mySrcPoints ), dst, warpMatrix, dst.size(), CV_WRAP_INVERSE_MAP );
// To get the points
for( int r = 0 ; r < dst.rows ; ++r )
{
    for( int c = 0 ; c < dst.cols ; ++c )
    {
        std::cout << "Point at " << r << "," << c << " is wrap at " << dst.at< float >( r, c ) << std::endl;
    }
}

This is working even if you don't set the input without a vector. But the destination point matrix is of the same type as the input matrix, don't forget that when you use the template accessor .at< TYPE >( row, col )!

edit flag offensive delete link more

Comments

I tried your suggestion, but the result is always 0 ?? have a look at the update

engine gravatar imageengine ( 2013-07-25 04:52:36 -0500 )edit

This is false. cv::warpPerspective() does not work at all for mapping points from one image to another. It actually computes each pixel of the transformed image by interpolating the neighboring pixel values of the original image as determined by the inverse mapping M^-1 of the given perspective transformation M.

SR gravatar imageSR ( 2013-07-25 05:16:44 -0500 )edit

this means that what I'm trying to do isn't possible ? ???

engine gravatar imageengine ( 2013-07-25 05:19:51 -0500 )edit

This means you cannot use cv::warpPerspective() for this. Use cv::perspectiveTransform().

SR gravatar imageSR ( 2013-07-25 05:21:55 -0500 )edit

Hm, my fault. It seems it should work with cv::warpPerspective() if you set the WARP_INVERSE_MAP flag. Nevertheless, I prefer cv::perspectiveTransform() as it is straightforward.

SR gravatar imageSR ( 2013-07-25 05:26:11 -0500 )edit

I can get the back transformation with cv::warpPerspective, but how can't to that only for a set points ?

engine gravatar imageengine ( 2013-07-25 05:35:21 -0500 )edit
Login/Signup to Answer

Question Tools

Stats

Asked: 2013-07-25 02:55:45 -0500

Seen: 7,791 times

Last updated: Jun 01 '17