PCL PLY轉PCD及批量處理

       學習點雲庫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();




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章