PCL点云曲面重采样三种方法:上采样,下采样,均匀采样
(1)下采樣? Downsampling
一般下采樣是通過構(gòu)造一個(gè)三維體素柵格,然后在每個(gè)體素內(nèi)用體素內(nèi)的所有點(diǎn)的重心近似顯示體素中的其他點(diǎn),這樣體素內(nèi)所有點(diǎn)就用一個(gè)重心點(diǎn)來表示,進(jìn)行下采樣的來達(dá)到濾波的效果,這樣就大大的減少了數(shù)據(jù)量,特別是在配準(zhǔn),曲面重建等工作之前作為預(yù)處理,可以很好的提高程序的運(yùn)行速度,
#include <pcl/io/pcd_io.h> #include <pcl/filters/voxel_grid.h>int main(int argc, char** argv) {// 創(chuàng)建點(diǎn)云對(duì)象pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);pcl::PointCloud<pcl::PointXYZ>::Ptr filteredCloud(new pcl::PointCloud<pcl::PointXYZ>);// 讀取PCD文件if (pcl::io::loadPCDFile<pcl::PointXYZ>(argv[1], *cloud) != 0){return -1;}// 創(chuàng)建濾波對(duì)象pcl::VoxelGrid<pcl::PointXYZ> filter;filter.setInputCloud(cloud);// 設(shè)置體素柵格的大小為 1x1x1cmfilter.setLeafSize(0.01f, 0.01f, 0.01f);filter.filter(*filteredCloud); }實(shí)驗(yàn)結(jié)果(略)
(2)
均勻采樣:這個(gè)類基本上是相同的,但它輸出的點(diǎn)云索引是選擇的關(guān)鍵點(diǎn)在計(jì)算描述子的常見方式。
#include <pcl/io/pcd_io.h> #include <pcl/keypoints/uniform_sampling.h>int main(int argc, char** argv) {pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);pcl::PointCloud<pcl::PointXYZ>::Ptr filteredCloud(new pcl::PointCloud<pcl::PointXYZ>);if (pcl::io::loadPCDFile<pcl::PointXYZ>(argv[1], *cloud) != 0){return -1;}// Uniform sampling object.pcl::UniformSampling<pcl::PointXYZ> filter;filter.setInputCloud(cloud);filter.setRadiusSearch(0.01f);// We need an additional object to store the indices of surviving points.pcl::PointCloud<int> keypointIndices;filter.compute(keypointIndices);pcl::copyPointCloud(*cloud, keypointIndices.points, *filteredCloud); }(3)增采樣 :增采樣是一種表面重建方法,當(dāng)你有比你想象的要少的點(diǎn)云數(shù)據(jù)時(shí),增采樣可以幫你恢復(fù)原有的表面(S),通過內(nèi)插你目前擁有的點(diǎn)云數(shù)據(jù),這是一個(gè)復(fù)雜的猜想假設(shè)的過程。所以構(gòu)建的結(jié)果不會(huì)百分之一百準(zhǔn)確,但有時(shí)它是一種可選擇的方案。所以,在你的點(diǎn)云云進(jìn)行下采樣時(shí),一定要保存一份原始數(shù)據(jù)!
#include <pcl/io/pcd_io.h> #include <pcl/surface/mls.h>int main(int argc,char** argv) { // 新建點(diǎn)云存儲(chǔ)對(duì)象 pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>); pcl::PointCloud<pcl::PointXYZ>::Ptr filteredCloud(new pcl::PointCloud<pcl::PointXYZ>);// 讀取文件if (pcl::io::loadPCDFile<pcl::PointXYZ>(argv[1], *cloud) != 0){return -1;}// 濾波對(duì)象pcl::MovingLeastSquares<pcl::PointXYZ, pcl::PointXYZ> filter;filter.setInputCloud(cloud);//建立搜索對(duì)象pcl::search::KdTree<pcl::PointXYZ>::Ptr kdtree;filter.setSearchMethod(kdtree);//設(shè)置搜索鄰域的半徑為3cmfilter.setSearchRadius(0.03);// Upsampling 采樣的方法有 DISTINCT_CLOUD, RANDOM_UNIFORM_DENSITYfilter.setUpsamplingMethod(pcl::MovingLeastSquares<pcl::PointXYZ, pcl::PointXYZ>::SAMPLE_LOCAL_PLANE);// 采樣的半徑是filter.setUpsamplingRadius(0.03);// 采樣步數(shù)的大小filter.setUpsamplingStepSize(0.02);filter.process(*filteredCloud); }實(shí)驗(yàn)的結(jié)果
原始圖像可視化:
?
(4)表面重建
深度傳感器的測(cè)量是不準(zhǔn)確的,和由此產(chǎn)生的點(diǎn)云也是存在的測(cè)量誤差,比如離群點(diǎn),孔等表面,可以用一個(gè)算法重建表面,遍歷所有的點(diǎn)云和插值數(shù)據(jù),試圖重建原來的表面。比如增采樣,PCL使用MLS算法和類。執(zhí)行這一步是很重要的,因?yàn)橛纱水a(chǎn)生的點(diǎn)云的法線將更準(zhǔn)確。
#include <pcl/io/pcd_io.h> #include <pcl/surface/mls.h> #include <pcl/visualization/pcl_visualizer.h> #include <pcl/visualization/cloud_viewer.h> #include <boost/thread/thread.hpp> int main(int argc, char** argv) {pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>); pcl::PointCloud<pcl::PointNormal>::Ptr smoothedCloud(new pcl::PointCloud<pcl::PointNormal>);if (pcl::io::loadPCDFile<pcl::PointXYZ>(argv[1], *cloud) != 0){return -1;}// Smoothing object (we choose what point types we want as input and output).pcl::MovingLeastSquares<pcl::PointXYZ, pcl::PointNormal> filter;filter.setInputCloud(cloud);// Use all neighbors in a radius of 3cm.filter.setSearchRadius(0.03);// If true, the surface and normal are approximated using a polynomial estimation// (if false, only a tangent one).filter.setPolynomialFit(true);// We can tell the algorithm to also compute smoothed normals (optional).filter.setComputeNormals(true);// kd-tree object for performing searches.pcl::search::KdTree<pcl::PointXYZ>::Ptr kdtree;filter.setSearchMethod(kdtree);filter.process(*smoothedCloud);boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer(new pcl::visualization::PCLVisualizer("smooth")); viewer->addPointCloud<pcl::PointNormal>(smoothedCloud,"smoothed");while(!viewer->wasStopped()){viewer->spinOnce(100); boost::this_thread::sleep(boost::posix_time::microseconds(1000000));} }運(yùn)行即可查看結(jié)果
?????????????????????????????????????????????????????????????? 原始圖像(加了顏色)
???????????????????????????????????????????? 增采樣平滑后(沒有顏色信息)
?
《新程序員》:云原生和全面數(shù)字化實(shí)踐50位技術(shù)專家共同創(chuàng)作,文字、視頻、音頻交互閱讀總結(jié)
以上是生活随笔為你收集整理的PCL点云曲面重采样三种方法:上采样,下采样,均匀采样的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Matlab读取点云数据显示
- 下一篇: MATLAB点云处理:读取、展示、最近邻