描述
opencv可以利用rect,绘制出与图像坐标系u轴v轴平行的,姿态正的矩形
如果该矩形绕其原点旋转,如何画出呢?
思路
利用原矩形的四个点,根据旋转角度,计算出新的四个端点。最后将四个端点利用画线的方式链接起来,就能实现了
代码
利用原始四个端点及旋转角度,得到新的端点,代码如下:
int x_new = (x_old - x_center)*cos(theta) - (y_old - y_center)*sin(theta) + x_center;
int y_new = (x_old - x_center)*sin(theta) + (y_old - y_center)*cos(theta) + y_center;
上式以一个端点的计算为例
x_old和y_old代表该端点的原始坐标,theta代表绕矩形旋转中心的旋转角度,x_center和y_center代表旋转中心的坐标。这些点坐标可以是世界坐标,也可以是图像坐标,都可以直接带入。只不过要注意theta的正负。上述公式代表theta是,x轴正方向向右,y轴正方向向上的坐标系下,逆时针旋转的角度。显然如果是图像中的像素坐标点计算,你应该把theta加一个负号,因为图像y轴也就是v轴,是朝下的
没什么难度,实际上还是二维坐标变换那一套东西,唯一需要注意的就是结合情况觉得左乘还是右乘旋转矩阵罢了。我有另外一篇文章介绍过,感兴趣可以去阅读
下面一段代码是我为了画一个旋转车体的代码,变量是我的定义方式,根据名字容易自行理解
// 画出车的矩形
std::vector<cv::Point> car_rect_points_standard;
int length_half = BIRD_CAR_LENGTH/BIRD_SCALE/2;
int width_half = BIRD_CAR_WIDTH/BIRD_SCALE/2;
car_rect_points_standard.push_back(cv::Point(car_point_grid.x - length_half, car_point_grid.y - width_half));
car_rect_points_standard.push_back(cv::Point(car_point_grid.x + length_half, car_point_grid.y - width_half));
car_rect_points_standard.push_back(cv::Point(car_point_grid.x + length_half, car_point_grid.y + width_half));
car_rect_points_standard.push_back(cv::Point(car_point_grid.x - length_half, car_point_grid.y + width_half));
// 车体需要根据偏航角yaw进行调整
int rx0 = car_point_grid.x;
int ry0 = car_point_grid.y;
float a = -m_pose_now.yaw;
std::vector<cv::Point> car_rect;
for (int i = 0; i < 4; i++) {
int x = car_rect_points_standard[i].x;
int y = car_rect_points_standard[i].y;
int x0 = (x - rx0)*cos(a) - (y - ry0)*sin(a) + rx0;
int y0 = (x - rx0)*sin(a) + (y - ry0)*cos(a) + ry0;
car_rect.push_back(cv::Point(x0, y0));
}
cv::Mat m_image_run_show = m_image_run.clone();
for (int i = 0; i < 4; i++)
{
cv::line(m_image_run_show, car_rect[i], car_rect[(i + 1) % 4], cv::Scalar(255), 1, 8, 0);
}
结论
利用二维点的坐标变换,求出新的坐标点