Skip to content

Commit cb50529

Browse files
authored
Fix issue of mesh oriented bbox computation (#31)
* fix[assimp_mesh_loader]: fix obb computation in assimp mesh loader Signed-off-by: zz990099 <771647586@qq.com> * improve[simple_tests]: Add axies drawing in draw3DBoundingBox function Signed-off-by: zz990099 <771647586@qq.com> * fix precommit Signed-off-by: zz990099 <771647586@qq.com> --------- Signed-off-by: zz990099 <771647586@qq.com>
1 parent 052b4ae commit cb50529

2 files changed

Lines changed: 59 additions & 16 deletions

File tree

detection_6d_foundationpose/src/mesh_loader/assimp_mesh_loader.cpp

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -88,28 +88,33 @@ static void ComputeOBB(const aiMesh *mesh,
8888

8989
// 特征分解
9090
Eigen::SelfAdjointEigenSolver<Eigen::Matrix3f> solver(cov);
91-
Eigen::Matrix3f rotation = solver.eigenvectors();
92-
Eigen::Vector3f extents = solver.eigenvalues().cwiseSqrt();
93-
// 生成变换矩阵
94-
Eigen::Matrix4f transform = Eigen::Matrix4f::Identity();
95-
transform.block<3, 3>(0, 0) = rotation;
96-
transform.block<3, 1>(0, 3) = mean;
91+
Eigen::Matrix3f rotation = solver.eigenvectors();
92+
Eigen::Vector3f extents = solver.eigenvalues().cwiseSqrt();
9793

94+
// 将顶点变换到旋转后的坐标系
9895
Eigen::MatrixXf transformed(vertices.size(), 3);
9996
for (int i = 0; i < vertices.size(); ++i)
10097
{
101-
Eigen::Vector3f proj = rotation.transpose() * vertices[i];
102-
transformed(i, 0) = proj(0);
103-
transformed(i, 1) = proj(1);
104-
transformed(i, 2) = proj(2);
98+
Eigen::Vector3f proj = rotation.transpose() * (vertices[i] - mean);
99+
transformed(i, 0) = proj(0);
100+
transformed(i, 1) = proj(1);
101+
transformed(i, 2) = proj(2);
105102
}
106103

104+
// 计算边界框
107105
Eigen::Vector3f minBound = transformed.colwise().minCoeff();
108106
Eigen::Vector3f maxBound = transformed.colwise().maxCoeff();
109-
110107
Eigen::Vector3f dimension = maxBound - minBound;
111108

112-
out_orient_bbox = transform;
109+
// 计算OBB中心(在旋转后的坐标系中)
110+
Eigen::Vector3f center = (minBound + maxBound) / 2.0f;
111+
112+
// 构建变换矩阵:从OBB坐标系到模型坐标系
113+
Eigen::Matrix4f to_origin = Eigen::Matrix4f::Identity();
114+
to_origin.block<3, 3>(0, 0) = rotation;
115+
to_origin.block<3, 1>(0, 3) = rotation * center + mean;
116+
117+
out_orient_bbox = to_origin;
113118
out_dimension = dimension;
114119
}
115120

simple_tests/include/tests/help_func.hpp

Lines changed: 42 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,10 @@ inline void draw3DBoundingBox(const Eigen::Matrix3f &intrinsic,
6464
float h = dimension(2) / 2;
6565

6666
// 目标的八个顶点在物体坐标系中的位置
67-
Eigen::Vector3f points[8] = {{-l, -w, h}, {l, -w, h}, {l, w, h}, {-l, w, h},
68-
{-l, -w, -h}, {l, -w, -h}, {l, w, -h}, {-l, w, -h}};
67+
Eigen::Vector3f points[8] = {
68+
{-l, -w, h}, {l, -w, h}, {l, w, h}, {-l, w, h},
69+
{-l, -w, -h}, {l, -w, -h}, {l, w, -h}, {-l, w, -h}
70+
};
6971

7072
// 变换到世界坐标系
7173
Eigen::Vector4f transformed_points[8];
@@ -99,10 +101,46 @@ inline void draw3DBoundingBox(const Eigen::Matrix3f &intrinsic,
99101
{
100102
if (edge.first < image_points.size() && edge.second < image_points.size())
101103
{
102-
cv::line(image, image_points[edge.first], image_points[edge.second], cv::Scalar(0, 255, 0),
103-
2); // 绿色边框
104+
cv::line(image, image_points[edge.first], image_points[edge.second], cv::Scalar(0, 255, 0), 2); // 绿色边框
104105
}
105106
}
107+
108+
// 计算物体中心在世界坐标系中的位置
109+
Eigen::Vector4f center_obj(0, 0, 0, 1); // 物体坐标系中心原点
110+
Eigen::Vector4f center_world = pose * center_obj;
111+
112+
// 定义三个轴的终点
113+
float axis_length = (dimension(0) + dimension(1) + dimension(2)) / 6;
114+
Eigen::Vector4f x_end_obj(axis_length, 0, 0, 1);
115+
Eigen::Vector4f y_end_obj(0, axis_length, 0, 1);
116+
Eigen::Vector4f z_end_obj(0, 0, axis_length, 1);
117+
118+
Eigen::Vector4f x_end_world = pose * x_end_obj;
119+
Eigen::Vector4f y_end_world = pose * y_end_obj;
120+
Eigen::Vector4f z_end_world = pose * z_end_obj;
121+
122+
std::vector<Eigen::Vector4f> axis_end_points = {x_end_world, y_end_world, z_end_world};
123+
std::vector<cv::Scalar> axis_colors = {
124+
cv::Scalar(0, 0, 255), // X轴: 红色
125+
cv::Scalar(0, 255, 0), // Y轴: 绿色
126+
cv::Scalar(255, 0, 0) // Z轴: 蓝色
127+
};
128+
129+
float cx = center_world(0) / center_world(2);
130+
float cy = center_world(1) / center_world(2);
131+
float cu = intrinsic(0, 0) * cx + intrinsic(0, 2);
132+
float cv = intrinsic(1, 1) * cy + intrinsic(1, 2);
133+
cv::Point center_pt(cu, cv);
134+
135+
for (int k = 0; k < 3; ++k)
136+
{
137+
float ex = axis_end_points[k](0) / axis_end_points[k](2);
138+
float ey = axis_end_points[k](1) / axis_end_points[k](2);
139+
float eu = intrinsic(0, 0) * ex + intrinsic(0, 2);
140+
float ev = intrinsic(1, 1) * ey + intrinsic(1, 2);
141+
142+
cv::line(image, center_pt, cv::Point(eu, ev), axis_colors[k], 3);
143+
}
106144
}
107145

108146
inline Eigen::Matrix3f ReadCamK(const std::string &cam_K_path)

0 commit comments

Comments
 (0)