Opencv画出斜矩形

描述

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);
}

结论

利用二维点的坐标变换,求出新的坐标点

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值