为了账号安全,请及时绑定邮箱和手机立即绑定

在一组cv :: Point上执行cv :: warpPerspective以进行伪偏移

在一组cv :: Point上执行cv :: warpPerspective以进行伪偏移

C++
慕尼黑8549860 2019-09-19 15:08:30
我正在尝试对一组点进行透视变换以实现偏斜效果:http://nuigroup.com/?ACT=28&fid=27&aid=1892_H6eNAaign4Mrnn30Au8d我正在使用下面的图像进行测试,绿色矩形显示感兴趣的区域。我在想,如果有可能实现,我希望使用的简单组合的效果cv::getPerspectiveTransform和cv::warpPerspective。我正在分享我到目前为止所写的源代码,但它不起作用。这是结果图像因此,有一个vector<cv::Point>是定义感兴趣的区域,但点不存储在任何特定的顺序载体内,这件事情我不能在检测过程中发生改变。无论如何,稍后,向量中的点用于定义a RotatedRect,而这又用于组装cv::Point2f src_vertices[4];,所需的变量之一cv::getPerspectiveTransform()。我对顶点及其组织方式的理解可能是其中一个问题。我还认为使用a RotatedRect不是存储ROI原始点的最佳方法,因为坐标会稍微改变以适应旋转的矩形,这并不是很酷。#include <cv.h>#include <highgui.h>#include <iostream>using namespace std;using namespace cv;int main(int argc, char* argv[]){    cv::Mat src = cv::imread(argv[1], 1);    // After some magical procedure, these are points detect that represent     // the corners of the paper in the picture:     // [408, 69] [72, 2186] [1584, 2426] [1912, 291]    vector<Point> not_a_rect_shape;    not_a_rect_shape.push_back(Point(408, 69));    not_a_rect_shape.push_back(Point(72, 2186));    not_a_rect_shape.push_back(Point(1584, 2426));    not_a_rect_shape.push_back(Point(1912, 291));    // For debugging purposes, draw green lines connecting those points     // and save it on disk    const Point* point = &not_a_rect_shape[0];    int n = (int)not_a_rect_shape.size();    Mat draw = src.clone();    polylines(draw, &point, &n, 1, true, Scalar(0, 255, 0), 3, CV_AA);    imwrite("draw.jpg", draw);    // Assemble a rotated rectangle out of that info    RotatedRect box = minAreaRect(cv::Mat(not_a_rect_shape));    std::cout << "Rotated box set to (" << box.boundingRect().x << "," << box.boundingRect().y << ") " << box.size.width << "x" << box.size.height << std::endl;    }有人可以帮我解决这个问题吗?
查看完整描述

3 回答

?
慕尼黑5688855

TA贡献1848条经验 获得超2个赞

问题是在向量内声明点的顺序,然后在定义上还有另一个与此相关的问题dst_vertices。


该点的顺序关系到getPerspectiveTransform(),必须按以下顺序指定:


1st-------2nd

 |         |

 |         |

 |         |

3rd-------4th

因此,原产地需要重新订购:


vector<Point> not_a_rect_shape;

not_a_rect_shape.push_back(Point(408, 69));

not_a_rect_shape.push_back(Point(1912, 291));

not_a_rect_shape.push_back(Point(72, 2186));

not_a_rect_shape.push_back(Point(1584, 2426));

和目的地:


Point2f dst_vertices[4];

dst_vertices[0] = Point(0, 0);

dst_vertices[1] = Point(box.boundingRect().width-1, 0); // Bug was: had mistakenly switched these 2 parameters

dst_vertices[2] = Point(0, box.boundingRect().height-1);

dst_vertices[3] = Point(box.boundingRect().width-1, box.boundingRect().height-1);

在此之后,需要进行一些裁剪,因为生成的图像不仅仅是绿色矩形内的区域,我认为它将是:


我不知道这是不是OpenCV的错误,或者我错过了什么,但主要问题已经解决了。


查看完整回答
反对 回复 2019-09-19
?
qq_遁去的一_1

TA贡献1725条经验 获得超7个赞

使用四边形时,OpenCV并不是你的朋友。RotatedRect会给你不正确的结果。此外,你需要一个透视投影,而不是像这里提到的其他仿射投影。


基本上必须做的是:


遍历所有多边形段并连接几乎相同的多边形段。

对它们进行排序,使您拥有4个最大的线段。

相交这些线,你有4个最可能的角点。

在从角点和已知对象的纵横比收集的透视图上变换矩阵。

我实现了一个Quadrangle处理轮廓到四边形转换的类,并且还将在正确的视角上对其进行转换。



查看完整回答
反对 回复 2019-09-19
  • 3 回答
  • 0 关注
  • 1002 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信