开发环境为win10+vstudio2019。
注:.txt形式的点云文件没有header,存储的全是xyz数据。如下图:
这个点云数据中不仅包含有x、y、z的位置信息,还包含其他的位置信息,因此我们只需要提取前三列的信息,并忽略前两行。提取后的数据如下图:
提取后的点云并完成可视化,可视化效果如下图:
源码如下:
extrat_txt.hpp
#include <iostream>
#include <vector>
#include <iomanip>
#include <fstream>
#include <sstream>
using namespace std;
class ExtraTXT
{
public:
void processing(string a,string b)
{
//从txt文件中获取指定列的内容
ifstream ifs;
ifs.open(a, ios::in);
if (!ifs.is_open())
{
cout << "打开文件失败!!!";
}
cout << "数据读取中" << endl;
vector<double> x, y, z;
vector<string> item;
string temp;
while (getline(ifs, temp))
{
item.push_back(temp);
}
for (auto it = item.begin() + 2; it != item.end(); it++)
{
istringstream istr(*it);
string str;
int count = 0;
while (istr >> str)
{
if (count == 0)
{
double r = atof(str.c_str());
x.push_back(r);
}
else if (count == 1)
{
double r = atof(str.c_str());
y.push_back(r);
}
else if (count == 2)
{
double r = atof(str.c_str());
z.push_back(r);
}
count++;
}
}
cout << "数据读取完成,正在生成新的txt文件" << endl;
ofstream ofs;
ofs.open(b, std::ios::out | std::ios::app);
for (int i = 0; i < x.size(); i++)
{
ofs << x[i] << " " << y[i] << " " << z[i] << endl;
}
ofs.close();
cout << "新的txt生成完成" << endl;
}
};
main.cpp:
#pragma warning(disable:4996)
#include "extrat_txt.hpp"
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include<pcl/visualization/cloud_viewer.h>
#include<boost/thread/thread.hpp>
using namespace std;
using namespace pcl;
typedef struct tagPOINT_3D
{
double x; //mm world coordinate x
double y; //mm world coordinate y
double z; //mm world coordinate z
double r;
}POINT_WORLD;
int main()
{
ExtraTXT extra_txt;
extra_txt.processing("未处理的txt/6.txt", "处理过的txt/6.txt");
//加载txt数据
int number_Txt;
FILE* fp_txt;
tagPOINT_3D TxtPoint;
vector<tagPOINT_3D> m_vTxtPoints;
fp_txt = fopen("处理过的txt/6.txt", "r");//这个地方填文件的位置
cout << "txt正在转换为pcd" << endl;
if (fp_txt)
{
while (fscanf(fp_txt, "%lf %lf %lf", &TxtPoint.x, &TxtPoint.y, &TxtPoint.z) != EOF)
{
m_vTxtPoints.push_back(TxtPoint);
}
}
else
cout << "txt数据加载失败!" << endl;
number_Txt = m_vTxtPoints.size();
pcl::PointCloud<pcl::PointXYZ> cloud;
// Fill in the cloud data
cloud.width = number_Txt;
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 = m_vTxtPoints[i].x;
cloud.points[i].y = m_vTxtPoints[i].y;
cloud.points[i].z = m_vTxtPoints[i].z;
}
pcl::io::savePCDFileASCII("pcd/6.pcd", cloud);//这个地方填输出的路径
std::cerr << "Saved " << cloud.points.size() << " data points to txt2pcd.pcd." << std::endl;
cout << "txt转换pcd完成" << endl;
//将pcl::PointCloud转换为pcl::PointCloud::Ptr类型
pcl::PointCloud<pcl::PointXYZ>::Ptr cloudPointer(new pcl::PointCloud < pcl::PointXYZ>);
cloudPointer = cloud.makeShared();
boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer(new pcl::visualization::PCLVisualizer("cloud viewer"));
viewer->setBackgroundColor(0, 0, 0);
viewer->addPointCloud<pcl::PointXYZ>(cloudPointer, "sample cloud");
viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 0.5, "sample cloud");
viewer->addCoordinateSystem(1.0);
viewer->initCameraParameters();
while (!viewer->wasStopped()) {
viewer->spinOnce(100);
boost::this_thread::sleep(boost::posix_time::microseconds(100000));
}
system("pause");
return 0;
}
需注意:
加了ptr的是指针类型,两者可以相互转换,在上边可视化的过程中需要先将pcl::PointCloud转换为pcl::PointCloud::Ptr,所以总结以下的转换代码
(1)pcl::PointCloud转换为pcl::PointCloud::Ptr
//将pcl::PointCloud转换为pcl::PointCloud::Ptr类型
pcl::PointCloud<pcl::PointXYZ> cloud;
pcl::PointCloud<pcl::PointXYZ>::Ptr cloudPointer(new pcl::PointCloud < pcl::PointXYZ>);
cloudPointer = cloud.makeShared();
(2)pcl::PointCloud::Ptr转换为pcl::PointCloud
pcl::PointCloud<pcl::PointXYZ> cloud;
pcl::PointCloud<pcl::PointXYZ>::Ptr cloudPointer(new pcl::PointCloud<pcl::PointXYZ>);
cloud=*cloudPointer;