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
#include
#include
#include
#include //导入ModelCoefficients(模型系数)结构
#include //导入ProjectInliers滤波器
#include
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;
}