Using transform matrix from larger area on ROI [closed]

asked 2014-10-08 08:28:46 -0600

jesperhag gravatar image

I've a problem that I don't really know how to solve. The situation is that I've got a picture, inside this picture I have one ROI (a large rect). Inside this rect I then have X number of smaller ROI:s.

I then use the getPerspectiveTransform() method on the larger of the ROI. What I then want to do is to apply this matrix on the smaller ROI:s in-order to warp them separately but using the matrix from the larger ROI. The reason I want to do this is basically because I want to keep the bounding rects I've got before the warp. If there is any way to warp the larger ROI and keep the bounding rects inside of this (i.e. keep the smaller ROI:s) that would be very helpful!

Anyway, this is what I've tried and the results it produces:

vector<Mat> warpSmallerRoi( vector<Rect> smallerRoi ) { 

    vector<Mat> quad;

    for( int i = 0; i < smallerRoi.size(); ++ i ) {
        Mat wholeQuad;

        wholeQuad = Mat::zeros( originalImage(smallerRoi[i]).rows, originalImage(smallerRoi[i]).cols, CV_8UC1 );
        vector<Point2f> largerRoiCorners;
        vector<Point2f> quadPoints;

        // Takes the corners from the first smaller ROI and the last smaller ROI, represents the bigger ROI
        largerRoiCorners.push_back( Point2f( smallerRoi[0].tl().x, smallerRoi[0].tl().y ) ); // Top left
        largerRoiCorners.push_back( Point2f( smallerRoi[ smallerRoi.size() - 1 ].br().x, smallerRoi[ smallerRoi.size() - 1  ].tl().y ) ); // Top right
        largerRoiCorners.push_back( Point2f( smallerRoi[ smallerRoi.size() - 1 ].br().x, smallerRoi[ smallerRoi.size() - 1  ].br().y ) ); // Bottom right
        largerRoiCorners.push_back( Point2f( smallerRoi[0].tl().x, smallerRoi[0].br().y ) ); // Bottom left

        quadPoints.push_back( Point2f(0, 0) );
        quadPoints.push_back( Point2f(wholeQuad.cols, 0) );
        quadPoints.push_back( Point2f( wholeQuad.cols, wholeQuad.rows ) );
        quadPoints.push_back( Point2f(0, wholeQuad.rows) );

        // Transform matrix for the larger ROI, this warps into a perfect result.
        Mat largerRoiTransformMatrix = getPerspectiveTransform( largerRoiCorners, quadPoints );

        //Corners of the smaller ROI
        vector<Point2f> corners;
        corners.push_back( Point2f( smallerRoi[i].tl().x, smallerRoi[i].tl().y ) ); // Top left
        corners.push_back( Point2f( smallerRoi[i].br().x, smallerRoi[i].tl().y ) ); // Top right
        corners.push_back( Point2f( smallerRoi[i].br().x, smallerRoi[i].br().y )); // Bottom right
        corners.push_back( Point2f( smallerRoi[i].tl().x, smallerRoi[i].br().y ) ); // Bottom left

        Mat transformMatrix = getPerspectiveTransform( corners, quadPoints );

        /* This part is just experimental and does not work all the time, it works well sometimes though 
           Uses the pars from the larger ROI transform matrix and applies it on the smaller ROI
           then warps it.
        */
        transformMatrix.at<double>(1,0) = largerRoiTransformMatrix.at<double>(1,0);
        transformMatrix.at<double>(1,1) = largerRoiTransformMatrix.at<double>(1,1);
        transformMatrix.at<double>(1,2) = largerRoiTransformMatrix.at<double>(1,2);

        transformMatrix.at<double>(2,0) = largerRoiTransformMatrix.at<double>(2,0);
        transformMatrix.at<double>(2,1) = largerRoiTransformMatrix.at<double>(2,1);
        transformMatrix.at<double>(2,2) = largerRoiTransformMatrix.at<double>(2,2);

        // Warps the 
        warpPerspective( plateRgb, wholeQuad, transformMatrix, wholeQuad.size() );
        quad.push_back(wholeQuad);
    }
    return quad;
}

This function works sometimes, especially when the larger ROI is already pretty straight (I guess this is because my replacements are ... (more)

edit retag flag offensive reopen merge delete

Closed for the following reason question is not relevant or outdated by sturkmen
close date 2020-10-21 16:12:20.088894

Comments

As you said while the skew increase warped image may cropped, because you are using the destination size same as source, you may need to calculate the destination image size according to angle. See the answer here.

Haris gravatar imageHaris ( 2014-10-08 11:19:41 -0600 )edit