日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

pcl完整分割聚类流程

發布時間:2025/3/15 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 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完整分割聚类流程的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。