遮挡检测--HPR:hidden point remove

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(Rpi)pipi
直观地说,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》

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值