Ask Your Question
2

Runnig cv::warpPerspective on points

asked Jul 25 '13

engine gravatar image

updated Jul 25 '13

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 ??

Preview: (hide)

3 answers

Sort by » oldest newest most voted
1

answered Jul 25 '13

SR gravatar image

updated Jul 25 '13

Use cv::perspectiveTransform().

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

Preview: (hide)
0

answered Jun 1 '17

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);
Preview: (hide)
0

answered Jul 25 '13

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 )!

Preview: (hide)

Comments

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

engine gravatar imageengine (Jul 25 '13)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 (Jul 25 '13)edit

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

engine gravatar imageengine (Jul 25 '13)edit

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

SR gravatar imageSR (Jul 25 '13)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 (Jul 25 '13)edit

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

engine gravatar imageengine (Jul 25 '13)edit

Question Tools

Stats

Asked: Jul 25 '13

Seen: 11,916 times

Last updated: Jun 01 '17