Apollo  v5.5.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() && (jj - ori_ii) < velodyne_model; ++jj) {
82  const PointT& p = cloud->at(jj);
83  if (std::isnan(p.x) || std::isnan(p.y) || std::isnan(p.z)) {
84  continue;
85  }
86  float r = CalculateEuclidenDist2DXY<PointT>(center_pt, p);
87  if (r > radius) {
88  continue;
89  }
90  down_cloud->at(jj).x = cloud->at(jj).x;
91  down_cloud->at(jj).y = cloud->at(jj).y;
92  down_cloud->at(jj).z = cloud->at(jj).z;
93  ++ii;
94  }
95  }
96  down_cloud->resize(ii);
97 }
98 
99 // @brief: like function DownsamplingCircularOrgAll, this function is
100 // downsampling 2d PointCloud alternately.
101 // usually set velodyne_model to 64.
102 template <typename PointT>
104  const PointT& center_pt, int org_num, int smp_ratio, float radius,
105  int velodyne_model,
106  const typename std::shared_ptr<const base::PointCloud<PointT>> cloud,
107  typename std::shared_ptr<base::PointCloud<PointT>> down_cloud,
108  std::vector<std::pair<int, int>>* all_org_idx_ptr) {
109  int smp_height = static_cast<int>(cloud->height()) / smp_ratio;
110  int smp_width = org_num;
111  if (smp_width < 1 || smp_width >= velodyne_model) {
112  AERROR << "org_num error!";
113  return;
114  }
115  size_t ii = 0;
116  down_cloud->resize(smp_height * smp_width);
117  all_org_idx_ptr->resize(smp_height * smp_width);
118  for (size_t hh = 0; hh < smp_height; ++hh) {
119  for (size_t ww = 0; ww < smp_width; ++ww) {
120  int ori_hh = static_cast<int>(hh) * smp_ratio;
121  const PointT* p_ptr = cloud->at(ww, ori_hh);
122  if (p_ptr == nullptr) {
123  continue;
124  }
125  const PointT& p = *(p_ptr);
126  if (std::isnan(p.x) || std::isnan(p.y) || std::isnan(p.z)) {
127  continue;
128  }
129  float r = CalculateEuclidenDist2DXY<PointT>(center_pt, p);
130  if (r > radius) {
131  continue;
132  } else {
133  down_cloud->at(ii) = p;
134  all_org_idx_ptr->at(ii).first = static_cast<int>(hh);
135  all_org_idx_ptr->at(ii).second = static_cast<int>(ww);
136  ++ii;
137  }
138  }
139  }
140  down_cloud->resize(ii);
141  all_org_idx_ptr->resize(ii);
142 }
143 
144 // @brief: This function is downsampling 2d PointCloud alternately.
145 // usually set velodyne_model to 64.
146 template <typename PointT>
148  int org_num, int smp_ratio, float front_range, float side_range,
149  int velodyne_model,
150  typename std::shared_ptr<const base::PointCloud<PointT>> cloud,
151  typename std::shared_ptr<base::PointCloud<PointT>> down_cloud,
152  std::vector<std::pair<int, int>>* all_org_idx_ptr) {
153  int smp_height = static_cast<int>(cloud->height()) / smp_ratio;
154  int smp_width = org_num;
155  if (smp_width < 1 || smp_width >= velodyne_model) {
156  AERROR << "org_num error!";
157  return;
158  }
159  size_t ii = 0;
160  down_cloud->resize(smp_height * smp_width);
161  all_org_idx_ptr->resize(smp_height * smp_width);
162  for (size_t hh = 0; hh < smp_height; ++hh) {
163  for (size_t ww = 0; ww < smp_width; ++ww) {
164  int ori_hh = static_cast<int>(hh) * smp_ratio;
165  const PointT* p_ptr = cloud->at(ww, ori_hh);
166  if (p_ptr == nullptr) {
167  continue;
168  }
169  const PointT& p = *(p_ptr);
170  if (std::isnan(p.x) || std::isnan((p.y) || std::isnan(p.z))) {
171  continue;
172  }
173  if (fabs(p.x) > front_range || fabs(p.y) > side_range) {
174  continue;
175  } else {
176  down_cloud->at(ii) = p;
177  all_org_idx_ptr->at(ii).first = static_cast<int>(hh);
178  all_org_idx_ptr->at(ii).second = static_cast<int>(ww);
179  ++ii;
180  }
181  }
182  }
183  down_cloud->resize(ii);
184  all_org_idx_ptr->resize(ii);
185 }
186 
187 // @brief: a filter of neighbour rectangle.
188 // usually set velodyne_model to 64.
189 template <typename PointT>
191  float front_range, float side_range, double max_nei, int velo_model,
192  typename std::shared_ptr<const base::PointCloud<PointT>> cloud,
193  typename std::shared_ptr<base::PointCloud<PointT>> down_cloud) {
194  if (cloud->width() != velo_model) {
195  AERROR << "cloud->width (" << cloud->width() << ") does not match "
196  << "velo_model (" << velo_model << ")";
197  return;
198  }
199  down_cloud->resize(cloud->size());
200  size_t pt_num = 0;
201  for (int ww = 0; ww < cloud->width(); ++ww) {
202  PointT nei_pt;
203  nei_pt.x = 0;
204  nei_pt.y = 0;
205  nei_pt.z = 0;
206  for (int hh = 0; hh < cloud->height(); ++hh) {
207  const PointT* p_ptr = cloud->at(ww, hh);
208  if (p_ptr == nullptr) {
209  continue;
210  }
211  const PointT& p = *(p_ptr);
212  if (std::isnan(p.x) || std::isnan(p.y) || std::isnan(p.z)) {
213  continue;
214  }
215  if (fabs(p.x) > front_range || fabs(p.y) > side_range) {
216  continue;
217  }
218  if (fabs(p.x - nei_pt.x) > max_nei || fabs(p.y - nei_pt.y) > max_nei) {
219  nei_pt = p;
220  down_cloud->at(pt_num++) = p;
221  }
222  }
223  }
224  down_cloud->resize(pt_num);
225 }
226 
227 } // namespace common
228 } // namespace perception
229 } // 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:103
Definition: blob.h:72
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:33
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:147
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:190