學習點雲庫PCL過程中,總會遇到數據格式轉換,流行的3D數據基準庫 大都是ply格式的,並且是二進制格式,ply在PCL庫中是可以處理的,但是更好的做其他處理,我一般都先把ply轉pcd,方便的以後處理,格式轉爲ascii的,這樣就可以用txt ultraedit打開 其數據是可看到的。
ply 一般有兩種格式 頭文件處理VCGLIB生成 的ply 用簡單的程序ply->pcd 就可以轉化pcd,VTK 生成的 則 ply->vtk->pcd, 程序如下:
* 兩種格式都能處理
//pcd文件顯示
pcl::PointCloud<pcl::PointXYZRGBA>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZRGBA>());
//pcl::io::loadPCDFile("model1.pcd",*cloud);
//ply文件顯示
pcl::PolygonMesh mesh;
vtkSmartPointer<vtkPolyData> polydata = vtkSmartPointer<vtkPolyData>::New();
pcl::io::loadPolygonFilePLY("mario/Scene1.ply", mesh);
// ply另存vtk
//pcl::io::saveVTKFile("temp.vtk", mesh);
pcl::io::mesh2vtk(mesh, polydata);
pcl::io::vtkPolyDataToPointCloud(polydata, *cloud);
//兩種存貯方式 pcd另存pcd
pcl::PCDWriter pcdwriter;
//pcdwriter.write<pcl::PointXYZRGBA>("save_ply2vtk2pcd.pcd", *cloud);
pcl::io::savePCDFileASCII("mario/Scene11.pcd", *cloud);
*/
/*VCGLIB生成 的ply
pcl::PCLPointCloud2 clod;
pcl::io::loadPLYFile("mario/Scene1.ply", clod);
pcl::io::savePCDFile("mario/Scene111.pcd", clod);
*/
/*VCGLIB生成 的ply
pcl::PCLPointCloud2 clod;
pcl::PLYReader reader;
reader.read("mario/Scene1.ply", clod);
pcl::PCDWriter writer;
writer.writeASCII("mario/Scene1111.pcd", clod); writeBinary
*/
ply 的數據 一般都是 點屬性:xyzrgba
邊屬性:索引值
由於pcd的顏色編碼不同,程序吧ply轉出pcd後,顏色值四通道 變成一個值,以上三種轉法,會把ply的rgba數據 轉化 很大的一個數 幾千萬 真的,我當時也蒙了,難道說顏色丟失了 沒有轉換過了,但是想到去年的時候,確實顏色也轉過來了,我就用顯示pcl viewer 來看顏色是否轉過來了。
pcl::PointCloud<pcl::PointXYZRGBA>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZRGBA>());
pcl::io::loadPCDFile("mario/Scene1111.pcd", *cloud);
boost::shared_ptr<pcl::visualization::PCLVisualizer> viewe(new pcl::visualization::PCLVisualizer("ss"));
viewe->initCameraParameters();
viewe->setBackgroundColor(0.3,0.3,0.3);
viewe->addCoordinateSystem(1.0f);
pcl::visualization::PointCloudColorHandlerRGBField<pcl::PointXYZRGBA> color(cloud);
viewe->addPointCloud<pcl::PointXYZRGBA>(cloud, color, "cloud");
viewe->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_FONT_SIZE, 3, "cloud");
while (!viewe->wasStopped()) {
viewe->spinOnce(100);
boost::this_thread::sleep(boost::posix_time::microseconds(100000));
}
有個坑 就是pcl::visualization::PointCloudColorHandlerRGBField<pcl::PointXYZRGBA> color(cloud);PointCloudColorHandlerRGBField 一定不能寫成 RGBAField,儘管pcd是PointXYZRGBA格式的,這樣才能完全顯示顏色 保真
以上便是轉換代碼,下面是對所有PLY格式的文件進行批量處理的程序:第一種
stringstream 名字要整齊一致
stringstream ss_tou;
ss_tou<<"E://datasets//SHOT//dataset4 kinect cvlab//3D models scenes//CVLab//xx//"; // 最後一定要zai加個 //
for (int i = 1; i<24; i++)
{
stringstream ss;
ss<<ss_tou.str()<<i<<".ply";
第二種 把所有ply放到一個data文件下,在定義一個txt,存放個ply的相對路徑,這種方法不對名字做要求pcl::PointCloud<pcl::PointXYZRGBA>::Ptr clud(new pcl::PointCloud<pcl::PointXYZRGBA>());
//pcl::io::loadPCDFile("model1.pcd",*cloud);
//修改後綴名 路徑不變
std::string file = "standford/mario_object_templates.txt";
std::ifstream input(file);
std::string ply_file, pcd_file;
while (input.good()) //判斷文件是否結束
{
std::getline(input, ply_file);
std::string::size_type pos = ply_file.rfind("ply"); // 雙字符
if (ply_file.empty() || ply_file.at(0) =='#' )
continue;
pcl::PolygonMesh mesh;
vtkSmartPointer<vtkPolyData> polydata = vtkSmartPointer<vtkPolyData>::New();
pcl::io::loadPolygonFilePLY(ply_file, mesh);
pcl::io::mesh2vtk(mesh, polydata);
pcl::io::vtkPolyDataToPointCloud(polydata, *clud);
pcd_file = ply_file;
if (pos != std::string::npos) //npos就是到頭了
pcd_file.replace(pos, 3, "pcd"); // 雙字符
pcl::io::savePCDFile(pcd_file, *clud);
}
input.close();