PCL滤波--参数化模型投影点云---三维点云投影到二维平面

PCL点云滤波模块,有一种方法叫做参数化模型投影点云滤波,意思就是创建一个参数化模型(可以是平面,球体,椎体等),然后将点云投影到上面,比如说如果投影到平面上,那么就实现了三维降到二维,滤掉了一个维度,也勉强算是滤波吧。
掌握了这种方法感觉一下子掌握了宇宙中最强大的能力之一:降维打击!
以后看哪个模型不顺眼就拍扁它,哈哈哈~
进入正题,虽然感觉牛逼轰轰但是原理很简单,比如我把点云的z方向坐标全都设置为0,那么就实现了向X-Y平面的投影

    pcl::ModelCoefficients::Ptr coefficients(new pcl::ModelCoefficients());
    coefficients->values.resize(4);
    coefficients->values[0] = 0;
    coefficients->values[1] = 0;
    coefficients->values[2] = 1;
    coefficients->values[3] = 0;
proj.setModelType(pcl::SACMODEL_PLANE);   //创建投影类型,投影到平面上

这里可以设置投影类型,除了平面还可以设置锥体,球体,柱体等(SACMODEL_CYLINDER,SACMODEL_SPHERE,SACMODEL_CYLINDER,SACMODEL_CONE等),参见采样一致性参数化模型添加链接描述
更改了投影模型之后,每个类型的投影参数都不一样,有的是四个参数比如平面和球体,有的是7个参数,比如柱体和锥体。
如果用SACMODEL_CONE,那么可以设置参数如下:

    pcl::ModelCoefficients::Ptr coefficients(new pcl::ModelCoefficients());
    coefficients->values.resize(7);
    coefficients->values[0] = 0.3;
    coefficients->values[1] = 0.3;
    coefficients->values[2] = 0;
    coefficients->values[3] = 0;
    coefficients->values[4] = 0.5;
    coefficients->values[5] = 0;
    coefficients->values[6] = 5;

在这里插入图片描述
在这里插入图片描述
这样我们就成功拍扁了前女友(假装这是前女友)~
在这里插入图片描述
用SACMODEL_CONE模型甚至可以拍得不成人样~

#include <iostream>
#include <pcl/io/pcd_io.h>
#include <pcl/io/ply_io.h>
#include <pcl/point_types.h>
#include <pcl/ModelCoefficients.h>          //导入ModelCoefficients(模型系数)结构
#include <pcl/filters/project_inliers.h>        //导入ProjectInliers滤波器
#include <pcl/visualization/cloud_viewer.h>

int main(int argc, char** argv)
{
    pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZRGB>);
    pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud_projected(new pcl::PointCloud<pcl::PointXYZRGB>);


    if (pcl::io::loadPLYFile("C:\\Users\\fhlhc\\Desktop\\p.ply", *cloud) == -1)
            return (-1);

        //输出投影前点云坐标
    //std::cerr << "Cloud before projection: " << std::endl;
    //for (std::size_t i = 0; i < cloud->points.size(); ++i)
    //    std::cerr << "    " << cloud->points[i].x << " "
    //    << cloud->points[i].y << " "
    //    << cloud->points[i].z << std::endl;

    // 我们使用一个平面模型ax + by + cz + d = 0,其中a,b,c,d分别对应下面四个通道,对值为1的维度进行降维打击,或者换句话说,假如a = b = d = 0,c = 1,则投影到XY平面
        //或者可以这么理解,画个坐标系把上面方程画出来,假如a = b =1,c = d=0,方程为x=-y,意味着投影在x=-y的平面上。
    pcl::ModelCoefficients::Ptr coefficients(new pcl::ModelCoefficients());
    coefficients->values.resize(4);
    coefficients->values[0] = 0;
    coefficients->values[1] = 1;
    coefficients->values[2] = 0;
    coefficients->values[3] = 0;
   

    // Create the filtering object
    pcl::ProjectInliers<pcl::PointXYZRGB> proj;
    proj.setModelType(pcl::SACMODEL_PLANE);   //创建投影类型,投影到平面上
    proj.setInputCloud(cloud);
    proj.setModelCoefficients(coefficients);
    proj.filter(*cloud_projected);

    //输出投影后点云坐标
    //std::cerr << "Cloud after projection: " << std::endl;
    //for (std::size_t i = 0; i < cloud_projected->points.size(); ++i)
    //    std::cerr << "    " << cloud_projected->points[i].x << " "
    //    << cloud_projected->points[i].y << " "
    //    << cloud_projected->points[i].z << std::endl;

    //双视口显示
    boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer(new pcl::visualization::PCLVisualizer("test Viewer"));
    viewer->initCameraParameters();
    int v1(0), v2(0);
    //原始点云窗口
    viewer->createViewPort(0.0, 0.0, 0.5, 1.0, v1);
    viewer->setBackgroundColor(0, 0, 0, v1);
    viewer->addText("original", 10, 10, "v1 text", v1);
    viewer->addPointCloud<pcl::PointXYZRGB>(cloud, "sample cloud1", v1);
    viewer->addCoordinateSystem(1.0);
    viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 2, "sample cloud1");
    //滤波窗口
    viewer->createViewPort(0.5, 0.0, 1.0, 1.0, v2);
    viewer->setBackgroundColor(0, 0, 0, v2);
    viewer->addText("cloud_projected", 10, 10, "v2 text", v2);
    viewer->addPointCloud<pcl::PointXYZRGB>(cloud_projected, "sample cloud2", v2);
    viewer->addCoordinateSystem(1.0);
    viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 2, "sample cloud2");
    while (!viewer->wasStopped())
    {
        viewer->spinOnce(100);  //刷新
        boost::this_thread::sleep(boost::posix_time::microseconds(100000));
    }
    system("pause");
    return 0;
}




  • 11
    点赞
  • 48
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 6
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

滑了丝的螺丝钉

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值