我想把梯形区域转换成矩形。
示例图片(不是完美的梯形,但你可以理解):
转换为:
我已经能够标记梯形区域的角落,并使用getPerspectiveTransform计算正确的矩阵以便使用warpPerspective来转换图像。
不幸的是,这个转换非常缓慢。在一个720p网络摄像头流的大约80%的区域上使用它会导致帧率下降到约5fps。我怀疑这可能是因为warpPerspective允许进行比我需要的更多的转换。
有没有更快的方法将图像从梯形转换为矩形?(最好使用OpenCV)
更多信息:
- warpAffine 可用于进行仿射变换。它比warpPerspective更快,但(如果我理解正确)你只能改变平行四边形的角度。
- 有点相关但没有答案:梯形到矩形
一个基于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;
}