当前位置: 首页> 文旅> 酒店 > 福州全网网站建设_小明seo教程_互联网销售公司_网络营销活动策划方案模板

福州全网网站建设_小明seo教程_互联网销售公司_网络营销活动策划方案模板

时间:2025/8/27 2:53:51来源:https://blog.csdn.net/weixin_42215453/article/details/143600761 浏览次数:0次
福州全网网站建设_小明seo教程_互联网销售公司_网络营销活动策划方案模板

函数

RotatedRect minAreaRect(InputArray points)
//  points:输入信息,可以为包含点的容器(vector)或是Mat。 

        为了返回包含输入信息的最小斜矩形,我们采用一个名为Box2D的结构体rect,该结构体包含最小外接矩形的中心坐标(x,y)、尺寸(宽度,高度)以及旋转角度。然而,为了绘制这个矩形,我们需要获取矩形的四个顶点坐标,这可以通过调用BoxPoints()函数来实现。该函数返回一个包含四个顶点坐标的列表,形式为[ [x0,y0], [x1,y1], [x2,y2], [x3,y3] ]

 问题

        在实际应用中,minAreaRect()函数在计算并返回点集的最小外接矩形时,虽然提供了旋转矩形的形式,并包含了目标的旋转角度,这为图像矫正或其他应用提供了极大的便利。然而,该函数的使用也伴随着一些挑战,其中最为突出的是角度计算方式的不明确性:

  • 角度计算的不确定性minAreaRect()函数所返回的角度,其计算方法和参考基准可能并不直观或明确。例如,该角度是以哪个方向为基准(如水平轴或垂直轴)进行测量的?是顺时针还是逆时针方向?这些不明确之处可能导致用户在理解和应用该角度时出现困惑。

定点坐标顺序变化的原因及解决方案

理解原理

为了深入理解为何会出现定点坐标顺序变化的问题,我们首先需要明确minAreaRect函数的运作原理。通过查阅资料,我们了解到minAreaRect函数返回的角度位于-90到0之间(不包括0),即[-90, 0)区间。旋转中心为矩形的几何中心。当图像处于水平状态时,函数返回-90度;随着矩形顺时针旋转,角度逐渐增大(趋向于0)。当角度达到一个完整的90度循环时,即图像再次回到水平状态,函数给出的角度会重新从-90度开始。这就解释了为何在某些情况下,如图2和图3所示,尽管矩形看起来旋转了不同的角度,但minAreaRect函数返回的角度却相同。在图2中,以长边为基准旋转90度后,角度理应变化,但由于函数的周期性,它仍然返回初始角度附近的值。

角度区间的变化

值得注意的是,minAreaRect函数返回的角度区间并非一成不变。随着OpenCV版本的更新,接口可能发生变化。在opencv-3.1.13.47及更早版本中,函数返回的角度位于[-90, 0)区间;而在后续版本中,返回的角度则位于(0, 90]区间。这解释了为何在某些情况下,我们会看到与预期不符的角度值。例如,在图3中,如果以长边为基准,则角度应为75度,但由于版本差异导致的角度区间变化,实际返回的角度可能与预期不符。

解决方案

针对这一问题,我们可以采取以下解决方案:

  1. 确认OpenCV版本:首先,明确你所使用的OpenCV版本,以便了解minAreaRect函数在该版本中的具体行为。

  2. 选择基准边:根据目标的具体形状,选择长边或短边作为基准边。这将有助于你更准确地解释minAreaRect函数返回的角度。

  3. 角度换算:如果函数返回的角度与你的预期不符,你可以根据所选的基准边进行角度换算。例如,在图3中,如果以长边为基准,且你使用的是返回(0, 90]区间的OpenCV版本,则你可以通过计算实际角度与minAreaRect返回角度之和为90度来进行转换。

  4. 编写通用代码:为了兼容不同版本的OpenCV,你可以编写一段通用代码来自动检测版本差异,并根据需要调整角度计算方式。

通过上述步骤,你可以更有效地解决定点坐标顺序变化的问题,并确保minAreaRect函数返回的角度与你的预期相符。

#include <opencv2/opencv.hpp>
#include <vector>
#include <cstdio>using namespace cv;
using namespace std;void printAngle(RotatedRect rect, bool isLongerSideVertical) {float angle = rect.angle;if (!isLongerSideVertical) {angle = 90 - angle;if (angle < 0) angle += 90; // Handle negative angles due to periodicity} else if (angle > 0) {angle -= 90; // Convert to equivalent angle within [-90, 0)}printf("Angle: %7.2f\n", angle);
}int minAreaRectTest() {float angle = 0.0f;Mat image = Mat::zeros(800, 1600, CV_8UC3);RotatedRect originalRect;vector<Point2f> points;RotatedRect calculatedRect;bool isLongerSideVertical = true; // Assume initially the longer side is verticalwhile (true) {int key = waitKey(10);if (key == 27) break; // ESC to exitif (key == 32) {waitKey(0); // Space to pausecontinue;}// Create a rectangle and rotate itoriginalRect = RotatedRect(Point2f(400, 400), Size2f(400, 200), angle);// Get the points of the rectangleoriginalRect.points(points);// Offset the points for visualizationfor (auto& pt : points) {pt += Point2f(800, 0);}// Get the minAreaRect for the pointscalculatedRect = minAreaRect(points);// Determine if the longer side is vertical or horizontalisLongerSideVertical = calculatedRect.size.width < calculatedRect.size.height;// Draw rectanglesline(image, points[0], points[1], Scalar(0, 255, 0), 2);line(image, points[1], points[2], Scalar(0, 255, 0), 2);line(image, points[2], points[3], Scalar(0, 255, 0), 2);line(image, points[3], points[0], Scalar(0, 255, 0), 2);Point2f box[4];calculatedRect.points(box);for (int i = 0; i < 4; i++) {line(image, box[i], box[(i + 1) % 4], Scalar(255, 0, 0), 2);}imshow("rectangles", image);// Print anglesprintf("---\n");printf("Original angle: %7.2f\n", angle);printAngle(calculatedRect, isLongerSideVertical);printf("---\n");// Reset image for next frameimage = Mat::zeros(800, 1600, CV_8UC3);// Decrement angle for next frameangle -= 0.1f;if (angle <= -90.0f) angle = -89.9f; // Avoid wrapping around to positive angles}destroyAllWindows();return 0;
}int main() {minAreaRectTest();return 0;
}

 

关键字:福州全网网站建设_小明seo教程_互联网销售公司_网络营销活动策划方案模板

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

责任编辑: