0.写在前面
由于扫描仪设备软件采集到的数据转化后是txt的,所以将它转成pcd,这里提供一种写法
1.主要思路
通过构造pcl::PointCloud的对象cloud,从txt的空间坐标中读取数据,对这个cloud中的每个点赋值。
2.main.cpp
#include <iostream>
#include <fstream>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <vector>
#include <string>
using namespace std;
typedef struct txtPoint_3D{
double x;
double y;
double z;
//double r;
}txtPoint_3D;
void GetFileNames(string path,vector<string>& filenames, string con);
void txt2pcd(string readPath, string savePath);
int main (int argc, char** argv)
{
if(argc != 3)
{
cerr<<"输入参数数量不对!"<<endl;
exit(1);
}
//输入输出路径
string input_dir = argv[1];
string output_dir = argv[2];
//输入输出格式
// string in_format = "scanf";
// string out_format = "scanf";
//获取文件
vector<string> filenames;
string con = ".txt";
GetFileNames(input_dir, filenames, con);
vector<string>::iterator it;
for (it=filenames.begin(); it!=filenames.end(); it++)
{
string tmp = *it;
string input_filename = input_dir + tmp + ".txt";
//string name = tmp.substr(0, tmp.find("."));//去除文件格式
string output_filename = output_dir + tmp + ".pcd";
cout<<"input_filename:"<<input_filename<<endl;
cout<<"output_filename:"<<output_filename<<endl;
txt2pcd(input_filename, output_filename);
}
//txt2pcd(input_filename, output_filename);
cout<<"点云格式转换完成"<<endl;
return (0);
}
void GetFileNames(string path,vector<string>& filenames, string con)
{
DIR *pDir;
struct dirent* ptr;
string filename, format, name;
if(!(pDir = opendir(path.c_str())))
return;
while((ptr = readdir(pDir))!=0) {
//跳过.和..文件
if(strcmp(ptr->d_name, ".") == 0 || strcmp(ptr->d_name, "..") == 0)
continue;
filename = ptr->d_name;
format = filename.substr(filename.find("."), filename.length());
name = filename.substr(0, filename.find("."));
//cout<<format<<endl;
//cout<<name<<endl;
if(format == con)//也可以添加对文件名的要求
filenames.push_back(name);
//filenames.push_back(filename);
}
closedir(pDir);
sort(filenames.begin(), filenames.end());
// sort(filenames.begin(), filenames.end(), [](string a, string b){
// return stoi(a) < stoi(b);
// });
}
void txt2pcd(string readPath, string savePath){
FILE *fp_txt;
txtPoint_3D txtPoint;
vector<txtPoint_3D> txtPoints;
fp_txt = fopen(readPath.c_str(),"r");
if (fp_txt == NULL){
cerr<<"open error!"<<endl;
}
while (fscanf(fp_txt, "%lf;%lf;%lf", &txtPoint.x, &txtPoint.y, &txtPoint.z) != EOF){
//cout<<txtPoint.x<<" "<<txtPoint.y<<" "<<txtPoint.z<<endl;
txtPoints.push_back(txtPoint);
}
//cout<<"cloud size:"<<txtPoints.size()<<endl;
pcl::PointCloud<pcl::PointXYZ> cloud;
cloud.width = txtPoints.size();
cloud.height = 1;
cloud.is_dense = false;
cloud.points.resize(cloud.width * cloud.height);
for (size_t i = 0; i < cloud.points.size(); ++i){
cloud.points[i].x = txtPoints[i].x;
cloud.points[i].y = txtPoints[i].y;
cloud.points[i].z = txtPoints[i].z;
}
pcl::io::savePCDFileASCII(savePath,cloud);
std::cout << "Saved " << cloud.points.size () << " data points" << std::endl;
}
3.CMakeList.txt
cmake_minimum_required(VERSION 2.8)
project(txt2pcd)
set( CMAKE_CXX_FLAGS "-std=c++11 -O3" )
# pcl
find_package( PCL REQUIRED )
include_directories( ${PCL_INCLUDE_DIRS} )
add_definitions( ${PCL_DEFINITIONS} )
list(REMOVE_ITEM PCL_LIBRARIES "vtkproj4")
add_executable(main "main.cpp")
target_link_libraries( main ${PCL_LIBRARIES} )
参考
https://pcl.readthedocs.io/projects/tutorials/en/latest/writing_pcd.html#writing-pcd