jjzjj

MMDetection3D/3D目标检测中的边界框和坐标系介绍(含相关函数以及坐标变换的介绍)

byzy 2024-01-11 原文

1.准备知识

参考:带你玩转 3D 检测和分割 (二):核心组件分析之坐标系和 Box - 知乎

1.1 坐标系介绍

        激光雷达坐标系通常定义如下左图所示,其中指向前方,指向左方,指向上方。

 

        相机坐标系通常定义如上右图所示,其中指向右方,指向下方,指向前方。

1.2 3D边界框的定义

        一般来说,对于自动驾驶目标检测任务而言,一个3D边界框可以由7个参数决定:位置、尺寸以及朝向角/偏航角/旋转角

        一般将与物体朝向平行的棱的长度记为边界框长度,竖直方向棱的长度记为边界框高度,余下一组棱的长度记为边界框宽度,如下左图所示。

        将边界框绕高度轴(对于激光雷达坐标系,高度轴为轴;对于相机坐标系,高度轴为轴)旋转到朝向与轴正方向相同时,边界框与坐标轴平行的3组棱对应的长度分别记为

        对于激光雷达坐标系下的边界框,其即为(如上中图所示);则对于相机坐标系下的边界框,其(如上右图所示)。 

        朝向角为边界框绕高度轴的旋转角度(从轴正向与边界框朝向之间的角度),其正负按照右手螺旋定则确定。

1.3 边界框的坐标变换

        从激光雷达坐标系到相机坐标系:

  • 位置变换直接按照点的坐标变换方法进行(需要坐标变换矩阵);
  • 尺寸上,x_size不变,y_size和z_size交换(原因见1.2节中灰底内容);
  • 旋转角先取相反数,再减去90度。

        角度的变换是由于两个坐标系中,的基准轴轴并不是同一个(相差90度),且由于相机坐标系高度轴正方向向下, 故角度增大的方向从上向下看是顺时针,与激光雷达坐标系中相反。

        注意:上述旋转角的变换的前提条件是,相机坐标系轴与激光雷达坐标系轴朝向相同(多数情况下均符合此条件)。

后续内容是MMDetection3D的相关概念、函数和数据类型的介绍。若只是想了解3D目标检测的坐标系和边界框,则无需继续往下看。 

1.4 origin

        在MMDetection3D一些边界框相关的函数中(如2.3节的函数),存在origin参数,这个origin表示边界框位置坐标对应的那个点在边界框中的相对位置。

        具体来说,在坐标系下先旋转3D边界框到朝向角为0,然后将其缩放为单位正方体,并平移到第一象限,使其一个角点位于坐标系原点,与角点相邻的三条棱分别与三个坐标轴重合。此时边界框位置坐标也相应地被变换到某处,其变换后的坐标即为origin。

        举例来说,一般的数据集会使用边界框底面中心坐标作为边界框的位置坐标,则在激光雷达坐标系下,origin应设为(0.5,0.5,0),如下左图所示:

        而在相机坐标系下,origin应设为(0.5,1,0.5),如上右图所示。

2. mmdet3d/core/bbox/box_np_ops.py中的常用函数

        mmdet3d/core/bbox/box_np_ops.py中有很多与边界框相关的函数,这些函数通常会在数据准备的相关代码中看到。

2.1 remove_outside_points

        目的是去除图像视锥外的点云,仅保留能投影到图像范围内的那些点。

  • 输入
    • 原始点云();
    • 相机修正矩阵(扩维成);
    • 点云坐标系到相机坐标系的坐标变换阵(扩维成);
    • 相机内参矩阵(扩维成);
    • 图像大小
  • 输出
    • 能投影到图像范围内的点云子集()。

2.2 box_camera_to_lidar

        目的是将相机坐标系下的边界框参数变换为激光雷达坐标系下的参数。

  • 输入
    • 相机坐标系下的3D边界框();
    • 相机修正矩阵(扩维成);
    • 点云坐标系到相机坐标系的坐标变换阵(扩维成)。
  • 输出
    • 激光雷达坐标系下的3D边界框()。

        该函数的原理见1.3节。

        注意:该函数默认相机坐标系轴和激光雷达坐标系轴同向;若坐标系不完全对齐(如View-of-Delft数据集),若输入该函数的旋转角定义为绕激光雷达轴的旋转角(朝向激光雷达轴时角度为0),则也可使用该函数。

