pcl完整分割聚类流程
前言
在接觸了pcl庫三天后,根據一篇博客https://blog.csdn.net/ys578676728/article/details/104657262實現了自己的分離出人體的點云。參考的博客中,實現將一個人的點云信息分割出來。在今天參考該博客的流程,實現對場景中的五個人的點云圖進行分割。這個流程可以作為pcl基礎學習的一個流程。
效果
每次看別人的博客都喜歡看別人實現了什么效果,總是拉到頁面最下面,所以先把效果貼出來,提起興趣再看流程和代碼,圖會比較多,耐心看。
左圖為拿到的原圖,右圖為分割出來的五個人
對于人物來說,同樣可以單獨的分割出每個人:下圖中每個人都可以單獨的分離出,當然最后一個是兩個人聚類時,連在了一起,忽略這細節,感受其中的牛X(大佬勿噴),請讓小白驕傲一會。
流程
看完了效果,將實現該效果的流程先在這里說一下,后面具體到每個流程:
- 讀入pcd點云;
-
- 搜一搜,應該比較容易
- 濾波操作
-
- 這里用的是體素濾波器,具體原因,你懂得,作為一下小白怎么可能知道
- 利用SAC分割算法
-
- 利用該算法,將點云中的平面,比如地面等,給去除;這一步中可以得到去除的平面和剩余的點云
- 采用歐式聚類分割算法,實現最終的效果
-
- 同樣的我也不知道原理,今天只是跑通一個流程。
詳細步驟
首先,對于小白想要復現,有個頭疼的問題,不知道你們有沒有,反正我有,為了解決和我有一樣頭疼地方的人,先說一下,不知道引入那個頭文件的問題,哈哈哈哈。
引入頭文件
#include <iostream> #include <pcl/point_cloud.h> #include <pcl/point_types.h> #include <pcl/io/pcd_io.h> #include <pcl/visualization/pcl_visualizer.h> #include <pcl/filters/voxel_grid.h> #include <pcl/filters/approximate_voxel_grid.h> #include <pcl/filters/voxel_grid.h> #include <pcl/common/transforms.h> #include <pcl/segmentation/sac_segmentation.h> #include <pcl/filters/extract_indices.h> #include <pcl/search/kdtree.h> #include <pcl/segmentation/extract_clusters.h>讀入文件
//讀取pcd文件string pcdPath = "F:/3dDataSets/pcdFiles/five_people.pcd";pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);pcl::PCDWriter writer;if (pcl::io::loadPCDFile(pcdPath.c_str(), *cloud) < 0){cout << "load PCD failure" << endl;}體素濾波器實現降采樣
小白再問怎么還有transform啊!我這對降采樣的點云的進行一個平移,這樣在顯示時效果比較直觀。
//采用體素濾波器來實現降采樣pcl::PointCloud<pcl::PointXYZ>::Ptr cloudFilterVoxelGrid(new pcl::PointCloud<pcl::PointXYZ>);//pcl::ApproximateVoxelGrid<pcl::PointXYZ> sor;pcl::VoxelGrid<pcl::PointXYZ> sor;sor.setInputCloud(cloud);sor.setLeafSize(0.05f,0.05f,0.05f);sor.filter(*cloudFilterVoxelGrid);Eigen::Affine3f transformM = Eigen::Affine3f::Identity();transformM.translation() << 5.0, 0.0, 0.0;transformM.rotate(Eigen::AngleAxisf(0.0,Eigen::Vector3f::UnitZ()));pcl::PointCloud<pcl::PointXYZ>::Ptr pingyi(new pcl::PointCloud<pcl::PointXYZ>);pcl::transformPointCloud(*cloudFilterVoxelGrid,*pingyi,transformM);SAC分割點云,去除平面
小白再問,怎么都是代碼也沒個注釋和講解,水平有限,后續會把我的學習過程分享一樣。這里姑且先跑一跑流程,裝一下。
pcl::ModelCoefficients::Ptr coefficients(new pcl::ModelCoefficients);pcl::PointIndices::Ptr inliners(new pcl::PointIndices);pcl::SACSegmentation<pcl::PointXYZ> sac;sac.setOptimizeCoefficients(true);sac.setModelType(pcl::SACMODEL_PLANE);sac.setMethodType(pcl::SAC_RANSAC);sac.setDistanceThreshold(0.1);sac.setMaxIterations(500);int i = 0, nr_points = (int)pingyi->points.size();pcl::PointCloud<pcl::PointXYZ>::Ptr cloudPlane(new pcl::PointCloud<pcl::PointXYZ>), cloudT(new pcl::PointCloud<pcl::PointXYZ>);while(pingyi->points.size() > 0.7 * nr_points){sac.setInputCloud(pingyi);sac.segment(*inliners, *coefficients);if (inliners->indices.size() == 0){cout << "could not remove " << endl;break;}pcl::ExtractIndices<pcl::PointXYZ> extract;extract.setInputCloud(pingyi);extract.setIndices(inliners);extract.setNegative(false);extract.filter(*cloudPlane);extract.setNegative(true);extract.filter(*cloudT);writer.write<pcl::PointXYZ>("./temp/cloudPlane" + to_string(i) + ".pcd", *cloudPlane, false);writer.write<pcl::PointXYZ>("./temp/cloudfilter" + to_string(i) + ".pcd", *cloudT, false);i++;*pingyi = *cloudT;}歐式距離聚類分割
pcl::search::KdTree<pcl::PointXYZ>::Ptr tree(new pcl::search::KdTree<pcl::PointXYZ>);tree->setInputCloud(pingyi);std::vector<pcl::PointIndices> clusterIndices;pcl::EuclideanClusterExtraction<pcl::PointXYZ> ec;ec.setClusterTolerance(0.1);ec.setMinClusterSize(100);ec.setMaxClusterSize(25000);ec.setSearchMethod(tree);ec.setInputCloud(pingyi);ec.extract(clusterIndices);int j = 0;for (std::vector<pcl::PointIndices>::const_iterator it = clusterIndices.begin();it!=clusterIndices.end();++it){pcl::PointCloud<pcl::PointXYZ>::Ptr cloudCluster(new pcl::PointCloud<pcl::PointXYZ>);for (std::vector<int>::const_iterator pit = it->indices.begin();pit != it->indices.end();++pit){cloudCluster->points.push_back(pingyi->points[*pit]);}cloudCluster->width = cloudCluster->points.size();cloudCluster->height = 1;cloudCluster->is_dense = true;writer.write<pcl::PointXYZ>("cluster"+to_string(j++)+".pcd",*cloudCluster,false);}復現
對3d點云感興趣,想跑一跑的,肯定就會本小白,“您好,那個點云文件你可以發一下”或者“您好,有源代碼文件文件嗎?”。這里把點云的文件放在資源中,至于源代碼,上述的源碼是完全銜接的,沒有漏裁。
點云:https://download.csdn.net/download/qq_25105061/21018535,在csdn直接搜索five_people.pcd就可以下載了,不要幣的。
總結
以上是生活随笔為你收集整理的pcl完整分割聚类流程的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 随机信号知识点总结
- 下一篇: MATLAB在通信系统仿真中的注意