一、先看十字光标怎么绘制
源码如下:
void pointRotate(const cv::Point2d &src, const cv::Point2d &base, double angle, cv::Point2d &dst)
{
//旋转角度参数angle,单位是角度,非弧度
//点A(x1, y1)基于点O(x0, y0)逆时针旋转angle角度后,得到点B(x2,y2),求解点B坐标
double x1 = src.x; //点A
double y1 = src.y;
double x0 = base.x;
double y0 = base.y; //点O
double theta = angle * CV_PI / 180.0; //角度转弧度
double x2 = (x1 - x0) * cos(theta) - (y1 - y0) * sin(theta) + x0; //点B
double y2 = (x1 - x0) * sin(theta) + (y1 - y0) * cos(theta) + y0;
dst.x = x2;
dst.y = y2;
}
void drawCross(cv::Mat &image, cv::Point center, int len, cv::Scalar color, int thickness, double angle)
{
//不旋转
if (fabs(angle) < 0.001)
{
//绘制横线
cv::line(image, cv::Point(center.x - len / 2, center.y), cv::Point(center.x + len / 2, center.y), color, thickness);
//绘制竖线
cv::line(image, cv::Point(center.x, center.y - len / 2), cv::Point(center.x, center.y + len / 2), color, thickness);
return;
}
//旋转角度angle,单位是角度,非弧度
cv::Point2d p1;
cv::Point2d p2;
//绘制x线
double x1 = center.x - len / 2;
double x2 = center.x + len / 2;
double y = center.y;
pointRotate(cv::Point2d(x1, y), center, angle, p1);
pointRotate(cv::Point2d(x2, y), center, angle, p2);
cv::line(image, p1, p2, color, thickness);
//绘制y线
double y1 = center.y - len / 2;
double y2 = center.y + len / 2;
double x = center.x;
pointRotate(cv::Point2d(x, y1), center, angle, p1);
pointRotate(cv::Point2d(x, y2), center, angle, p2);
cv::line(image, p1, p2, color, thickness);
}
测试:
cv::circle(imageMatch, cv::Point(col, row), 10, cv::Scalar(0, 0, 255), 1);
drawCross(imageMatch, cv::Point(col, row), 10, cv::Scalar(0, 0, 255), 1, angle);
二、再看旋转矩形怎么绘制
cv::Mat output, cv::Point center, float angle, cv::Rect valid;
int linesize = 2;
//画矩形框
if (fabs(angle) < 0.0001)
{
cv::rectangle(output, valid, cv::Scalar(255, 0, 0), linesize); //不旋转
}
else
{
float deg = angle * 180 / CV_PI; //弧度转角度
cv::RotatedRect rRect = cv::RotatedRect(center, valid.size(), deg); //旋转矩形
cv::Point2f vertices[4];
rRect.points(vertices);
for (int i = 0; i < 4; i++)
{
cv::line(output, vertices[i], vertices[(i + 1) % 4], cv::Scalar(255, 0, 0), linesize);
}
}
三、已知矩形A,求旋转矩形B,再由B求最小外接矩形C
cv::Rect region;//已知矩形A
cv::Point2d base;
double degree;
std::vector<Point2d> vertices(4);//待求的旋转矩形B的4个顶点
cv::Point2d p1 = cv::Point2d(region.x, region.y);
cv::Point2d p2 = cv::Point2d(region.x + region.width, region.y);
cv::Point2d p3 = cv::Point2d(region.x + region.width, region.y + region.height);
cv::Point2d p4 = cv::Point2d(region.x, region.y + region.height);
pointRotate(p1, base, -degree, vertices[0]);
pointRotate(p2, base, -degree, vertices[1]);
pointRotate(p3, base, -degree, vertices[2]);
pointRotate(p4, base, -degree, vertices[3]);
//请注意,cv::boundingRect不接受std::vector<Point2d>类型,所以转换为std::vector<Point2f>
std::vector<Point2f> v;
for (auto p : vertices)
{
v.emplace_back(p);
}
cv::Rect r = cv::boundingRect(v); //最小外接矩形C
---
引申阅读,旋转矩形
OpenCV之RotatedRect基本用法和角度探究_sandalphon4869的博客-CSDN博客_rotatedrect