pcl 读取ASCII文件

本文介绍了一段用于读取ASCII格式的点云数据,包含RGB信息的C++代码。在处理过程中遇到了bug,但已成功调试。代码使用PCL库,并通过std::stringstream解析每一行数据,将x,y,z,r,g,b,scale,intensity转换为点云对象。最终,代码可以将读取的数据转换为PCL点云并保存为PCD文件,供进一步处理或可视化。
摘要由CSDN通过智能技术生成

哼唧,最近做一个相机激光雷达标定的大作业,点云数据是ASCII格式的,网上找到了读取代码,但是有点bug,虽然被我de下去了,emmm,但是挺费事,de了快一上午,不敢想啊。

文件格式

依次是x,y,z,r,g,b,scale,intensity

读取代码

参考:PCL读取带rgb信息的asc文件C++_pcl支持asc文件吗_一行风的博客-CSDN博客

 类定义:

#include <iostream>
#include <pcl/point_cloud.h> // for PointCloud
#include <pcl/point_types.h>
#include <fstream>
#include <string>
#include <sstream>
#include <vector>
#include <string>
template <class PointT>
class read_ascii_rgb {
private:
	std::string file_name;
	using PointCloudPtr = typename pcl::PointCloud<PointT>::Ptr;
	PointCloudPtr cloud;
public:
	read_ascii_rgb(const std::string file_path) {
		file_name = file_path;
		cloud = PointCloudPtr(new pcl::PointCloud<PointT>);
	}
	PointCloudPtr read() {
		std::stringstream ss;
		std::vector<PointT> v;
		std::ifstream ifs(file_name);
		std::string buffer;
		if (!ifs) {
			std::cout << "Open file fail at" << file_name << std::endl;
			exit(1);
		}
		int i_output = 0;
		while (std::getline(ifs, buffer)) {
			PointT tmp;
			ss.clear();
			ss.str(buffer);
			// ss << buffer;
			unsigned r, g, b;
			double scale, intensity;
			ss >> tmp.x >> tmp.y >> tmp.z >> r >> g >> b >> scale >> intensity;
			// tmp.intensity = intensity;
			// if(i_output<=10){
			// 	std::cout<<ss.str()<<std::endl;
			// 	std::cout<<buffer<<std::endl;
			// 	std::cout<<tmp.x<<"  "<<tmp.y<<"  "<<tmp.z<<"  "<<r<<"  "<<g<<"  "<<b<<"  "<<scale<<"  "<<intensity<<"  "<<std::endl;
			// 	i_output++;
			// }
			int rgb = (r << 16 | g << 8 | b);
			tmp.rgb = *reinterpret_cast<float*>(&rgb);
			//std::cout << tmp.rgb << std::endl;
			v.push_back(tmp);
		}
		cloud->height = 1;
		cloud->width = v.size();
		cloud->points.resize(cloud->width*cloud->height);

		std::cout << cloud->width << std::endl;

		for (auto i = 0; i < v.size(); i++) {
			cloud->points[i].x = v[i].x;
			cloud->points[i].y = v[i].y;
			cloud->points[i].z = v[i].z;
			cloud->points[i].rgb = v[i].rgb;
			// cloud->points[i].r = 255;
			// cloud->points[i].g = 255;
			// cloud->points[i].b = 255;
			// cloud->points[i].a = 255;
			// cloud->points[i].intensity = v[i].intensity;
		}
		return cloud;
	}
};

调用代码

#include<iostream>
#include "include/read_txt.hpp"

#include <pcl/visualization/cloud_viewer.h>
#include <pcl/visualization/pcl_visualizer.h>
#include <pcl/io/pcd_io.h> // 读写

using namespace std;

typedef pcl::PointXYZRGB PointT;
pcl::visualization::PCLVisualizer viewer("PointCloud");

int main(int argc, char const *argv[])
{
    string path_folder = "/home/room401/ZhangShuo/MMS/data/Cam_Lidar_calibrate/lidar_txt";
    string file_name = path_folder+"/10.txt";

    read_ascii_rgb<PointT> a= read_ascii_rgb<PointT>(file_name);
    pcl::PointCloud<PointT>::Ptr cloud= a.read();

    // PointT tmp;
    // tmp.intensity

    cout<<"点云信息: "<<*cloud<<endl;

    pcl::PCDWriter writer;
    writer.write("cloud.pcd", *cloud, true);

    viewer.removeAllPointClouds();
    viewer.addPointCloud(cloud, "cloud");
    viewer.spin();
    // viewer.spinOnce(1000);
    return 0;
}

遇到的坑

这里用stringstreanm逐行读取,先用getline函数从ifstream中读取一行存至std::string中,接着将string转到stringstreanm中,使用>>进行数值读取。

一个细节是从string转存到stringstreanm时候,应该先clear,这样才能保证之前的读取被清空,否则就会出现大量重复坐标点。。。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值