遍历文件夹进行点云格式转换 PCD转BIN BIN转PCD PCD转TXT TXT转PCD PLY转PCD

点云格式转换

1. C++ PCL PCD2BIN BIN2PCD

  • 运行这个文件需安装配置PCL环境
#include <iostream>           
#include <pcl/io/pcd_io.h>      
#include <pcl/point_types.h>
#include <string>
#include <vector>
#include <stdio.h>
//#include <dirent.h>
#include <io.h>
using namespace std;

//遍历文件夹获取文件夹下文件名
void getFileNames(string path, vector<string>& files)
{
	//文件句柄
	intptr_t hFile = 0;
	//文件信息
	struct _finddata_t fileinfo;
	string p;
	if ((hFile = _findfirst(p.assign(path).append("/*").c_str(), &fileinfo)) != -1)
	{
		do
		{
			//如果是目录,递归查找
			//如果不是,把文件绝对路径存入vector中
			if ((fileinfo.attrib & _A_SUBDIR))
			{
				if (strcmp(fileinfo.name, ".") != 0 && strcmp(fileinfo.name, "..") != 0)
					getFileNames(p.assign(path).append("/").append(fileinfo.name), files);
			}
			else
			{
				files.push_back(p.assign(path).append("/").append(fileinfo.name));
			}
		} while (_findnext(hFile, &fileinfo) == 0);
		_findclose(hFile);
	}
}


void pcd2bin(string in_file, string out_file)
{
	//Create a PointCloud value
	pcl::PointCloud<pcl::PointXYZI>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZI>);

	//Open the PCD file
	if (pcl::io::loadPCDFile<pcl::PointXYZI>(in_file, *cloud) == -1)
	{
		PCL_ERROR("Couldn't read in_file\n");
	}
	//Create & write .bin file
	ofstream bin_file(out_file.c_str(), ios::out | ios::binary | ios::app);
	if (!bin_file.good()) cout << "Couldn't open " << out_file << endl;

	//PCD 2 BIN 
	for (size_t i = 0; i < cloud->points.size(); ++i)
	{
		bin_file.write((char*)&cloud->points[i].x, 3 * sizeof(float));
		bin_file.write((char*)&cloud->points[i].intensity, sizeof(float));
		//bin_file.write(0, sizeof(float));
	}

	bin_file.close();
}
void bin2pcd(string in_file, string out_file) {
	fstream input(in_file.c_str(), ios::in | ios::binary);
	if (!input.good()) {
		cerr << "Couldn't read in_file: " << in_file << endl;
	}

	pcl::PointCloud<pcl::PointXYZI>::Ptr points(new pcl::PointCloud<pcl::PointXYZI>);

	int i;
	for (i = 0; input.good() && !input.eof(); i++) {
		pcl::PointXYZI point;
		input.read((char *)&point.x, 3 * sizeof(float));
		input.read((char *)&point.intensity, sizeof(float));
		points->push_back(point);
	}
	input.close();

	pcl::io::savePCDFileASCII(out_file, *points);
}
int main(int argc, char** argv) {

	vector<string> fileNames;
	//将路径更改为要修改的点云的存储目录路径
	string path("E:/DataSet/Tof_Image/PCDcloud/"); 	
	getFileNames(path, fileNames);
	for (const auto &ph : fileNames) {
		std::cout << "ph: "<< ph<< "\n";
		//不带路径的文件名
		string::size_type iPos = ph.find_last_of("/") + 1;
		string filename = ph.substr(iPos, path.length() - iPos);
		cout <<"filename: "<< filename << endl;
		//不带后缀的文件名
		string name = filename.substr(0, filename.rfind("."));
		cout <<"name: "<< name << endl;
		//记得将这里的路径改为自己转换后的点云要存储的文件路径
		//pcd格式的点云转成bin格式的,对于不含强度信息的点云会提示缺少强度intensity信息,但还是可以转换成功
		pcd2bin(ph, "E:/DataSet/Tof_Image/binCloud/"+ name+".bin");
		//bin格式的点云转成pcd格式的,使用方法注释上面那行,取消注释下面这行。
		//bin2pcd(ph, "E:/DataSet/PCD/" + name + ".pcd");
	}
	return 0;
}

2. C++ PCL PCD2TXT

#include <iostream>
#include <pcl/io/pcd_io.h>  
#include <pcl/point_types.h>  
#include <pcl/filters/voxel_grid.h>

using namespace std;

