Ask Your Question

jesperhag's profile - activity

2020-10-21 16:12:02 -0600 received badge  Student (source)
2014-10-08 08:28:46 -0600 asked a question Using transform matrix from larger area on ROI

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)