1. 程式人生 > >pcl點雲的一些學習認識

pcl點雲的一些學習認識

博主最近在做三維重建,之前就瞭解過pcl庫,俗話說,二維處理靠opencv,三維處理靠pcl,那麼這個點雲庫到底有什麼神奇功能呢?博主才疏學淺,現在就學瞭如何將三維點顯示和一些簡單的濾波,在這裡,對自己,也是對廣大初學者都可以做個複習和簡單的介紹。

首先如何將已有的三維點顯示,博主這裡是利用深度相機直接測得的深度,幀之間通過icp獲得世界座標系下的空間位姿,在這裡,我們簡單來看從深度照片中提取點雲。

pcl::pointcloud<pcl::pointxyzrgb>::ptr pointcloud(new pcl::pointcloud<pcl::pointxyzrgb>);
//opencv提取點雲
Mat color=imread("your adress");
Mat depth=imread("your adress",-1);
//遍歷畫素,還原深度和三維點
for(int v=0;v<color.rows;v++)
 for(int u=0;u<color.cols;u++)
  {
     ushort d=depth.ptr<unsigned short>(v)[u];
     //還原三維點
    Point3d world;
    world.z=double(d)/1000.0;
    world.x=(u-cx)/fx*world.z;
    world.y=(v-cy)/fy*world.z;
    //定義點雲型別(博主手碼,類函式裡面一些大小寫就不區分了,大家自己寫應該一眼就看得出)
    pcl::xyzrgb pc;
    pc.x=world.x;
    pc.y=world.y;
    pc.z=world.z;
    pc.b=color.data[v*color.step+u*color.channels()];
    pc.g=color.data[v*color.step+u*color.channels()+1];
    pc.r=color.data[v*color.step+u*color.channels()+2];
    pointcloud->push_back(pc);
  }
//好了,至此你已經將照片上的畫素點都新增到點雲了,注意了,博主自己碼的,所以類的名稱大小寫應該都是錯的(QAQ),見諒。
pointcloud->is_dense=false;
//將照片儲存
pcl::io::savepcdfilebinary("map.pcd",*pointcloud);

博主其實不懶,上面的程式碼大家將就看吧,對不起大家啊,不能複製黏貼哈哈。

好了,下面介紹兩種常見的濾波,統計濾波和體素濾波,博主學的不深,簡單來說,統計濾波是將空間上的點聚類,感覺是不是類似kmeans啊哈哈,然後去除孤立的點,一般用來去除帶噪聲的資料,而體素濾波是將一個很小空間上的點裡面很多個點算它們的質心,博主感覺是用來消除重投影誤差的把,意思是可能一個點被不同觀測重新還原到了有些誤差的不同位置,這樣可以是整個空間更加趨於平滑,也為以後的稠密重建做好了準備。

廢話不多說,博主懶了,直接上程式碼了,大家講究看吧,實在不好意思了。

  //統計濾波,存放點雲
	  pointcloud::Ptr currentstatistical(new pointcloud);
	  //定義統計濾波類
	  pcl::StatisticalOutlierRemoval<pcl::PointXYZRGB> statistical_filter;
	  statistical_filter.setMeanK(50);
	  statistical_filter.setStddevMulThresh(1.0);
	  statistical_filter.setInputCloud(currentpoint);
	  statistical_filter.filter(*currentstatistical);
	  (*pointcloud_ptr)=(*pointcloud_ptr)+(*currentstatistical);

這是統計濾波,大家應該看得懂吧

pcl::VoxelGrid<pcl::PointXYZRGB> voxel_filter;
  //設定最小單位
  voxel_filter.setLeafSize(0.01,0.01,0.01);
  voxel_filter.setInputCloud(pointcloud_ptr);
  //定義點雲型別存放濾波後的
  pcl::PointCloud<pcl::PointXYZRGB>::Ptr current_voxelpoint;
  voxel_filter.filter(*current_voxelpoint);
  current_voxelpoint->swap(*pointcloud_ptr);

這是體素濾波,估計問題不大對應各位來說

各位再見