Apollo  6.0
Open source self driving car software
downsampling.h
Go to the documentation of this file.
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  *****************************************************************************/
16 
17 #pragma once
18 
19 #include <memory>
20 #include <utility>
21 #include <vector>
22 
23 #include "cyber/common/log.h"
24 
27 
28 namespace apollo {
29 namespace perception {
30 namespace common {
31 
32 // @brief: a filter of circular.
33 // if point's euclidean dist smaller than neighbour_dist with center_pt and
34 // bigger than or equal radius with last_pt, it will be keep.
35 template <typename PointT>
37  const PointT& center_pt, float radius, float neighbour_dist,
38  typename std::shared_ptr<const base::PointCloud<PointT>> cloud,
39  typename std::shared_ptr<base::PointCloud<PointT>> down_cloud) {
40  for (size_t c = 0; c < cloud->width(); ++c) {
41  for (size_t r = 0; r < cloud->height(); ++r) {
42  PointT tmp_pt;
43  if (cloud->height() > 1) {
44  const PointT* tmp_pt_ptr = cloud->at(c, r);
45  if (tmp_pt_ptr == nullptr) {
46  continue;
47  }
48  tmp_pt = *(tmp_pt_ptr);
49  } else {
50  tmp_pt = cloud->at(c);
51  }
52  if (CalculateEuclidenDist<PointT>(tmp_pt, center_pt) < radius) {
53  if (down_cloud->size() == 0) {
54  down_cloud->push_back(tmp_pt);
55  } else {
56  if (CalculateEuclidenDist<PointT>(
57  tmp_pt, down_cloud->at(down_cloud->size() - 1)) >=
58  neighbour_dist) {
59  down_cloud->push_back(tmp_pt);
60  }
61  }
62  }
63  }
64  }
65 }
66 
67 // @brief: like function DownsamplingCircular. Its center is origin, and have
68 // a new parameter smp_ratio to downsampling.
69 // if smp_ratio=1, func don't downsample, only filtering.
70 // usually set velodyne_model to 64.
71 template <typename PointT>
73  const PointT& center_pt, int smp_ratio, float radius, int velodyne_model,
74  typename std::shared_ptr<const base::PointCloud<PointT>> cloud,
75  typename std::shared_ptr<base::PointCloud<PointT>> down_cloud) {
76  int smp_step = smp_ratio * velodyne_model;
77  down_cloud->resize(cloud->size() / smp_ratio + 1);
78  size_t ii = 0;
79  for (size_t ori_ii = 0; ori_ii < cloud->size(); ori_ii += smp_step) {
80  for (size_t jj = ori_ii;
81  jj < cloud->size() && static_cast<int>(jj - ori_ii) < velodyne_model;
82  ++jj) {
83  const PointT& p = cloud->at(jj);
84  if (std::isnan(p.x) || std::isnan(p.y) || std::isnan(p.z)) {
85  continue;
86  }
87  float r = CalculateEuclidenDist2DXY<PointT>(center_pt, p);
88  if (r > radius) {
89  continue;
90  }
91  down_cloud->at(jj).x = cloud->at(jj).x;
92  down_cloud->at(jj).y = cloud->at(jj).y;
93  down_cloud->at(jj).z = cloud->at(jj).z;
94  ++ii;
95  }
96  }
97  down_cloud->resize(ii);
98 }
99 
100 // @brief: like function DownsamplingCircularOrgAll, this function is
101 // downsampling 2d PointCloud alternately.
102 // usually set velodyne_model to 64.
103 template <typename PointT>
105  const PointT& center_pt, int org_num, int smp_ratio, float radius,
106  int velodyne_model,
107  const typename std::shared_ptr<const base::PointCloud<PointT>> cloud,
108  typename std::shared_ptr<base::PointCloud<PointT>> down_cloud,
109  std::vector<std::pair<int, int>>* all_org_idx_ptr) {
110  int smp_height = static_cast<int>(cloud->height()) / smp_ratio;
111  int smp_width = org_num;
112  if (smp_width < 1 || smp_width >= velodyne_model) {
113  AERROR << "org_num error!";
114  return;
115  }
116  size_t ii = 0;
117  down_cloud->resize(smp_height * smp_width);
118  all_org_idx_ptr->resize(smp_height * smp_width);
119  for (int hh = 0; hh < smp_height; ++hh) {
120  for (int ww = 0; ww < smp_width; ++ww) {
121  int ori_hh = hh * smp_ratio;
122  const PointT* p_ptr = cloud->at(ww, ori_hh);
123  if (p_ptr == nullptr) {
124  continue;
125  }
126  const PointT& p = *(p_ptr);
127  if (std::isnan(p.x) || std::isnan(p.y) || std::isnan(p.z)) {
128  continue;
129  }
130  float r = CalculateEuclidenDist2DXY<PointT>(center_pt, p);
131  if (r > radius) {
132  continue;
133  } else {
134  down_cloud->at(ii) = p;
135  all_org_idx_ptr->at(ii).first = hh;
136  all_org_idx_ptr->at(ii).second = ww;
137  ++ii;
138  }
139  }
140  }
141  down_cloud->resize(ii);
142  all_org_idx_ptr->resize(ii);
143 }
144 
145 // @brief: This function is downsampling 2d PointCloud alternately.
146 // usually set velodyne_model to 64.
147 template <typename PointT>
149  int org_num, int smp_ratio, float front_range, float side_range,
150  int velodyne_model,
151  typename std::shared_ptr<const base::PointCloud<PointT>> cloud,
152  typename std::shared_ptr<base::PointCloud<PointT>> down_cloud,
153  std::vector<std::pair<int, int>>* all_org_idx_ptr) {
154  int smp_height = static_cast<int>(cloud->height()) / smp_ratio;
155  int smp_width = org_num;
156  if (smp_width < 1 || smp_width >= velodyne_model) {
157  AERROR << "org_num error!";
158  return;
159  }
160  size_t ii = 0;
161  down_cloud->resize(smp_height * smp_width);
162  all_org_idx_ptr->resize(smp_height * smp_width);
163  for (int hh = 0; hh < smp_height; ++hh) {
164  for (int ww = 0; ww < smp_width; ++ww) {
165  int ori_hh = hh * smp_ratio;
166  const PointT* p_ptr = cloud->at(ww, ori_hh);
167  if (p_ptr == nullptr) {
168  continue;
169  }
170  const PointT& p = *(p_ptr);
171  if (std::isnan(p.x) || std::isnan((p.y) || std::isnan(p.z))) {
172  continue;
173  }
174  if (fabs(p.x) > front_range || fabs(p.y) > side_range) {
175  continue;
176  } else {
177  down_cloud->at(ii) = p;
178  all_org_idx_ptr->at(ii).first = hh;
179  all_org_idx_ptr->at(ii).second = ww;
180  ++ii;
181  }
182  }
183  }
184  down_cloud->resize(ii);
185  all_org_idx_ptr->resize(ii);
186 }
187 
188 // @brief: a filter of neighbour rectangle.
189 // usually set velodyne_model to 64.
190 template <typename PointT>
192  float front_range, float side_range, double max_nei, int velo_model,
193  typename std::shared_ptr<const base::PointCloud<PointT>> cloud,
194  typename std::shared_ptr<base::PointCloud<PointT>> down_cloud) {
195  if (static_cast<int>(cloud->width()) != velo_model) {
196  AERROR << "cloud->width (" << cloud->width() << ") does not match "
197  << "velo_model (" << velo_model << ")";
198  return;
199  }
200  down_cloud->resize(cloud->size());
201  size_t pt_num = 0;
202  for (size_t ww = 0; ww < cloud->width(); ++ww) {
203  PointT nei_pt;
204  nei_pt.x = 0;
205  nei_pt.y = 0;
206  nei_pt.z = 0;
207  for (size_t hh = 0; hh < cloud->height(); ++hh) {
208  const PointT* p_ptr = cloud->at(ww, hh);
209  if (p_ptr == nullptr) {
210  continue;
211  }
212  const PointT& p = *(p_ptr);
213  if (std::isnan(p.x) || std::isnan(p.y) || std::isnan(p.z)) {
214  continue;
215  }
216  if (fabs(p.x) > front_range || fabs(p.y) > side_range) {
217  continue;
218  }
219  if (fabs(p.x - nei_pt.x) > max_nei || fabs(p.y - nei_pt.y) > max_nei) {
220  nei_pt = p;
221  down_cloud->at(pt_num++) = p;
222  }
223  }
224  }
225  down_cloud->resize(pt_num);
226 }
227 
228 } // namespace common
229 } // namespace perception
230 } // namespace apollo
void DownsamplingCircularOrgPartial(const PointT &center_pt, int org_num, int smp_ratio, float radius, int velodyne_model, const typename std::shared_ptr< const base::PointCloud< PointT >> cloud, typename std::shared_ptr< base::PointCloud< PointT >> down_cloud, std::vector< std::pair< int, int >> *all_org_idx_ptr)
Definition: downsampling.h:104
PlanningContext is the runtime context in planning. It is persistent across multiple frames...
Definition: atomic_hash_map.h:25
void DownsamplingCircular(const PointT &center_pt, float radius, float neighbour_dist, typename std::shared_ptr< const base::PointCloud< PointT >> cloud, typename std::shared_ptr< base::PointCloud< PointT >> down_cloud)
Definition: downsampling.h:36
Definition: point_cloud.h:37
void DownsamplingRectangleOrgPartial(int org_num, int smp_ratio, float front_range, float side_range, int velodyne_model, typename std::shared_ptr< const base::PointCloud< PointT >> cloud, typename std::shared_ptr< base::PointCloud< PointT >> down_cloud, std::vector< std::pair< int, int >> *all_org_idx_ptr)
Definition: downsampling.h:148
void DownsamplingCircularOrgAll(const PointT &center_pt, int smp_ratio, float radius, int velodyne_model, typename std::shared_ptr< const base::PointCloud< PointT >> cloud, typename std::shared_ptr< base::PointCloud< PointT >> down_cloud)
Definition: downsampling.h:72
void DownsamplingRectangleNeighbour(float front_range, float side_range, double max_nei, int velo_model, typename std::shared_ptr< const base::PointCloud< PointT >> cloud, typename std::shared_ptr< base::PointCloud< PointT >> down_cloud)
Definition: downsampling.h:191
#define AERROR
Definition: log.h:44