2.3 points_in_bbox

        目的是统计各点是否落在每个边界框内。

  • 输入
    • 点云 ();
    • 边界框(  ,其与点云定义于同一坐标系下);
    • 旋转轴序号(0,1,2之一,表示高度轴是第几个坐标轴;对于图像坐标系,应设置为1;对于激光雷达坐标系,应设置为2);
    • origin(表示边界框位置坐标在边界框中的相对位置,详见1.4节)。
  • 输出
    • 二值矩阵(,其第行第列为True表示第个点位于第个边界框内) 。

2.4 center_to_corner_box3d

        目的是将边界框的位置、尺寸、朝向角参数转换为边界框的8个角点坐标。

  • 输入
    • 各边界框位置();
    • 各边界框尺寸();
    • 各边界框朝向角();
    • origin(表示边界框位置坐标在边界框中的相对位置,详见1.4节);
    • 旋转轴序号(0,1,2之一,表示高度轴是第几个坐标轴;对于图像坐标系,应设置为1;对于激光雷达坐标系,应设置为2)。
  • 输出
    • 各边界框的8个角点坐标()。

        注意:所有边界框参数、origin以及旋转轴应对应同一坐标系。

3.点云在不同坐标系下的变换

3.1 view_points(位于nuscenes/utils/geometry_utils.py

        目的是将相机坐标系下的点云坐标转换到图像坐标系下。

  • 输入
    • 相机坐标系下的点云();
    • 相机内参矩阵(;可扩维成);
    • 归一化选择(True则输出像素坐标,False则输出像平面上的坐标)。
  • 输出
    • 图像坐标系下的点云(,归一化时前两维为像素坐标,最后一维恒为1;否则最后一维为深度,前两维为)。

3.2 points_cam2img(位于mmdet3d/core/bbox/structures/utils.py)

        目的是将相机坐标系下的点云坐标转换到图像坐标系下。

  • 输入
    • 相机坐标系下的点云();
    • 相机内参矩阵(,可扩维成);
    • 是否包含深度信息的选择(True则输出包含深度信息)。
  • 输出
    • 图像坐标系下的点云(若输出包含深度信息则为,前两维为像素坐标,最一维为深度;否则输出为,为像素坐标)。

注:上述维度中的 “  ” 代表任意多个维度,如可以为等。

3.3 点云数据类型及其坐标变换

        mmdet3d提供了定义好的边界框数据类型LiDARPoints(位于mmdet3d/core/points/lidar_points.py下)和CameraPoints(位于mmdet3d/core/points/camera_points.py下),分别是激光雷达坐标系下的点云以及相机坐标系下的点云数据类型。一些方法已经内置于数据结构中,可直接调用。

        以LiDARPoints为例,首先需要创建该类的实例:

# 设pts为(N,C)的Tensor,表示N个C维的点(C>=3),其中前三个维度分别是x,y,z坐标
pts = LiDARPoints(pts, points_dim=C)

         然后可以直接调用flip/rotate等数据增广方法以及坐标变换方法。

  • convert_to:坐标变换方法。
    • 输入:
      • dst:目标坐标系,为Coord3DMode.LIDARCoord3DMode.CAM
      • rt_mat:坐标变换矩阵。
    • 若输入dst=Coord3dMode.LIDAR,则输出数据类型为LiDARPoints;若输入dst=Coord3dMode.CAM,则输出数据类型为CameraPoints。

4.边界框的数据类型及其在不同坐标系下的变换

        mmdet3d提供了定义好的边界框数据类型LiDARInstance3DBoxes(位于mmdet3d/core/bbox/structure/lidar_box3d.py下)以及CameraInstance3DBoxes(位于mmdet3d/core/bbox/structure/cam_box3d.py下),分别是激光雷达坐标系下的3D边界框以及相机坐标系下的3D边界框数据类型,许多方法已经内置于数据结构中,可直接调用。

        以LiDARInstance3DBoxes类为例,首先需要创建该类的实例:

# 设bboxes为大小(M,7)的Tensor,其中M为边界框数量,7代表x,y,z坐标,x,y,z尺寸以及朝向角,若有速度等其它参数,需放置在最后
bboxes = LiDARInstance3DBoxes(bboxes)
# 另有三项输入box_dim(每个边界框的参数数量),with_yaw(包含朝向角为True)和origin(含义见前文介绍,指示3D坐标在边界框中的相对位置)
# 可使用默认值box_dim=7, with_yaw=True, origin=(0.5, 0.5, 0),

注意:对于边界框的朝向角,LiDARInstance3DBoxes是绕激光雷达坐标系轴定义的,而CameraInstance3DBoxes是绕相机坐标系轴定义的。

        然后可以直接调用如下方法(没有全部介绍):

  • gravity_center:取边界框几何中心
  • corners:取边界框8个角点
  • bev:取BEV下的边界框参数(x,y坐标、x,y尺寸以及朝向角)
  • in_range_bev:检查中心在BEV范围内的边界框。
    • 输入:BEV范围(x_min,y_min,x_max,y_max);
    • 输出:维bool值向量,若第个元素为True则表示第个边界框中心在该范围内。
  • limit_yaw:限制朝向角范围。
    • 输入:
      • offset:原点在角度区间中的相对位置;
      • period:角度范围的大小。
    • 例如,要将朝向角限制在的范围内,period需取,offset取0.5(表示原点在区间正中)。
    • 该方法的实现实际上是调用了mmdet3d/core/bboxes/structures/utils.py中的limit_period函数,因此在单独限制角度范围时可直接调用limit_period函数(输入依次为角度张量、offset和period)。
  • ​​​​​​​convert_to:坐标系变换方法。
    • 输入:
      • dst:目标坐标系,为Box3dMode.LIDARBox3dMode.CAM(Box3dMode类位于mmdet3d/core/bbox/structure/box_3d_mode.py下);
      • rt_mat:源坐标系到目标坐标系的坐标变换矩阵()。
    • 若输入dst=Box3dMode.LIDAR,则输出数据类型为LiDARInstance3DBoxes;若输入dst=Box3dMode.CAM,则输出数据类型为CameraInstance3DBoxes。
    • 注意:当相机坐标系轴与激光雷达坐标系轴朝向不完全相同时,朝向角的变换是不正确的。

调用上述方法的代码如下(以gravity_center为例):

bboxes_centers = bboxes.gravity_center

有关MMDetection3D/3D目标检测中的边界框和坐标系介绍(含相关函数以及坐标变换的介绍)的更多相关文章

  1. ruby-on-rails - 相关表上的范围为 "WHERE ... LIKE" - 2

    我正在尝试从Postgresql表(table1)中获取数据,该表由另一个相关表(property)的字段(table2)过滤。在纯SQL中,我会这样编写查询:SELECT*FROMtable1JOINtable2USING(table2_id)WHEREtable2.propertyLIKE'query%'这工作正常:scope:my_scope,->(query){includes(:table2).where("table2.property":query)}但我真正需要的是使用LIKE运算符进行过滤,而不是严格相等。然而,这是行不通的:scope:my_scope,->(que

  2. 世界前沿3D开发引擎HOOPS全面讲解——集3D数据读取、3D图形渲染、3D数据发布于一体的全新3D应用开发工具 - 2

    无论您是想搭建桌面端、WEB端或者移动端APP应用,HOOPSPlatform组件都可以为您提供弹性的3D集成架构,同时,由工业领域3D技术专家组成的HOOPS技术团队也能为您提供技术支持服务。如果您的客户期望有一种在多个平台(桌面/WEB/APP,而且某些客户端是“瘦”客户端)快速、方便地将数据接入到3D应用系统的解决方案,并且当访问数据时,在各个平台上的性能和用户体验保持一致,HOOPSPlatform将帮助您完成。利用HOOPSPlatform,您可以开发在任何环境下的3D基础应用架构。HOOPSPlatform可以帮您打造3D创新型产品,HOOPSSDK包含的技术有:快速且准确的CAD

  3. Unity 热更新技术 | (三) Lua语言基本介绍及下载安装 - 2

    ?博客主页:https://xiaoy.blog.csdn.net?本文由呆呆敲代码的小Y原创,首发于CSDN??学习专栏推荐:Unity系统学习专栏?游戏制作专栏推荐:游戏制作?Unity实战100例专栏推荐:Unity实战100例教程?欢迎点赞?收藏⭐留言?如有错误敬请指正!?未来很长,值得我们全力奔赴更美好的生活✨------------------❤️分割线❤️-------------------------

  4. FOHEART H1数据手套驱动Optitrack光学动捕双手运动(Unity3D) - 2

    本教程将在Unity3D中混合Optitrack与数据手套的数据流,在人体运动的基础上,添加双手手指部分的运动。双手手背的角度仍由Optitrack提供,数据手套提供双手手指的角度。 01  客户端软件分别安装MotiveBody与MotionVenus并校准人体与数据手套。MotiveBodyMotionVenus数据手套使用、校准流程参照:https://gitee.com/foheart_1/foheart-h1-data-summary.git02  数据转发打开MotiveBody软件的Streaming,开始向Unity3D广播数据;MotionVenus中设置->选项选择Unit

  5. Unity 3D 制作开关门动画,旋转门制作,推拉门制作,门把手动画制作 - 2

    Unity自动旋转动画1.开门需要门把手先动,门再动2.关门需要门先动,门把手再动3.中途播放过程中不可以再次进行操作觉得太复杂?查看我的文章开关门简易进阶版效果:如果这个门可以直接打开的话,就不需要放置"门把手"如果门把手还有钥匙需要旋转,那就可以把钥匙放在门把手的"门把手",理论上是可以无限套娃的可调整参数有:角度,反向,轴向,速度运行时点击Test进行测试自己写的代码比较垃圾,命名与结构比较拉,高手轻点喷,新手有类似的需求可以拿去做参考上代码usingSystem.Collections;usingSystem.Collections.Generic;usingUnityEngine;u

  6. [Vuforia]二.3D物体识别 - 2

    之前说过10之后的版本没有3dScan了,所以还是9.8的版本或者之前更早的版本。 3d物体扫描需要先下载扫描的APK进行扫面。首先要在手机上装一个扫描程序,扫描现实中的三维物体,然后上传高通官网,在下载成UnityPackage类型让Unity能够使用这个扫描程序可以从高通官网上进行下载,是一个安卓程序。点到Tools往下滑,找到VuforiaObjectScanner下载后解压数据线连接手机,将apk文件拷入手机安装然后刚才解压文件中的Media文件夹打开,两个PDF图打印第一张A4-ObjectScanningTarget.pdf,主要是用来辅助扫描的。好了,接下来就是扫描三维物体。将瓶

  7. ruby-on-rails - 在具有 ActiveRecord 条件的相关模型中按字段排序 - 2

    我正在尝试按Rails相关模型中的字段进行排序。我研究的所有解决方案都没有解决如果相关模型被另一个参数过滤?元素模型classItem相关模型:classPriority我正在使用where子句检索项目:@items=Item.where('company_id=?andapproved=?',@company.id,true).all我需要按相关表格中的“位置”列进行排序。问题在于,在优先级模型中,一个项目可能会被多家公司列出。因此,这些职位取决于他们拥有的company_id。当我显示项目时,它是针对一个公司的,按公司内的职位排序。完成此任务的正确方法是什么?感谢您的帮助。PS-我

  8. python - Ruby 或 Python 的 3d 游戏引擎? - 2

    关闭。这个问题不符合StackOverflowguidelines.它目前不接受答案。要求我们推荐或查找工具、库或最喜欢的场外资源的问题对于StackOverflow来说是偏离主题的,因为它们往往会吸引自以为是的答案和垃圾邮件。相反,describetheproblem以及迄今为止为解决该问题所做的工作。关闭9年前。Improvethisquestion是否有适用于这些的3d游戏引擎?

  9. ruby - 使用指向 ruby​​ 可执行文件的符号链接(symbolic link)时查找相关库 - 2

    假设您有一个可执行文件foo.rb,其库bar.rb的布局如下:/bin/foo.rb/lib/bar.rb在foo.rb的header中放置以下要求以在bar.rb中引入功能:requireFile.dirname(__FILE__)+"../lib/bar.rb"只要对foo.rb的所有调用都是直接的,这就可以正常工作。如果你把$HOME/project和符号链接(symboliclink)foo.rb放入$HOME/usr/bin,然后__FILE__解析为$HOME/usr/bin/foo.rb,因此无法找到bar.rb关于foo.rb的目录名.我意识到像ruby​​gems这

  10. HarmonyOS原子化服务开发相关术语 - 2

    术语中文解释Ability原子化服务帮助用户完成任务的原子化服务,和用户的意图进行关联。Fulfillment服务履行通过图标,卡片,语音等形式呈现用户意图。开发者通过接口的方式,处理用户意图,返回内容。Intent意图用于表达用户想要达成的目标或完成的任务。HUAWEIAssistant智能助手“无微不智”的个人助手,通过不断的学习用户的使用习惯,不断的为用户提供贴心的精准的便捷的个性化服务。AISearch全局搜索用户可快速搜索关键词,与之匹配的原子化服务则会出现在搜索结果中。SmartService智慧服务用户订阅原子化服务,在到达特定触发条件(时间、地点、事件)后,卡片推送至用户智能助

随机推荐