如何获取Open3D OrientedBoundingBox指定左下点的位姿
Open3D OrientedBoundingBox 目标点提取问题及修正
需要从Open3D的OrientedBoundingBox中提取满足x轴最靠近原点,其次z轴最靠近原点,且y轴距离原点最远的点,并获取该点对应的位姿(平移、旋转)。但由于包围盒旋转状态不固定,原本预期目标点是索引2的点,实际通过GetBoxPoints()结合法向量计算后,发现索引5的点才符合要求,原代码逻辑存在问题。
原实现代码
open3d::geometry::OrientedBoundingBox bbox_ws; std::vector<Eigen::Vector3d> points = bbox_ws.GetBoxPoints(); Eigen::Vector3d P2 = points[2]; for (const auto& point : points) { if (point.x() < P2.x() && point.y() > P2.y() && point.z() < P2.z()) { P2 = point; } } Eigen::Vector3d x_axis = points[7] - P2; // P2P7 Eigen::Vector3d y_axis = points[0] - P2; // P2P0 Eigen::Vector3d z_axis = points[5] - P2; // P2P5 x_axis.normalize(); y_axis.normalize(); z_axis.normalize(); Eigen::Matrix3d rotation_matrix; rotation_matrix.col(0) = x_axis; rotation_matrix.col(1) = y_axis; rotation_matrix.col(2) = z_axis;
实测点坐标数据
point number 0 Has values: 1.20885 0.52103 0.172856 point number 1 Has values: 0.939225 -0.536148 0.205281 point number 2 Has values: 1.21036 0.52761 0.399916 point number 3 Has values: 0.810032 0.622739 0.17256 point number 4 Has values: 0.541912 -0.42786 0.432043 point number 5 Has values: 0.811541 0.629318 0.399619 point number 6 Has values: 0.540403 -0.434439 0.204984 point number 7 Has values: 0.940734 -0.529568 0.43234 ## 其他测试数据集: 0.945674 -0.514864 0.407497 1.18082 0.423109 0.415139 0.945228 -0.513155 0.211485 0.546889 -0.414905 0.409276 0.781587 0.524777 0.220907 0.546443 -0.413196 0.213265 0.782034 0.523068 0.416919 1.18037 0.424818 0.219128 1.21301 0.515485 0.172203 0.945833 -0.534461 0.226136 1.21074 0.527857 0.401783 0.811611 0.617145 0.162747 0.542156 -0.42043 0.446261 0.809336 0.629517 0.392328 0.54443 -0.432802 0.21668 0.943558 -0.52209 0.455717
问题分析与修正
核心问题
- 筛选逻辑缺陷:原代码基于初始
points[2]进行逐点比较,无法保证找到全局最优的目标点——即同时满足x最小、z最小、y最大的点,必须按优先级排序筛选。 - 坐标轴计算错误:依赖固定索引的点推导坐标轴方向,而包围盒旋转后,顶点索引对应的相对位置会变化,不能直接复用固定索引的相邻点。
修正后的代码
open3d::geometry::OrientedBoundingBox bbox_ws; std::vector<Eigen::Vector3d> points = bbox_ws.GetBoxPoints(); // 按优先级筛选目标点:x最小 → z最小 → y最大 Eigen::Vector3d target_point = points[0]; for (const auto& p : points) { if (p.x() < target_point.x()) { target_point = p; } else if (p.x() == target_point.x()) { if (p.z() < target_point.z()) { target_point = p; } else if (p.z() == target_point.z()) { if (p.y() > target_point.y()) { target_point = p; } } } } // 直接复用包围盒的旋转矩阵(全局坐标轴方向一致) Eigen::Matrix3d rotation_matrix = bbox_ws.R_; // 平移向量即为目标点的坐标 Eigen::Vector3d translation = target_point;
补充说明
- Open3D的
OrientedBoundingBox的GetBoxPoints()返回的顶点顺序仅在无旋转时符合直观逻辑,旋转后索引对应的相对位置会改变,因此不能依赖固定索引计算坐标轴。 - 若需基于目标点相邻点推导坐标轴,需先找到目标点在
points中的索引,再通过立方体拓扑关系筛选相邻点,但直接复用包围盒自带的旋转矩阵R_更可靠。
内容的提问来源于stack exchange,提问作者bhomaidan90
相关产品推荐
相关产品推荐