void pclDownsize(pcl::PointCloud<pcl::PointXYZ>::Ptr in, pcl::PointCloud<pcl::PointXYZ>::Ptr out)
{
	pcl::VoxelGrid<pcl::PointXYZ> down_filter;
	float leaf = 0.1;
	down_filter.setLeafSize(leaf, leaf, leaf);
	down_filter.setInputCloud(in);
	down_filter.filter(*out);
}

//遍历文件夹获取文件夹下文件名
void getFileNames(string path, vector<string>& files)
{
	intptr_t hFile = 0;
	struct _finddata_t fileinfo;
	string p;
	if ((hFile = _findfirst(p.assign(path).append("/*").c_str(), &fileinfo)) != -1)
	{
		do
		{
			//如果是目录,递归查找
			//如果不是,把文件绝对路径存入vector中
			if ((fileinfo.attrib & _A_SUBDIR))
			{
				if (strcmp(fileinfo.name, ".") != 0 && strcmp(fileinfo.name, "..") != 0)
					getFileNames(p.assign(path).append("/").append(fileinfo.name), files);
			}
			else
			{
				files.push_back(p.assign(path).append("/").append(fileinfo.name));
			}
		} while (_findnext(hFile, &fileinfo) == 0);
		_findclose(hFile);
	}
}
void pcd2txt(string in_file, string out_file)
{
	pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
	// pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_out(new pcl::PointCloud<pcl::PointXYZ>);
	// Fill in the cloud data  
	if (pcl::io::loadPCDFile<pcl::PointXYZ>(in_file, *cloud) == -1)
	{
		PCL_ERROR("Couldn't read file \n");
		//return (0);
	}
	// pclDownsize(cloud,cloud_out);
	cout << "points cloud is successfully loaded! " << endl;
	//for (size_t i = 0; i < cloud->points.size(); i++)
	//  std::cout << " " << cloud->points[i].x << " " << cloud->points[i].y
	//  <<" "<< cloud->points[i].z << std::endl;
	int Num = cloud->points.size();
	double *X = new double[Num] {0};
	double *Y = new double[Num] {0};
	double *Z = new double[Num] {0};
	cout << "size is : " << cloud->points.size() << endl;
	for (size_t i = 0; i < cloud->points.size(); ++i)
	{
		X[i] = cloud->points[i].x;
		Y[i] = cloud->points[i].y;
		Z[i] = cloud->points[i].z;
		//cout << "first  " << i << " of " << Num << endl;
	}
	ofstream zos(out_file);
	for (int i = 0; i < cloud->points.size(); i++)
	{
		zos << X[i] << " " << Y[i] << " " << Z[i] << endl;
		//cout << "second  " << i << " of " << Num << endl;
	}
	cout << "trans has done!!!" << endl;
	//cin.get();
}
int main(int argc, char *argv[])
{
	vector<string> fileNames;
	string path("E:/DataSet/points"); 
	getFileNames(path, fileNames);
	for (const auto &ph : fileNames) {
		std::cout << "ph: " << ph << "\n";
		//不带路径的文件名
		string::size_type iPos = ph.find_last_of("/") + 1;
		string filename = ph.substr(iPos, path.length() - iPos);
		cout << "filename: " << filename << endl;
		//不带后缀的文件名
		string name = filename.substr(0, filename.rfind("."));
		cout << "name: " << name << endl;
		pcd2txt(ph, "E:/DataSet/bin/" + name + ".txt");
	}
	return 0;
}

3. python PCD2TXT


import os
from os import listdir, path

path_str = 'E:/desktop/PointCloud/OpenPCDet/data/carton/testing/points'  # your directory path
txts = [f for f in listdir(path_str)
        if f.endswith('.pcd') and path.isfile(path.join(path_str, f))]

for txt in txts:
    with open(os.path.join(path_str, txt), 'rb') as f:
        lines = f.readlines()

    with open(os.path.join(path_str,os.path.splitext(txt)[0]+".txt"), 'w') as f:
        line = str(line)
        f.write(''.join(lines[11:]))

