HPR:hidden point remove是一种遮挡检测领域一种经典的方法。在CC和open3d中都有实现。假设给定一个相机中心C,和点云P,HPR主要分为两个步骤:
1点云反转(inversion)
利用一个函数,将点云pi沿着光线方向(相机中心C与点云pi连线)投影到一个特殊的几何体上。
考虑一个以原点(相机中心:C )为圆心,半径为R的D维球面,并限制其包含P中的所有点。
使用spherical fipping实现上述思想。利用以下等式:
p
^
i
=
f
(
p
i
)
=
p
i
+
2
(
R
−
∥
p
i
∥
)
p
i
∥
p
i
∥
\widehat{p}_i=f\left(p_i\right)=p_i+2\left(R-\left\|p_i\right\|\right) \frac{p_i}{\left\|p_i\right\|}
p
i=f(pi)=pi+2(R−∥pi∥)∥pi∥pi
直观地说,spherical fipping将球面内部的每一点pi沿着从C到pi的射线映射到球面外部的图像,如下图所示:
2构建凸包
设点云P经过spherical fipping投影为点云P’,将P’和相机中心C构建凸包,位于凸包上的点即为可见点。
有一些算法讨论和理论证明,我没看特别明白。
3code
pcl::PointXYZ cameraPoint {}//assign value by yourself
// pcl::PointXYZ cameraPoint = cloud->points[0];
Eigen::Vector3d camera_location(cameraPoint.x, cameraPoint.y, cameraPoint.z);
std::vector <Eigen::Vector3d> spherical_projection;
pcl::PointCloud<pcl::PointXYZ>::Ptr newCloud(new pcl::PointCloud <pcl::PointXYZ>);
for (size_t pidx = 0; pidx < cloud->points.size(); ++pidx) {
pcl::PointXYZ currentPoint = cloud->points[pidx];
Eigen::Vector3d currentVector(currentPoint.x, currentPoint.y, currentPoint.z);
Eigen::Vector3d projected_point = currentVector - camera_location;
double norm = projected_point.norm();
if (norm == 0)
norm = 0.0001;
spherical_projection.push_back(
projected_point + 2 * (radius - norm) * projected_point / norm);
}
size_t origin_pidx = spherical_projection.size();
// add the last point, may be this is not necessary?
spherical_projection.push_back(Eigen::Vector3d(0, 0, 0));
/**
* This is just adding the points after performing spherical inversion to the newCloud
*/
for (std::size_t i = 0; i < spherical_projection.size(); ++i) {
Eigen::Vector3d currentVector = spherical_projection.at(i);
pcl::PointXYZ currentPoint(currentVector.x(), currentVector.y(), currentVector.z());
newCloud->push_back(currentPoint);
}
// Compute the convex hull, all the points that are in the convex hull are visible from C
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_hull(new pcl::PointCloud <pcl::PointXYZ>);
pcl::ConvexHull <pcl::PointXYZ> chull;
chull.setInputCloud(newCloud);
chull.reconstruct(*cloud_hull);//结果
参考链接:原文《Direct Visibility of Point Sets》