64 #include "pcl/common/common.h" 65 #include "pcl/filters/voxel_grid.h" 66 #include "pcl/kdtree/kdtree_flann.h" 69 namespace localization {
72 template <
typename Po
intT>
78 using pcl::VoxelGrid<PointT>::filter_name_;
79 using pcl::VoxelGrid<PointT>::getClassName;
80 using pcl::VoxelGrid<PointT>::input_;
81 using pcl::VoxelGrid<PointT>::indices_;
82 using pcl::VoxelGrid<PointT>::filter_limit_negative_;
83 using pcl::VoxelGrid<PointT>::filter_limit_min_;
84 using pcl::VoxelGrid<PointT>::filter_limit_max_;
85 using pcl::VoxelGrid<PointT>::filter_field_name_;
87 using pcl::VoxelGrid<PointT>::downsample_all_data_;
88 using pcl::VoxelGrid<PointT>::leaf_layout_;
89 using pcl::VoxelGrid<PointT>::save_leaf_layout_;
90 using pcl::VoxelGrid<PointT>::leaf_size_;
91 using pcl::VoxelGrid<PointT>::min_b_;
92 using pcl::VoxelGrid<PointT>::max_b_;
93 using pcl::VoxelGrid<PointT>::inverse_leaf_size_;
94 using pcl::VoxelGrid<PointT>::div_b_;
95 using pcl::VoxelGrid<PointT>::divb_mul_;
97 typedef typename pcl::traits::fieldList<PointT>::type
FieldList;
103 typedef boost::shared_ptr<pcl::VoxelGrid<PointT>>
Ptr;
104 typedef boost::shared_ptr<const pcl::VoxelGrid<PointT>>
ConstPtr;
107 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
167 min_points_per_voxel_(6),
168 min_covar_eigvalue_mult_(0.01),
171 voxel_centroidsleaf_indices_(),
173 downsample_all_data_ =
false;
174 save_leaf_layout_ =
false;
175 leaf_size_.setZero();
178 filter_name_ =
"VoxelGridCovariance";
183 if (min_points_per_voxel > 2) {
184 min_points_per_voxel_ = min_points_per_voxel;
186 PCL_WARN(
"%s, Covariance need 3 pts, set min_pt_per_vexel to 3",
187 this->getClassName().c_str());
188 min_points_per_voxel_ = 3;
197 min_covar_eigvalue_mult_ = min_covar_eigvalue_mult;
201 return min_covar_eigvalue_mult_;
205 inline void Filter(PointCloudPtr output,
bool searchable =
false) {
206 searchable_ = searchable;
209 if (searchable_ && voxel_centroids_->size() > 0) {
210 kdtree_.setInputCloud(voxel_centroids_);
215 inline void Filter(
bool searchable =
false) {
216 searchable_ = searchable;
218 ApplyFilter(voxel_centroids_);
219 if (searchable_ && voxel_centroids_->size() > 0) {
220 kdtree_.setInputCloud(voxel_centroids_);
226 typename std::map<size_t, Leaf>::iterator leaf_iter = leaves_.find(index);
227 if (leaf_iter != leaves_.end()) {
228 LeafConstPtr ret(&(leaf_iter->second));
236 inline LeafConstPtr
GetLeaf(
const PointT& p) {
238 int ijk0 =
static_cast<int>(floor(p.x * inverse_leaf_size_[0]) - min_b_[0]);
239 int ijk1 =
static_cast<int>(floor(p.y * inverse_leaf_size_[1]) - min_b_[1]);
240 int ijk2 =
static_cast<int>(floor(p.z * inverse_leaf_size_[2]) - min_b_[2]);
243 int idx = ijk0 * divb_mul_[0] + ijk1 * divb_mul_[1] + ijk2 * divb_mul_[2];
246 typename std::map<size_t, Leaf>::iterator leaf_iter = leaves_.find(idx);
247 if (leaf_iter != leaves_.end()) {
249 LeafConstPtr ret(&(leaf_iter->second));
260 static_cast<int>(floor(p[0] * inverse_leaf_size_[0]) - min_b_[0]);
262 static_cast<int>(floor(p[1] * inverse_leaf_size_[1]) - min_b_[1]);
264 static_cast<int>(floor(p[2] * inverse_leaf_size_[2]) - min_b_[2]);
267 int idx = ijk0 * divb_mul_[0] + ijk1 * divb_mul_[1] + ijk2 * divb_mul_[2];
270 typename std::map<size_t, Leaf>::iterator leaf_iter = leaves_.find(idx);
271 if (leaf_iter != leaves_.end()) {
273 LeafConstPtr ret(&(leaf_iter->second));
281 inline std::map<size_t, Leaf>&
GetLeaves() {
return leaves_; }
285 void ApplyFilter(PointCloudPtr output) {
286 voxel_centroidsleaf_indices_.clear();
290 PCL_WARN(
"[%s::ApplyFilter] No input dataset given!\n",
291 getClassName().c_str());
292 output->width = output->height = 0;
293 output->points.clear();
298 output->is_dense =
true;
299 output->points.clear();
301 Eigen::Vector4f min_p, max_p;
303 if (!filter_field_name_.empty()) {
304 pcl::getMinMax3D<PointT>(input_, filter_field_name_,
305 static_cast<float>(filter_limit_min_),
306 static_cast<float>(filter_limit_max_), min_p,
307 max_p, filter_limit_negative_);
309 pcl::getMinMax3D<PointT>(*input_, min_p, max_p);
313 static_cast<int64_t
>((max_p[0] - min_p[0]) * inverse_leaf_size_[0]) + 1;
315 static_cast<int64_t
>((max_p[1] - min_p[1]) * inverse_leaf_size_[1]) + 1;
317 static_cast<int64_t
>((max_p[2] - min_p[2]) * inverse_leaf_size_[2]) + 1;
319 if ((dx * dy * dz) > std::numeric_limits<int32_t>::max()) {
321 "[%s::ApplyFilter] leaf size is too small. Integer indices would " 323 getClassName().c_str());
328 min_b_[0] =
static_cast<int>(floor(min_p[0] * inverse_leaf_size_[0]));
329 max_b_[0] =
static_cast<int>(floor(max_p[0] * inverse_leaf_size_[0]));
330 min_b_[1] =
static_cast<int>(floor(min_p[1] * inverse_leaf_size_[1]));
331 max_b_[1] =
static_cast<int>(floor(max_p[1] * inverse_leaf_size_[1]));
332 min_b_[2] =
static_cast<int>(floor(min_p[2] * inverse_leaf_size_[2]));
333 max_b_[2] =
static_cast<int>(floor(max_p[2] * inverse_leaf_size_[2]));
336 div_b_ = max_b_ - min_b_ + Eigen::Vector4i::Ones();
341 divb_mul_ = Eigen::Vector4i(1, div_b_[0], div_b_[0] * div_b_[1], 0);
342 int centroid_size = 4;
343 if (downsample_all_data_) {
347 std::vector<pcl::PCLPointField> fields;
349 rgba_index = pcl::getFieldIndex(*input_,
"rgb", fields);
350 if (rgba_index == -1) {
351 rgba_index = pcl::getFieldIndex(*input_,
"rgba", fields);
353 if (rgba_index >= 0) {
354 rgba_index = fields[rgba_index].offset;
359 if (!filter_field_name_.empty()) {
361 std::vector<pcl::PCLPointField> fields;
363 pcl::getFieldIndex(*input_, filter_field_name_, fields);
364 if (distance_idx == -1) {
366 "[pcl::%s::ApplyFilter] Invalid filter field name. Index is %d.\n",
367 getClassName().c_str(), distance_idx);
371 for (
size_t cp = 0; cp < input_->points.size(); ++cp) {
372 if (!input_->is_dense) {
374 if (!std::isfinite(input_->points[cp].x) ||
375 !std::isfinite(input_->points[cp].y) ||
376 !std::isfinite(input_->points[cp].z)) {
381 const uint8_t* pt_data =
382 reinterpret_cast<const uint8_t*
>(&input_->points[cp]);
383 float distance_value = 0.0f;
384 memcpy(&distance_value, pt_data + fields[distance_idx].offset,
387 if (filter_limit_negative_) {
389 if ((distance_value < filter_limit_max_) &&
390 (distance_value > filter_limit_min_)) {
395 if ((distance_value > filter_limit_max_) ||
396 (distance_value < filter_limit_min_)) {
401 int ijk0 =
static_cast<int>(
402 floor(input_->points[cp].x * inverse_leaf_size_[0]) -
403 static_cast<float>(min_b_[0]));
404 int ijk1 =
static_cast<int>(
405 floor(input_->points[cp].y * inverse_leaf_size_[1]) -
406 static_cast<float>(min_b_[1]));
407 int ijk2 =
static_cast<int>(
408 floor(input_->points[cp].z * inverse_leaf_size_[2]) -
409 static_cast<float>(min_b_[2]));
412 ijk0 * divb_mul_[0] + ijk1 * divb_mul_[1] + ijk2 * divb_mul_[2];
414 Leaf& leaf = leaves_[idx];
416 leaf.
centroid.resize(centroid_size);
421 leaf.
cloud_.points.push_back(input_->points[cp]);
424 input_->points[cp].z);
428 leaf.
cov_ += pt3d * pt3d.transpose();
431 if (!downsample_all_data_) {
432 Eigen::Vector4f pt(input_->points[cp].x, input_->points[cp].y,
433 input_->points[cp].z, 0);
434 leaf.
centroid.template head<4>() += pt;
437 Eigen::VectorXf
centroid = Eigen::VectorXf::Zero(centroid_size);
438 pcl::for_each_type<FieldList>(pcl::NdCopyPointEigenFunctor<PointT>(
441 if (rgba_index >= 0) {
443 const pcl::RGB& rgb = *
reinterpret_cast<const pcl::RGB*
>(
444 reinterpret_cast<const char*
>(&input_->points[cp]) +
446 centroid[centroid_size - 4] = rgb.a;
447 centroid[centroid_size - 3] = rgb.r;
448 centroid[centroid_size - 2] = rgb.g;
449 centroid[centroid_size - 1] = rgb.b;
457 for (
size_t cp = 0; cp < input_->points.size(); ++cp) {
458 if (!input_->is_dense) {
460 if (!std::isfinite(input_->points[cp].x) ||
461 !std::isfinite(input_->points[cp].y) ||
462 !std::isfinite(input_->points[cp].z)) {
466 int ijk0 =
static_cast<int>(
467 floor(input_->points[cp].x * inverse_leaf_size_[0]) -
468 static_cast<float>(min_b_[0]));
469 int ijk1 =
static_cast<int>(
470 floor(input_->points[cp].y * inverse_leaf_size_[1]) -
471 static_cast<float>(min_b_[1]));
472 int ijk2 =
static_cast<int>(
473 floor(input_->points[cp].z * inverse_leaf_size_[2]) -
474 static_cast<float>(min_b_[2]));
478 ijk0 * divb_mul_[0] + ijk1 * divb_mul_[1] + ijk2 * divb_mul_[2];
484 Leaf& leaf = leaves_[idx];
486 leaf.
centroid.resize(centroid_size);
491 leaf.
cloud_.points.push_back(input_->points[cp]);
494 input_->points[cp].z);
498 leaf.
cov_ += pt3d * pt3d.transpose();
501 if (!downsample_all_data_) {
502 Eigen::Vector4f pt(input_->points[cp].x, input_->points[cp].y,
503 input_->points[cp].z, 0);
504 leaf.
centroid.template head<4>() += pt;
507 Eigen::VectorXf
centroid = Eigen::VectorXf::Zero(centroid_size);
508 pcl::for_each_type<FieldList>(pcl::NdCopyPointEigenFunctor<PointT>(
511 if (rgba_index >= 0) {
513 const pcl::RGB& rgb = *
reinterpret_cast<const pcl::RGB*
>(
514 reinterpret_cast<const char*
>(&input_->points[cp]) +
516 centroid[centroid_size - 4] = rgb.a;
517 centroid[centroid_size - 3] = rgb.r;
518 centroid[centroid_size - 2] = rgb.g;
519 centroid[centroid_size - 1] = rgb.b;
528 output->points.reserve(leaves_.size());
530 voxel_centroidsleaf_indices_.reserve(leaves_.size());
533 if (save_leaf_layout_) {
534 leaf_layout_.resize(div_b_[0] * div_b_[1] * div_b_[2], -1);
537 Eigen::SelfAdjointEigenSolver<Eigen::Matrix3d> eigensolver;
543 double min_covar_eigvalue;
545 for (
typename std::map<size_t, Leaf>::iterator it = leaves_.begin();
546 it != leaves_.end(); ++it) {
548 Leaf& leaf = it->second;
557 if (leaf.
nr_points_ >= min_points_per_voxel_) {
558 if (save_leaf_layout_) {
559 leaf_layout_[it->first] = cp++;
561 output->push_back(PointT());
563 if (!downsample_all_data_) {
564 output->points.back().x = leaf.
centroid[0];
565 output->points.back().y = leaf.
centroid[1];
566 output->points.back().z = leaf.
centroid[2];
568 pcl::for_each_type<FieldList>(pcl::NdCopyEigenPointFunctor<PointT>(
571 if (rgba_index >= 0) {
572 pcl::RGB& rgb = *
reinterpret_cast<pcl::RGB*
>(
573 reinterpret_cast<char*
>(&output->points.back()) + rgba_index);
574 rgb.a =
static_cast<uint8_t
>(leaf.
centroid[centroid_size - 4]);
575 rgb.r =
static_cast<uint8_t
>(leaf.
centroid[centroid_size - 3]);
576 rgb.g =
static_cast<uint8_t
>(leaf.
centroid[centroid_size - 2]);
577 rgb.b =
static_cast<uint8_t
>(leaf.
centroid[centroid_size - 1]);
583 voxel_centroidsleaf_indices_.push_back(static_cast<int>(it->first));
587 leaf.
cov_ = (leaf.
cov_ - 2 * (pt_sum * leaf.
mean_.transpose())) /
593 eigensolver.compute(leaf.
cov_);
594 eigen_val = eigensolver.eigenvalues().asDiagonal();
595 leaf.
evecs_ = eigensolver.eigenvectors();
597 if (eigen_val(0, 0) < 0 || eigen_val(1, 1) < 0 ||
598 eigen_val(2, 2) <= 0) {
604 min_covar_eigvalue = min_covar_eigvalue_mult_ * eigen_val(2, 2);
605 if (eigen_val(0, 0) < min_covar_eigvalue) {
606 eigen_val(0, 0) = min_covar_eigvalue;
607 if (eigen_val(1, 1) < min_covar_eigvalue) {
608 eigen_val(1, 1) = min_covar_eigvalue;
612 leaf.
evals_ = eigen_val.diagonal();
615 if (leaf.
icov_.maxCoeff() == std::numeric_limits<float>::infinity() ||
616 leaf.
icov_.minCoeff() == -std::numeric_limits<float>::infinity()) {
621 output->width =
static_cast<uint32_t
>(output->points.size());
628 int min_points_per_voxel_;
631 double min_covar_eigvalue_mult_;
634 std::map<size_t, Leaf> leaves_;
638 PointCloudPtr voxel_centroids_;
642 std::vector<int> voxel_centroidsleaf_indices_;
645 pcl::KdTreeFLANN<PointT> kdtree_;
int nr_points_
Definition: voxel_grid_covariance_hdmap.h:136
boost::shared_ptr< pcl::VoxelGrid< PointT > > Ptr
Definition: voxel_grid_covariance_hdmap.h:103
Definition: voxel_grid_covariance_hdmap.h:75
VoxelGridCovariance()
Definition: voxel_grid_covariance_hdmap.h:165
Eigen::Vector3f Vector3f
Definition: base_map_fwd.h:29
Eigen::Vector3d mean_
Definition: voxel_grid_covariance_hdmap.h:139
PlanningContext is the runtime context in planning. It is persistent across multiple frames...
Definition: atomic_hash_map.h:25
void SetMinPointPerVoxel(int min_points_per_voxel)
Definition: voxel_grid_covariance_hdmap.h:182
void Filter(bool searchable=false)
Definition: voxel_grid_covariance_hdmap.h:215
Leaf * LeafPtr
Definition: voxel_grid_covariance_hdmap.h:160
Eigen::Matrix3d cov_
Definition: voxel_grid_covariance_hdmap.h:145
Eigen::Matrix3d icov_
Definition: voxel_grid_covariance_hdmap.h:148
Eigen::Matrix3d evecs_
Definition: voxel_grid_covariance_hdmap.h:151
Eigen::Vector3d GetEvals() const
Definition: voxel_grid_covariance_hdmap.h:130
Eigen::Vector3d Vector3d
Definition: frame_transform.h:27
const Leaf * LeafConstPtr
Definition: voxel_grid_covariance_hdmap.h:162
EIGEN_MAKE_ALIGNED_OPERATOR_NEW Leaf()
Definition: voxel_grid_covariance_hdmap.h:108
LeafType
Definition: voxel_grid_covariance_hdmap.h:75
int GetMinPointPerVoxel()
Definition: voxel_grid_covariance_hdmap.h:193
Definition: voxel_grid_covariance_hdmap.h:106
Definition: voxel_grid_covariance_hdmap.h:75
std::map< size_t, Leaf > & GetLeaves()
Definition: voxel_grid_covariance_hdmap.h:281
LeafConstPtr GetLeaf(const Eigen::Vector3f &p)
Definition: voxel_grid_covariance_hdmap.h:257
Eigen::Vector3d GetMean() const
Definition: voxel_grid_covariance_hdmap.h:124
LeafConstPtr GetLeaf(const PointT &p)
Definition: voxel_grid_covariance_hdmap.h:236
Eigen::VectorXf centroid
Definition: voxel_grid_covariance_hdmap.h:142
boost::shared_ptr< const pcl::VoxelGrid< PointT > > ConstPtr
Definition: voxel_grid_covariance_hdmap.h:104
Eigen::Matrix3d GetEvecs() const
Definition: voxel_grid_covariance_hdmap.h:127
void SetCovEigValueInflationRatio(double min_covar_eigvalue_mult)
Definition: voxel_grid_covariance_hdmap.h:196
pcl::traits::fieldList< PointT >::type FieldList
Definition: voxel_grid_covariance_hdmap.h:97
Definition: voxel_grid_covariance_hdmap.h:75
double GetCovEigValueInflationRatio()
Definition: voxel_grid_covariance_hdmap.h:200
int GetPointCount() const
Definition: voxel_grid_covariance_hdmap.h:133
void Filter(PointCloudPtr output, bool searchable=false)
Definition: voxel_grid_covariance_hdmap.h:205
LeafType type_
Definition: voxel_grid_covariance_hdmap.h:157
apollo::cyber::base::std value
PointCloud::Ptr PointCloudPtr
Definition: voxel_grid_covariance_hdmap.h:99
Eigen::Vector3d evals_
Definition: voxel_grid_covariance_hdmap.h:154
pcl::PointCloud< PointT > PointCloud
Definition: voxel_grid_covariance_hdmap.h:98
Eigen::Matrix3d GetInverseCov() const
Definition: voxel_grid_covariance_hdmap.h:121
LeafConstPtr GetLeaf(int index)
Definition: voxel_grid_covariance_hdmap.h:225
PointCloud::ConstPtr PointCloudConstPtr
Definition: voxel_grid_covariance_hdmap.h:100
Eigen::Matrix3d GetCov() const
Definition: voxel_grid_covariance_hdmap.h:118
Definition: voxel_grid_covariance_hdmap.h:75
pcl::PointCloud< PointT > cloud_
Definition: voxel_grid_covariance_hdmap.h:156
Eigen::Matrix3d Matrix3d
Definition: base_map_fwd.h:33
Definition: voxel_grid_covariance_hdmap.h:73