3#include <SimoxUtility/math/periodic/periodic_diff.h>
4#include <SimoxUtility/math/periodic/periodic_mean.h>
8 const pcl::PointIndices& indices)
10 std::vector<float> xs, ys, zs;
11 xs.reserve(cloud.size());
12 ys.reserve(cloud.size());
13 zs.reserve(cloud.size());
15 auto processPoint = [&](
const auto& p)
22 if (indices.indices.empty())
24 for (
const auto& p : cloud)
31 for (
int i : indices.indices)
33 processPoint(cloud.at(
size_t(i)));
37 std::sort(xs.begin(), xs.end());
38 std::sort(ys.begin(), ys.end());
39 std::sort(zs.begin(), zs.end());
41 size_t index = cloud.size() / 2;
48 return fitPlaneSVD(cloud, pcl::PointIndices(), center);
53 const pcl::PointIndices& indices,
54 Eigen::Vector3f center)
69 if (indices.indices.empty())
72 A = MatT(3, cloud.size());
73 for (
size_t i = 0; i < cloud.size(); ++i)
75 A.col(
int(i)) = Eigen::Vector3f(cloud[i].
data) - center;
81 A = MatT(3, indices.indices.size());
82 for (
int index : indices.indices)
84 A.col(i++) = Eigen::Vector3f(cloud.at(
size_t(
index)).data) - center;
89 Eigen::JacobiSVD<MatT> svd(
A, Eigen::ComputeFullU);
92 Eigen::Vector3f normal = svd.matrixU().col(2);
102 pcl::PointIndicesPtr inliers(
new pcl::PointIndices);
103 for (
size_t i = 0; i < cloud.size(); ++i)
105 if (plane.absDistance(Eigen::Vector3f(cloud[i].data)) <= maxDistance)
107 inliers->indices.push_back(
int(i));
115 const pcl::PointXYZHSV& rhs,
116 const Eigen::Vector3f& hsvWeights)
119 Eigen::Vector3f(lhs.h, lhs.s, lhs.v), Eigen::Vector3f(rhs.h, rhs.s, rhs.v), hsvWeights);
124 const Eigen::Vector3f& rhs,
125 const Eigen::Vector3f& hsvWeights)
127 Eigen::Array3f dists(simox::math::periodic_diff(lhs.x(), rhs.x(), 0.f, 360.f) / 180.f,
130 Eigen::Array3f weighted = hsvWeights.normalized().array() * dists.abs();
131 return weighted.sum();
135visionx::hsvMean(
const pcl::PointCloud<pcl::PointXYZHSV>& hsvCloud,
const std::vector<int>& indices)
138 std::vector<float> hues;
139 hues.reserve(indices.size());
141 for (
int i : indices)
143 const auto& p = hsvCloud.at(
size_t(i));
148 float h = simox::math::periodic_mean(hues, 0.f, 360.f);
149 Eigen::Vector3f hsv(h, s / indices.size(), v / indices.size());
156 return plane.normal().dot(normal) >= 0 ? plane
class A(deque< T, A >)) ARMARX_OVERLOAD_STD_HASH_FOR_ITERABLE((class T
Enables hashing of std::list.
Hyperplane< float, 3 > Hyperplane3f
pcl::PointIndicesPtr getPlaneInliers(const pcl::PointCloud< pcl::PointXYZRGBA > &cloud, Eigen::Hyperplane3f plane, float maxDistance)
Eigen::Hyperplane3f fitPlaneSVD(const pcl::PointCloud< pcl::PointXYZRGBA > &cloud, const pcl::PointIndices &indices, Eigen::Vector3f center=Eigen::Vector3f::Zero())
float hsvDistance(const pcl::PointXYZHSV &lhs, const pcl::PointXYZHSV &rhs, const Eigen::Vector3f &hsvWeights=Eigen::Vector3f::Ones())
Eigen::Hyperplane3f alignPlaneNormal(Eigen::Hyperplane3f plane, Eigen::Vector3f normal)
Flip plane if its normal does not point towards normal.
Eigen::Vector3f pointCloudMedian(const pcl::PointCloud< pcl::PointXYZRGBA > &cloud, const pcl::PointIndices &indices={})
Eigen::Vector3f hsvMean(const pcl::PointCloud< pcl::PointXYZHSV > &hsvCloud, const std::vector< int > &indices)