@@ -135,8 +135,7 @@ void RadiusSearch2dFilter::filter(
135
135
const int min_points_threshold = std::min (
136
136
std::max (static_cast <int >(min_points_and_distance_ratio_ / distance + 0 .5f ), min_points_),
137
137
max_points_);
138
- const int points_num =
139
- kd_tree_->radiusSearch (i, search_radius_, k_indices, k_distances, min_points_threshold);
138
+ const int points_num = kd_tree_->nearestKSearch (i, min_points_threshold, k_indices, k_distances);
140
139
141
140
if (min_points_threshold <= points_num) {
142
141
output.points .push_back (xyz_cloud.points .at (i));
@@ -150,43 +149,62 @@ void RadiusSearch2dFilter::filter(
150
149
const PclPointCloud & high_conf_input, const PclPointCloud & low_conf_input, const Pose & pose,
151
150
PclPointCloud & output, PclPointCloud & outlier)
152
151
{
153
- const auto & high_conf_xyz_cloud = high_conf_input;
154
- const auto & low_conf_xyz_cloud = low_conf_input;
155
152
// check the limit points number
156
- if (low_conf_xyz_cloud .points .size () > max_filter_points_nb_) {
153
+ if (low_conf_input .points .size () > max_filter_points_nb_) {
157
154
RCLCPP_WARN (
158
155
rclcpp::get_logger (" OccupancyGridMapOutlierFilterComponent" ),
159
156
" Skip outlier filter since too much low_confidence pointcloud!" );
160
157
return ;
161
158
}
162
159
163
- pcl::PointCloud<pcl::PointXY>::Ptr xy_cloud (new pcl::PointCloud<pcl::PointXY>);
164
- xy_cloud ->points .resize (low_conf_xyz_cloud. points . size () + high_conf_xyz_cloud .points .size ());
165
- for (size_t i = 0 ; i < low_conf_xyz_cloud .points .size (); ++i) {
166
- xy_cloud ->points [i].x = low_conf_xyz_cloud .points [i].x ;
167
- xy_cloud ->points [i].y = low_conf_xyz_cloud .points [i].y ;
160
+ pcl::PointCloud<pcl::PointXY>::Ptr low_conf_xy_cloud (new pcl::PointCloud<pcl::PointXY>);
161
+ low_conf_xy_cloud ->points .resize (low_conf_input .points .size ());
162
+ for (size_t i = 0 ; i < low_conf_input .points .size (); ++i) {
163
+ low_conf_xy_cloud ->points [i].x = low_conf_input .points [i].x ;
164
+ low_conf_xy_cloud ->points [i].y = low_conf_input .points [i].y ;
168
165
}
169
- for (size_t i = low_conf_xyz_cloud.points .size (); i < xy_cloud->points .size (); ++i) {
170
- xy_cloud->points [i].x = high_conf_xyz_cloud.points [i - low_conf_xyz_cloud.points .size ()].x ;
171
- xy_cloud->points [i].y = high_conf_xyz_cloud.points [i - low_conf_xyz_cloud.points .size ()].y ;
166
+
167
+ // Low conf cloud check
168
+ std::vector<int > k_indices_low (low_conf_xy_cloud->points .size ());
169
+ std::vector<float > k_distances_low (low_conf_xy_cloud->points .size ());
170
+ kd_tree_->setInputCloud (low_conf_xy_cloud);
171
+ for (size_t i = 0 ; i < low_conf_input.points .size (); ++i) {
172
+ const float distance = std::hypot (low_conf_xy_cloud->points [i].x - pose.position .x , low_conf_xy_cloud->points [i].y - pose.position .y );
173
+ const int min_points_threshold = std::min (
174
+ std::max (static_cast <int >(min_points_and_distance_ratio_ / distance + 0 .5f ), min_points_),
175
+ max_points_);
176
+ const int points_num = kd_tree_->nearestKSearch (i, min_points_threshold, k_indices_low, k_distances_low);
177
+ if (min_points_threshold <= points_num) {
178
+ output.points .push_back (low_conf_input.points .at (i));
179
+ } else {
180
+ outlier.points .push_back (low_conf_input.points .at (i));
181
+ }
172
182
}
173
183
174
- std::vector<int > k_indices (xy_cloud->points .size ());
175
- std::vector<float > k_distances (xy_cloud->points .size ());
176
- kd_tree_->setInputCloud (xy_cloud);
177
- for (size_t i = 0 ; i < low_conf_xyz_cloud.points .size (); ++i) {
178
- const float distance =
179
- std::hypot (xy_cloud->points [i].x - pose.position .x , xy_cloud->points [i].y - pose.position .y );
184
+ // High conf cloud check
185
+ if (outlier.points .size () == 0 ){return ;}
186
+
187
+ pcl::PointCloud<pcl::PointXY>::Ptr high_conf_xy_cloud (new pcl::PointCloud<pcl::PointXY>);
188
+ high_conf_xy_cloud->points .resize (high_conf_input.points .size ());
189
+ for (size_t i = 0 ; i < high_conf_input.points .size (); ++i) {
190
+ high_conf_xy_cloud->points [i].x = high_conf_input.points [i].x ;
191
+ high_conf_xy_cloud->points [i].y = high_conf_input.points [i].y ;
192
+ }
193
+
194
+ std::vector<int > k_indices_high (high_conf_xy_cloud->points .size ());
195
+ std::vector<float > k_distances_high (high_conf_xy_cloud->points .size ());
196
+ kd_tree_->setInputCloud (high_conf_xy_cloud);
197
+ for (size_t i = 0 ; i < outlier.points .size (); ++i) {
198
+ const float distance = std::hypot (high_conf_xy_cloud->points [i].x - pose.position .x , high_conf_xy_cloud->points [i].y - pose.position .y );
180
199
const int min_points_threshold = std::min (
181
200
std::max (static_cast <int >(min_points_and_distance_ratio_ / distance + 0 .5f ), min_points_),
182
201
max_points_);
183
- const int points_num =
184
- kd_tree_->radiusSearch (i, search_radius_, k_indices, k_distances, min_points_threshold);
202
+ const int points_num = kd_tree_->nearestKSearch (i, min_points_threshold, k_indices_high, k_distances_high);
185
203
186
204
if (min_points_threshold <= points_num) {
187
- output.points .push_back (low_conf_xyz_cloud .points .at (i));
205
+ output.points .push_back (outlier .points .at (i));
188
206
} else {
189
- outlier.points .push_back (low_conf_xyz_cloud .points .at (i) );
207
+ outlier.points .erase (outlier .points .begin () + i );
190
208
}
191
209
}
192
210
}
@@ -239,19 +257,41 @@ OccupancyGridMapOutlierFilterComponent::OccupancyGridMapOutlierFilterComponent(
239
257
void OccupancyGridMapOutlierFilterComponent::splitPointCloudFrontBack (
240
258
const PointCloud2::ConstSharedPtr & input_pc, PointCloud2 & front_pc, PointCloud2 & behind_pc)
241
259
{
242
- PclPointCloud tmp_behind_pc;
243
- PclPointCloud tmp_front_pc;
244
- for (sensor_msgs::PointCloud2ConstIterator<float > x (*input_pc, " x" ), y (*input_pc, " y" ),
245
- z (*input_pc, " z" );
246
- x != x.end (); ++x, ++y, ++z) {
260
+ size_t front_count = 0 ;
261
+ size_t behind_count = 0 ;
262
+
263
+ for (sensor_msgs::PointCloud2ConstIterator<float > x (*input_pc, " x" ); x != x.end (); ++x) {
247
264
if (*x < 0.0 ) {
248
- tmp_behind_pc. push_back ( pcl::PointXYZ (*x, *y, *z)) ;
265
+ behind_count++ ;
249
266
} else {
250
- tmp_front_pc. push_back ( pcl::PointXYZ (*x, *y, *z)) ;
267
+ front_count++ ;
251
268
}
252
269
}
253
- pcl::toROSMsg (tmp_front_pc, front_pc);
254
- pcl::toROSMsg (tmp_behind_pc, behind_pc);
270
+
271
+ sensor_msgs::PointCloud2Modifier front_pc_modfier (front_pc);
272
+ sensor_msgs::PointCloud2Modifier behind_pc_modfier (behind_pc);
273
+ front_pc_modfier.setPointCloud2FieldsByString (1 ," xyz" );
274
+ behind_pc_modfier.setPointCloud2FieldsByString (1 ," xyz" );
275
+ front_pc_modfier.resize (front_count);
276
+ behind_pc_modfier.resize (behind_count);
277
+
278
+ sensor_msgs::PointCloud2Iterator<float > fr_iter (front_pc, " x" );
279
+ sensor_msgs::PointCloud2Iterator<float > be_iter (behind_pc, " x" );
280
+
281
+ for (sensor_msgs::PointCloud2ConstIterator<float > in_iter (*input_pc, " x" ); in_iter != in_iter.end (); ++in_iter) {
282
+ if (*in_iter < 0.0 ) {
283
+ *be_iter = in_iter[0 ];
284
+ be_iter[1 ] = in_iter[1 ];
285
+ be_iter[2 ] = in_iter[2 ];
286
+ ++be_iter;
287
+ } else {
288
+ *fr_iter = in_iter[0 ];
289
+ fr_iter[1 ] = in_iter[1 ];
290
+ fr_iter[2 ] = in_iter[2 ];
291
+ ++fr_iter;
292
+ }
293
+ }
294
+
255
295
front_pc.header = input_pc->header ;
256
296
behind_pc.header = input_pc->header ;
257
297
}
0 commit comments