2021-01-04 21:26:09 +08:00
|
|
|
#pragma once
|
|
|
|
|
2021-01-30 01:19:14 +08:00
|
|
|
#include <pcl/common/eigen.h>
|
|
|
|
#include <pcl/common/transforms.h>
|
|
|
|
#include <pcl/point_cloud.h>
|
|
|
|
|
|
|
|
#include "common/geometry/pose3d.h"
|
2021-01-05 02:09:40 +08:00
|
|
|
#include "common/log/log.h"
|
2021-01-04 21:26:09 +08:00
|
|
|
#include "pcl_types.h"
|
|
|
|
|
|
|
|
namespace common {
|
|
|
|
|
2021-01-25 21:00:10 +08:00
|
|
|
// Distance squared of a point to origin
|
2021-01-23 22:11:08 +08:00
|
|
|
template <typename PT>
|
2021-01-25 21:00:10 +08:00
|
|
|
inline double DistanceSquare(const PT &pt) {
|
2021-01-04 21:26:09 +08:00
|
|
|
return pt.x * pt.x + pt.y * pt.y + pt.z * pt.z;
|
|
|
|
}
|
|
|
|
|
2021-01-25 21:00:10 +08:00
|
|
|
// Distance squared of two points
|
2021-01-23 22:11:08 +08:00
|
|
|
template <typename PT>
|
2021-01-25 21:00:10 +08:00
|
|
|
inline double DistanceSquare(const PT &pt1, const PT &pt2) {
|
2021-01-04 21:26:09 +08:00
|
|
|
return (pt1.x - pt2.x) * (pt1.x - pt2.x) + (pt1.y - pt2.y) * (pt1.y - pt2.y) +
|
|
|
|
(pt1.z - pt2.z) * (pt1.z - pt2.z);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Distance of a point to origin
|
2021-01-23 22:11:08 +08:00
|
|
|
template <typename PT>
|
|
|
|
inline double Distance(const PT &pt) {
|
2021-01-25 21:00:10 +08:00
|
|
|
return std::sqrt(DistanceSquare(pt));
|
2021-01-04 21:26:09 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// Distance squred of two points
|
2021-01-23 22:11:08 +08:00
|
|
|
template <typename PT>
|
|
|
|
inline double Distance(const PT &pt1, const PT &pt2) {
|
2021-01-25 21:00:10 +08:00
|
|
|
return std::sqrt(DistanceSquare(pt1, pt2));
|
2021-01-04 21:26:09 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// Check whether is a finite point: neither infinite nor nan
|
2021-01-23 22:11:08 +08:00
|
|
|
template <typename PT>
|
|
|
|
inline double IsFinite(const PT &pt) {
|
2021-01-04 21:26:09 +08:00
|
|
|
return std::isfinite(pt.x) && std::isfinite(pt.y) && std::isfinite(pt.z);
|
|
|
|
}
|
|
|
|
|
2021-01-30 01:19:14 +08:00
|
|
|
template <typename PT>
|
|
|
|
inline void TransformPoint(const Pose3d &pose, const PT &pt_in,
|
|
|
|
PT *const pt_out) {
|
|
|
|
*pt_out = pt_in;
|
|
|
|
Eigen::Vector3d p = pose * Eigen::Vector3d(pt_in.x, pt_in.y, pt_in.z);
|
|
|
|
pt_out->x = p.x();
|
|
|
|
pt_out->y = p.y();
|
|
|
|
pt_out->z = p.z();
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename PT>
|
|
|
|
inline PT TransformPoint(const Pose3d &pose, const PT &pt_in) {
|
|
|
|
PT pt_out;
|
|
|
|
TransformPoint<PT>(pose, pt_in, &pt_out);
|
|
|
|
return pt_out;
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename PT>
|
|
|
|
inline void TransformPointCloud(const Pose3d &pose,
|
|
|
|
const pcl::PointCloud<PT> &cloud_in,
|
|
|
|
pcl::PointCloud<PT> *const cloud_out) {
|
|
|
|
pcl::transformPointCloud(cloud_in, *cloud_out, pose.TransMat().cast<float>());
|
|
|
|
}
|
|
|
|
|
2021-01-04 21:26:09 +08:00
|
|
|
// Remove point if the condition evaluated to true on it
|
2021-01-23 22:11:08 +08:00
|
|
|
template <typename PT>
|
|
|
|
void RemovePoints(const pcl::PointCloud<PT> &cloud_in,
|
|
|
|
pcl::PointCloud<PT> *const cloud_out,
|
|
|
|
std::function<bool(const PT &)> check,
|
2021-01-22 16:33:55 +08:00
|
|
|
std::vector<int> *const removed_indices = nullptr) {
|
2021-01-05 02:09:40 +08:00
|
|
|
if (&cloud_in != cloud_out) {
|
2021-01-04 21:26:09 +08:00
|
|
|
cloud_out->header = cloud_in.header;
|
2021-01-05 02:09:40 +08:00
|
|
|
cloud_out->resize(cloud_in.size());
|
2021-01-04 21:26:09 +08:00
|
|
|
}
|
|
|
|
size_t j = 0;
|
2021-01-05 02:09:40 +08:00
|
|
|
for (size_t i = 0; i < cloud_in.size(); ++i) {
|
2021-02-27 17:55:29 +08:00
|
|
|
const auto &pt = cloud_in.points[i];
|
2021-01-14 00:34:13 +08:00
|
|
|
if (check(pt)) {
|
|
|
|
if (removed_indices) removed_indices->push_back(i);
|
|
|
|
continue;
|
|
|
|
}
|
2021-01-04 21:26:09 +08:00
|
|
|
cloud_out->points[j++] = pt;
|
|
|
|
}
|
|
|
|
|
|
|
|
cloud_out->points.resize(j);
|
|
|
|
cloud_out->height = 1;
|
|
|
|
cloud_out->width = static_cast<uint32_t>(j);
|
|
|
|
cloud_out->is_dense = true;
|
|
|
|
}
|
|
|
|
|
2021-01-23 22:11:08 +08:00
|
|
|
template <typename PT>
|
|
|
|
void VoxelDownSample(const typename pcl::PointCloud<PT>::ConstPtr &cloud_in,
|
|
|
|
pcl::PointCloud<PT> *const cloud_out, double voxel_size) {
|
|
|
|
pcl::VoxelGrid<PT> filter;
|
2021-01-04 21:26:09 +08:00
|
|
|
filter.setInputCloud(cloud_in);
|
|
|
|
filter.setLeafSize(voxel_size, voxel_size, voxel_size);
|
2021-02-08 17:09:52 +08:00
|
|
|
if (cloud_out == cloud_in.get()) {
|
|
|
|
pcl::PointCloud<PT> cloud_downsampled;
|
|
|
|
filter.filter(cloud_downsampled);
|
|
|
|
cloud_out->swap(cloud_downsampled);
|
|
|
|
} else {
|
|
|
|
filter.filter(*cloud_out);
|
|
|
|
}
|
2021-01-04 21:26:09 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
} // namespace common
|