PCL视椎体裁剪滤波(frustum_culling)

PCL专栏目录及须知-CSDN博客

1.原理

本示例会设计到三维相关的东西,如果不大知道视椎体、透视矩阵这些概念,可以在这个网站上了解一下:learnOpenGL

具体原理

(1)声明一个相机,并设置相机的各个参数。

(2)通过点云是否在相机视椎体内部进行点云裁剪;得到结果点云。

视椎体滤波

所谓视椎体滤波,就是使用相机的视椎体去对点云进行裁剪。即对于你所设置相机的“所见即所得”,裁剪出来相机透视矩阵看到的点云,滤掉剩余的点云。

如下图:

红色为视椎体,视椎体滤波即裁剪得到视椎体中的点云(即红色框中的部分)

视椎体简介

近裁剪面:距离相机较近的裁剪面(相机最近能看到的地方)

远裁剪面:距离相机较远的裁剪面(相机最远能看到的地方)

注:相机只保留远近裁剪面之间的内容,其他内容都会被删除

视椎体水平角度:视椎体水平方向上的夹角(决定视椎体水平方向上能看多大范围)

视椎体垂直角度:视椎体垂直方向上的夹角(决定视椎体垂直方向上能看多大范围)

2.使用场景

实际工作中使用较少,因为PCL一般都是做点云后处理的,这种方法一般都用在双目视觉处理点云的情况中。

3.注意事项

4.关键函数

(1)设置相机视椎体的参数

1)设置视椎体垂直视角范围

setVerticalFOV()

2)设置视椎体水平视角范围

setHorizontalFOV()

3)设置视椎体近裁剪面

setNearPlaneDistance()

4)设置视椎体远裁剪面

setFarPlaneDistance()

(2)设置相机的位姿

setCameraPose()

5.代码

#include <iostream>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/search/kdtree.h>
#include <boost/thread/thread.hpp>
#include <pcl/filters/frustum_culling.h>
#include <pcl/visualization/pcl_visualizer.h>

int main()
{
    /****************视椎体滤波********************/
    // 原始点云
    pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZRGB>);
    pcl::io::loadPCDFile("D:/code/csdn/data/Sphere.pcd", *cloud);   // 加载原始点云数据
    // 结果点云
    pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud_filtered(new pcl::PointCloud<pcl::PointXYZRGB>);

    // 视椎体滤波
    pcl::FrustumCulling<pcl::PointXYZRGB> filters;
    filters.setInputCloud(cloud);
    filters.setVerticalFOV(70.4);                                               // 设置垂直视角范围
    filters.setHorizontalFOV(77.2);                                             // 设置水平视角范围
    filters.setNearPlaneDistance(0);                                            // 近裁剪面
    filters.setFarPlaneDistance(500);                                           // 远裁剪面
    Eigen::Matrix4f camera_pos;                                                 // 相机位姿矩阵(测试相机位于原点,实际操作时将相机矩阵传入该位置)
    camera_pos << 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1; 
    filters.setCameraPose(camera_pos);                                          // 设置相机
    filters.filter(*cloud_filtered);

    /****************展示********************/
    boost::shared_ptr<pcl::visualization::PCLVisualizer> view_raw(new pcl::visualization::PCLVisualizer("raw"));
    pcl::visualization::PointCloudColorHandlerRGBField<pcl::PointXYZRGB> raw_rgb(cloud);
    view_raw->addPointCloud<pcl::PointXYZRGB>(cloud, raw_rgb, "raw cloud");
    view_raw->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 1, "raw cloud");

    boost::shared_ptr<pcl::visualization::PCLVisualizer> view_filtered(new pcl::visualization::PCLVisualizer("filter"));
    pcl::visualization::PointCloudColorHandlerRGBField<pcl::PointXYZRGB> filtered_rgb(cloud);
    view_filtered->addPointCloud<pcl::PointXYZRGB>(cloud_filtered, filtered_rgb, "filtered cloud");
    view_filtered->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 1, "filtered cloud");

    while (!view_raw->wasStopped())
    {
        view_raw->spinOnce(100);
        boost::this_thread::sleep(boost::posix_time::microseconds(100000));
    }
    while (!view_filtered->wasStopped())
    {
        view_filtered->spinOnce(100);
        boost::this_thread::sleep(boost::posix_time::microseconds(100000));
    }

    return 0;
}

6.结果展示

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值