Apollo 11.0
自动驾驶开放平台
object_split.cc
浏览该文件的文档.
1/******************************************************************************
2 * Copyright 2024 The Apollo Authors. All Rights Reserved.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *****************************************************************************/
16
18
19namespace apollo {
20namespace perception {
21namespace lidar {
22
23void SplitObject(const base::ObjectPtr& obj, std::vector<base::ObjectPtr>* split_objs, float split_distance) {
24 split_objs->clear();
25 const auto max_edge = std::max(obj->size(0), obj->size(1));
26 if (max_edge < split_distance) {
27 split_objs->push_back(obj);
28 return;
29 }
30 const auto& cloud = obj->lidar_supplement.cloud;
31 const auto& cloud_world = obj->lidar_supplement.cloud_world;
32 const auto& point_ids = obj->lidar_supplement.point_ids;
33 Eigen::Vector3f params;
34 if (!LineFit2D(obj->lidar_supplement.cloud, &params)) {
35 split_objs->push_back(obj);
36 return;
37 }
38
39 Eigen::Vector2f offset(cloud.at(0).x, cloud.at(0).y);
40 Eigen::Vector2f min_xy(std::numeric_limits<float>::max(), std::numeric_limits<float>::max());
41 Eigen::Vector2f max_xy(-std::numeric_limits<float>::max(), -std::numeric_limits<float>::max());
42 Eigen::Vector2f odirection = params.head(2);
43 Eigen::Vector2f direction(odirection(1), -odirection(0));
44 std::vector<Eigen::Vector2f> transfrom_cloud;
45 transfrom_cloud.resize(cloud.size());
46 for (size_t i = 0; i < cloud.size(); ++i) {
47 const auto& pt = cloud.at(i);
48 auto& vec_pt = transfrom_cloud.at(i);
49 Eigen::Vector2f vec(pt.x, pt.y);
50 vec -= offset;
51 vec_pt(0) = direction.dot(vec);
52 vec_pt(1) = odirection.dot(vec);
53 min_xy(0) = std::min(min_xy(0), vec_pt(0));
54 min_xy(1) = std::min(min_xy(1), vec_pt(1));
55 max_xy(0) = std::max(max_xy(0), vec_pt(0));
56 max_xy(1) = std::max(max_xy(1), vec_pt(1));
57 }
58
59 const auto size = max_xy - min_xy;
60 size_t segments = size(0) / split_distance + 1;
61 base::ObjectPool::Instance().BatchGet(segments, split_objs);
62 base::Object tmp_obj = *obj;
63 tmp_obj.polygon.clear();
64 tmp_obj.lidar_supplement.cloud.clear();
66 tmp_obj.lidar_supplement.point_ids.clear();
67 tmp_obj.confidence = obj->confidence;
68 for (auto& obj : *split_objs) {
69 *obj = tmp_obj;
70 }
71
72 for (size_t i = 0; i < transfrom_cloud.size(); ++i) {
73 auto& vec_pt = transfrom_cloud.at(i);
74 const int section = (vec_pt(0) - min_xy(0)) / split_distance;
75 auto& obj = split_objs->at(section);
76 obj->lidar_supplement.cloud.push_back(cloud.at(i));
77 obj->lidar_supplement.cloud_world.push_back(cloud_world.at(i));
78 obj->lidar_supplement.point_ids.push_back(point_ids.at(i));
79 }
80
81 size_t valid = 0;
82 for (auto& obj : *split_objs) {
83 if (obj->lidar_supplement.cloud.size() > 3) {
84 obj->lidar_supplement.num_points_in_roi = obj->lidar_supplement.point_ids.size();
85 split_objs->at(valid++) = obj;
86 }
87 }
88 split_objs->resize(valid);
89}
90
91bool LineFit2D(const base::PointFCloud& cloud, Eigen::Vector3f* params) {
92 if (cloud.size() < 2) {
93 return false;
94 }
95 Eigen::Vector2f mean(0, 0);
96 Eigen::Matrix2f covariance = Eigen::Matrix2f::Zero();
97 for (size_t i = 0; i < cloud.size(); ++i) {
98 const auto& pt = cloud.at(i);
99 mean(0) += pt.x;
100 mean(1) += pt.y;
101 }
102 mean /= cloud.size();
103 for (size_t i = 0; i < cloud.size(); ++i) {
104 const auto& pt = cloud.at(i);
105 float dx = pt.x - mean(0);
106 float dy = pt.y - mean(1);
107 covariance(0, 0) += dx * dx;
108 covariance(1, 1) += dy * dy;
109 covariance(0, 1) += dx * dy;
110 }
111 covariance(1, 0) = covariance(0, 1);
112 covariance /= cloud.size();
113 Eigen::SelfAdjointEigenSolver<Eigen::Matrix2f> solver(covariance);
114 if (solver.info() != Eigen::Success) {
115 return false;
116 }
117 Eigen::Vector2f values = solver.eigenvalues();
118 Eigen::Vector2f normal
119 = std::abs(values(0)) < std::abs(values(1)) ? solver.eigenvectors().col(0) : solver.eigenvectors().col(1);
120 normal.normalize();
121 params->head(2) = normal;
122 (*params)[2] = -normal.dot(mean);
123 return true;
124}
125
126} // namespace lidar
127} // namespace perception
128} // namespace apollo
const PointT * at(size_t col, size_t row) const
Definition point_cloud.h:63
std::shared_ptr< Object > ObjectPtr
Definition object.h:127
void SplitObject(const base::ObjectPtr &obj, std::vector< base::ObjectPtr > *split_objs, float split_distance)
split object
bool LineFit2D(const base::PointFCloud &cloud, Eigen::Vector3f *params)
line fitting according to max variance direction of pointcloud
class register implement
Definition arena_queue.h:37
base::AttributePointCloud< PointD > cloud_world
base::AttributePointCloud< PointF > cloud
PointCloud< PointD > polygon
Definition object.h:43
LidarObjectSupplement lidar_supplement
Definition object.h:115