Apollo 11.0
自动驾驶开放平台
downsampling.h
浏览该文件的文档.
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
28namespace apollo {
29namespace perception {
30namespace algorithm {
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.
35template <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.
71template <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.
103template <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.
147template <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.
190template <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 algorithm
229} // namespace perception
230} // namespace apollo
#define AERROR
Definition log.h:44
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)
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)
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)
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)
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)
class register implement
Definition arena_queue.h:37