c++ - C++ 中的 4 点 OpenCV 裁剪透视图
问题描述
我正在寻找一种将图像裁剪 4 点的方法。我找到了这个来源,但是当我使用它时,结果是错误的。
原始来源: 这是原始来源
有什么问题?
这是我的来源:
int main()
{
cv::Mat src = cv::imread("E:\\aaaaaa.jpg");
vector<Point> not_a_rect_shape;
not_a_rect_shape.push_back(Point(2224, 257));
not_a_rect_shape.push_back(Point(372, 393));
not_a_rect_shape.push_back(Point(338, 1498));
not_a_rect_shape.push_back(Point(2397, 1414));
// For debugging purposes, draw green lines connecting those points
// and save it on disk
const Point* point = ¬_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, LINE_AA);
imwrite("E:\\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;
Point2f pts[4];
box.points(pts);
// Does the order of the points matter? I assume they do NOT.
// But if it does, is there an easy way to identify and order
// them as topLeft, topRight, bottomRight, bottomLeft?
cv::Point2f src_vertices[3];
src_vertices[0] = pts[0];
src_vertices[1] = pts[1];
src_vertices[2] = pts[3];
//src_vertices[3] = not_a_rect_shape[3];
Point2f dst_vertices[3];
dst_vertices[0] = Point(0, 0);
dst_vertices[1] = Point(box.boundingRect().width - 1, 0);
dst_vertices[2] = Point(0, box.boundingRect().height - 1);
/* Mat warpMatrix = getPerspectiveTransform(src_vertices, dst_vertices);
cv::Mat rotated;
cv::Size size(box.boundingRect().width, box.boundingRect().height);
warpPerspective(src, rotated, warpMatrix, size, INTER_LINEAR, BORDER_CONSTANT);*/
Mat warpAffineMatrix = getAffineTransform(src_vertices, dst_vertices);
cv::Mat rotated;
cv::Size size(box.boundingRect().width, box.boundingRect().height);
warpAffine(src, rotated, warpAffineMatrix, size, INTER_LINEAR, BORDER_CONSTANT);
imwrite("E:\\rotated.jpg", rotated);
return 0;
}
那么我该如何解决呢?
谢谢你。
解决方案
您错误地匹配pts
边界框的点。
参考对方法有什么看法RotatedRect::points
?:
void cv::RotatedRect::points (Point2f pts[]) const 返回矩形的 4 个顶点
参数 pts 存储矩形顶点的点数组。顺序是bottomLeft、topLeft、topRight、bottomRight。
在坐标系 XY 中,它看起来像:
(0,0)--------------------------------> x
|
| topLeft ----- topRight
| / \
| / \
| bottomLeft --------------------- bottomRight
\ /
y
这个
src_vertices[0] = pts[0]; // bottomLeft
src_vertices[1] = pts[1]; // topLeft
src_vertices[2] = pts[3]; // bottomRight
应该对应于(很容易转换为边界框的坐标):
Point2f dst_vertices[3];
dst_vertices[0] = Point(0, box.boundingRect().height);
dst_vertices[1] = Point(0, 0);
dst_vertices[2] = Point(box.boundingRect().width, box.boundingRect().height);
推荐阅读
- c# - 从 Windows 服务而不是控制台应用程序获取错误“无法创建 Active X 组件”
- c#-4.0 - 用字符串分割逗号的正则表达式
- laravel - 如何在 Laravel 5.6 中将数组插入数据库
- kotlin - Intellij 自动完成在多平台库依赖项上失败
- mypy - 是否可以运行 mypy pre-commit 而不会失败?
- python - attr.asdict(x) 和 x.__dict__ 有什么区别?
- python - 使用并行计算的 for 循环
- view - Maximo:如何在主要对象为视图的应用程序中启用列表选项卡中的搜索
- c# - 泛型类约束多级继承
- angularjs - 手动插入一次性绑定