Apollo 10.0
自动驾驶开放平台
point_cloud_util.cc
浏览该文件的文档.
1/******************************************************************************
2 * Copyright 2018 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 *****************************************************************************/
17
18#include <algorithm>
19#include <limits>
20#include "Eigen/Dense"
21#include "opencv2/opencv.hpp"
22
23#include "cyber/common/log.h"
24
25namespace apollo {
26namespace perception {
27namespace base {
28
30 base::PointFCloudPtr out_cloud_ptr,
31 int downsample_factor) {
32 if (downsample_factor <= 0) {
33 return false;
34 }
35 for (size_t i = 0; i < cloud_ptr->size(); ++i) {
36 int32_t beam_id = cloud_ptr->points_beam_id(i);
37 if (beam_id % downsample_factor == 0) {
38 base::PointF point = cloud_ptr->at(i);
39 double timestamp = cloud_ptr->points_timestamp(i);
40 float height = cloud_ptr->points_height(i);
41 uint8_t label = cloud_ptr->points_label(i);
42 out_cloud_ptr->push_back(point, timestamp, height, beam_id, label);
43 }
44 }
45 return true;
46}
47
48void GetPointCloudCentroid(const PointFCloud& cloud, PointF* centroid) {
49 for (size_t i = 0; i < cloud.size(); ++i) {
50 centroid->x += cloud[i].x;
51 centroid->y += cloud[i].y;
52 centroid->z += cloud[i].z;
53 }
54 centroid->x /= static_cast<float>(cloud.size());
55 centroid->y /= static_cast<float>(cloud.size());
56 centroid->z /= static_cast<float>(cloud.size());
57}
58
60 // Demean by using centroid.
61 PointF centroid;
62 GetPointCloudCentroid(*pc, &centroid);
63 for (size_t i = 0; i < pc->size(); ++i) {
64 (*pc)[i].x -= centroid.x;
65 (*pc)[i].y -= centroid.y;
66 (*pc)[i].z -= centroid.z;
67 }
68}
69
70double OrientCloud(const PointFCloud& pc, PointFCloud* pc_out, bool demean) {
71 // Approach#1:
72 // Find car dominant direction on XY plane.
73 /*Eigen::VectorXf coeff;
74 find_dominant_direction_xy(pc, coeff);
75 // This theta has ambiguity. To calculate the true heading,
76 // we need to consider both obstacle's velocity direction and
77 // robot's current velocity direction.
78 double theta = atan2(coeff[4], coeff[3]);*/
79 // Approach#2:
80 // Use Minimum Area Bounding Box
81 BoundingCube bbox;
82 GetPointCloudMinareaBbox(pc, &bbox);
83 float theta = static_cast<float>(bbox.yaw);
84 Eigen::Affine3f transform = Eigen::Affine3f::Identity();
85 transform.rotate(Eigen::AngleAxisf(-theta, Eigen::Vector3f(0, 0, 1)));
86 pc.TransformPointCloud(transform, pc_out, true);
87 if (demean) {
88 CloudDemean(pc_out);
89 }
90 return theta;
91}
92
94 const int& min_num_points, const bool& verbose) {
95 if (pc.size() <= static_cast<size_t>(min_num_points)) {
96 return false;
97 }
98 std::vector<cv::Point2f> pts;
99 float min_z = std::numeric_limits<float>::max();
100 float max_z = -std::numeric_limits<float>::max();
101 for (size_t i = 0; i < pc.size(); ++i) {
102 pts.push_back(cv::Point2f(pc[i].x, pc[i].y));
103 min_z = std::min(min_z, pc[i].z);
104 max_z = std::max(max_z, pc[i].z);
105 }
106 // compute MinAreaRect
107 cv::RotatedRect mar = cv::minAreaRect(pts);
108 // adjust angle
109 if (mar.size.width < mar.size.height) {
110 mar.angle -= 90;
111 float tmp = mar.size.width;
112 mar.size.width = mar.size.height;
113 mar.size.height = tmp;
114 }
115 if (verbose) {
116 AINFO << "center = " << mar.center.x << " " << mar.center.y << std::endl;
117 AINFO << "size = " << mar.size.height << " " << mar.size.width << std::endl;
118 AINFO << "yaw = " << mar.angle << std::endl;
119 AINFO << "height = " << max_z - min_z << std::endl;
120 }
121 box->x = mar.center.x;
122 box->y = mar.center.y;
123 box->z = static_cast<float>((min_z + max_z) / 2.0);
124 box->length = mar.size.width;
125 box->width = mar.size.height;
126 box->height = max_z - min_z;
127 box->yaw = static_cast<float>((M_PI * (mar.angle + 180)) / 180);
128 return true;
129}
130
131} // namespace base
132} // namespace perception
133} // namespace apollo
void TransformPointCloud(bool check_nan=false)
#define AINFO
Definition log.h:42
bool DownSamplePointCloudBeams(base::PointFCloudPtr cloud_ptr, base::PointFCloudPtr out_cloud_ptr, int downsample_factor)
void CloudDemean(PointFCloud *pc)
void GetPointCloudCentroid(const PointFCloud &cloud, PointF *centroid)
std::shared_ptr< PointFCloud > PointFCloudPtr
bool GetPointCloudMinareaBbox(const PointFCloud &pc, BoundingCube *box, const int &min_num_points, const bool &verbose)
double OrientCloud(const PointFCloud &pc, PointFCloud *pc_out, bool demean)
class register implement
Definition arena_queue.h:37