Fast trapezoid for rectangle for video

I want to convert the trapezoid area to a rectangle. Example Image (not perfectly trapezoidal, but you get the idea):

enter image description here to that: enter image description here

I can already mark the corners of the trapezoid area and use getPerspectiveTransform to calculate the correct matrix for warpPerspective to transform the image.

Unfortunately, this conversion is very slow. Using ~ 80% of the 720p webcam’s stream area drops to ~ 5 frames per second. I suspect this may be because warpPerspective allows for more conversion than I need.

Is there a faster way to convert an image from a trapezoid to a rectangle? (preferably using OpenCV)

:

( ) AldurDisciple, .

#include <opencv2/core/core.hpp>  
#include <opencv2/highgui/highgui.hpp>
#include "opencv2/opencv.hpp"
using namespace cv;
int main() {

    //Mat img = imread("EQ9in.png");
    Mat img = imread("C:\\ss819729\\Aufnahmen\\arbeiten\\EQ9in.png");
    int height = img.rows;
    int width = img.cols;

    vector<Point2f> corners_rectangle, corners_trapezoid;

    corners_rectangle.push_back(Point2f(0, 0));
    corners_rectangle.push_back(Point2f(img.cols, 0));
    corners_rectangle.push_back(Point2f(img.cols, img.rows));
    corners_rectangle.push_back(Point2f(0, img.rows));

    corners_trapezoid.push_back(Point2f(35, 6));
    corners_trapezoid.push_back(Point2f(419, 55));
    corners_trapezoid.push_back(Point2f(404, 44));
    corners_trapezoid.push_back(Point2f(10, 477));

    Mat_<float> H_rectangle_to_trapezoid = cv::getPerspectiveTransform(corners_rectangle, corners_trapezoid);

    cv::Mat_<float> mapx_32f(height, width), mapy_32f(height, width);
    for(int y = 0; y<height; ++y) {
        float *buff_mapx = ((float*) mapx_32f.data)+y*width;
        float *buff_mapy = ((float*) mapy_32f.data)+y*width;
        for(int x = 0; x<width; ++x) {
            cv::Mat_<float> pt(3, 1);
            pt(0) = x;
            pt(1) = y;
            pt(2) = 1;
            pt = H_rectangle_to_trapezoid*pt;
            pt /= pt(2);
            buff_mapx[x] = pt(0);
            buff_mapy[x] = pt(1);
        }
    }
    cv::Mat map1_16u, map2_16u;
    cv::convertMaps(mapx_32f, mapy_32f, map1_16u, map2_16u, CV_16SC2);

    cv::Mat img_rectified;
    cv::remap(img, img_rectified, map1_16u, map2_16u, cv::INTER_LINEAR);

    namedWindow("Rectangle Image", CV_WINDOW_AUTOSIZE);
    while(waitKey(1)!='q') {
        cv::remap(img, img_rectified, map1_16u, map2_16u, cv::INTER_LINEAR);
        imshow("Rectangle Image", img_rectified);
    }
    return 1;
}
+3
1

, , warpPerspective , remap ( ). .

, , , (x,y) :

cv::Mat_<float> corners_rectangle, corners_trapezoid;
// TODO: fill corners_rectangle and corners_trapezoid
cv::Mat_<float> H_rectangle_to_trapezoid = cv::getPerspectiveTransform(corners_rectangle, corners_trapezoid);
cv::Mat_<float> mapx_32f(height,width), mapy_32f(height,width);
for(int y=0; y<height; ++y)
{
    float *buff_mapx=((float*)mapx_32f.data)+y*width;
    float *buff_mapy=((float*)mapy_32f.data)+y*width;
    for(int x=0; x<width; ++x)
    {
        cv::Mat_<float> pt(3,1);
        pt(0) = x;
        pt(1) = y;
        pt(2) = 1;
        pt = H_rectangle_to_trapezoid*pt;
        pt /= pt(2);
        buff_mapx[x] = pt(0);
        buff_mapy[x] = pt(1);
    }
}
cv::Mat map1_16u,map2_16u;
cv::convertMaps(mapx_32f,mapy_32f,map1_16u,map2_16u,CV_16SC2);
// Keep map1_16u & map2_16u, discard the rest

remap:

cv::Mat img_rectified;
cv::remap(img_src, img_rectified, map1_16u, map2_16u, cv::INTER_LINEAR);

, , warpPerspective .

+3

All Articles