"""
import os
#定义一个三维点类
class Point(object):
    def __init__(self,x,y,z):
        self.x = x
        self.y = y
        self.z = z
points = []
path = 'E:/desktop/PointCloud/OpenPCDet/data/carton/testing/points/cloudnorm_000002'
#读取pcd文件,从pcd的第12行开始是三维点
with open(path+'.pcd') as f:
    for line in  f.readlines()[11:len(f.readlines())-1]:
        strs = line.split(' ')
        points.append(Point(strs[0],strs[1],strs[2].strip()))
##strip()是用来去除换行符
##把三维点写入txt文件
fw = open(path+'.txt','w')
for i in range(len(points)):
     linev = points[i].x+" "+points[i].y+" "+points[i].z+"\n"
     fw.writelines(linev)
fw.close()



import math
import os
import pcl


def txt2pcd(filename):
    xlist = []
    ylist = []
    zlist = []
    with open(filename, 'r') as file_to_read:
        while True:
            lines = file_to_read.readline()
            if not lines:
                break
                pass
            x, y, z = [float(i) for i in lines.split(' ')]
            print(str(x) + ' ' + str(y) + ' ' + str(z))
            xlist.append(x)
            ylist.append(y)
            zlist.append(z)

    savefilename = './test_1.pcd'
    if not os.path.exists(savefilename):
        f = open(savefilename, 'w')
        f.close()
    with open(savefilename, 'w') as file_to_write:
        file_to_write.writelines("# .PCD v0.7 - Point Cloud Data file format\n")
        file_to_write.writelines("VERSION 0.7\n")
        file_to_write.writelines("FIELDS x y z\n")
        file_to_write.writelines("SIZE 4 4 4\n")
        file_to_write.writelines("TYPE F F F\n")
        file_to_write.writelines("COUNT 1 1 1\n")
        file_to_write.writelines("WIDTH " + str(len(xlist)) + "\n")
        file_to_write.writelines("HEIGHT 1\n")
        file_to_write.writelines("VIEWPOINT 0 0 0 1 0 0 0\n")
        file_to_write.writelines("POINTS " + str(len(xlist)) + "\n")
        file_to_write.writelines("DATA ascii\n")
        for i in range(len(xlist)):
            file_to_write.writelines(str(xlist[i]) + " " + str(ylist[i]) + " " + str(zlist[i]) + "\n")


def pcd2txt(pcdfile):
    p = pcl.load(pcdfile)
    savetxtfile = './test_1_inliers.txt'

    with open(savetxtfile, 'w') as f:
        f.write(str(p.size) + 'points in total' + '\n')
        # print(p[i])
        for i in range(p.size):
            x = str(p[i][0])
            y = str(p[i][1])
            z = str(p[i][2])
            f.write(x + ' ' + y + ' ' + z + '\n')


if __name__ == '__main__':
    txtfile = './3dposition.txt'
    pcdfile = './pcldata/tutorials/test_1.pcd'
    txt2pcd(txtfile)
    pcd2txt(pcdfile)
"""

4. python TXT2PCD

  • 这个不是遍历文件夹更改更改的是单个
import numpy as np
import open3d as o3d

## 数据读取
np.set_printoptions(suppress=True)  # 取消默认的科学计数法
Data1 = np.loadtxt('F:/information/car_0001.txt', dtype=np.float, skiprows=1,
                   delimiter=' ', usecols=(0, 1, 2), unpack=False)
## open3d数据转换
pcd = o3d.geometry.PointCloud()
pcd.points = o3d.utility.Vector3dVector(Data1)
# print(np.asarray(pcd.points))
o3d.visualization.draw_geometries([pcd])
## 保存成ply数据格式
# o3d.io.write_point_cloud('xxx.ply', pcd, write_ascii=True)  # ascii编码
# o3d.io.write_point_cloud('xxx.ply', pcd, write_ascii=False)  # 非ascii编码
## 保存成pcd数据化格式
o3d.io.write_point_cloud('F:/information/car_0001.pcd', pcd, write_ascii=True)  # ascii编码
# o3d.io.write_point_cloud('xxx.pcd', pcd, write_ascii=True)  # 非ascii编码

5. python PLY2PCD

import open3d as o3d
import numpy as np
import os


def alter(name):
    filename = os.path.splitext(name)[0]
    pcd = o3d.io.read_point_cloud('E:/DataSet/Tof_Image/cloud_image/' + name)
    print(pcd)
    o3d.io.write_point_cloud('E:/DataSet/Tof_Image/PCDcloud/' + filename + ".pcd", pcd)
    print(filename)

if __name__ == '__main__':
    path1 = 'E:/DataSet/Tof_Image/cloud_image/'
    list = os.listdir(path1)
    print(list)
    for i in list:
        alter(i)

  • 等后面有空再补充其他转换方式的
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值