点云PLY、PCD、OBJ、TXT文件互相转换
一、代码
本文点云文件的转换只针对点云的顶点信息,它们之间的相互转换关系一共12种。这份代码没有用PCL,不需要配置PCL环境也可以使用
Python
import reclass FormatTrans:def __init__(self):pass@staticmethoddef writePLYHeader(ply_file, num_points):ply_file.write("ply\n")ply_file.write("format ascii 1.0\n")ply_file.write("element vertex " + str(num_points) + "\n")ply_file.write("property float x\n")ply_file.write("property float y\n")ply_file.write("property float z\n")ply_file.write("end_header\n")@staticmethoddef writePCDHeader(pcdFile, vertexCount):pcdFile.write("# .PCD v0.7 - Point Cloud Data file format\n")pcdFile.write("VERSION 0.7\n")pcdFile.write("FIELDS x y z\n")pcdFile.write("SIZE 4 4 4\n")pcdFile.write("TYPE F F F\n")pcdFile.write("COUNT 1 1 1\n")pcdFile.write("WIDTH " + str(vertexCount) + "\n")pcdFile.write("HEIGHT 1\n")pcdFile.write("VIEWPOINT 0 0 0 1 0 0 0\n")pcdFile.write("POINTS " + str(vertexCount) + "\n")pcdFile.write("DATA ascii\n")@staticmethoddef txtToply(txtpath, plypath):txtfile = open(txtpath, "r")plyfile = open(plypath, "w")txtNum = []num_points = int(txtfile.readline())while True:line = txtfile.readline()if not line:breakline = line[:-1]lineList = line.split(" ")txtNum.append(lineList)txtfile.close()FormatTrans.writePLYHeader(plyfile, num_points)for i in range(num_points):content = txtNum[i][0] + " " + txtNum[i][1] + " " + txtNum[i][2] + "\n"plyfile.write(content)plyfile.close()@staticmethoddef txtTopcd(txtpath, pcdpath):txtfile = open(txtpath, "r")pcdfile = open(pcdpath, "w")txtNum = []num_points = int(txtfile.readline())while True:line = txtfile.readline()if not line:breakline = line[:-1]lineList = line.split(" ")txtNum.append(lineList)txtfile.close()FormatTrans.writePCDHeader(pcdfile, num_points)for i in range(num_points):content = txtNum[i][0] + " " + txtNum[i][1] + " " + txtNum[i][2] + "\n"pcdfile.write(content)pcdfile.close()@staticmethoddef txtToobj(txtpath, objpath):txtfile = open(txtpath, "r")objfile = open(objpath, "w")txtNum = []num_points = int(txtfile.readline())while True:line = txtfile.readline()if not line:breakline = line[:-1]lineList = line.split(" ")txtNum.append(lineList)txtfile.close()for i in range(num_points):content = "v " + txtNum[i][0] + " " + txtNum[i][1] + " " + txtNum[i][2] + "\n"objfile.write(content)objfile.close()@staticmethoddef plyTotxt(plypath, txtpath):txtfile = open(txtpath, "w")plyfile = open(plypath, "r")flag = 0plyNum = []while True:line = plyfile.readline()if not line:breakif flag == 1:line = line[:-1]lineList = line.split(" ")plyNum.append(lineList)if flag == 0 and re.findall("end_header", line):flag = 1plyfile.close()num_points = len(plyNum)for i in range(num_points):content = plyNum[i][0] + " " + plyNum[i][1] + " " + plyNum[i][2] + "\n"txtfile.write(content)txtfile.close()@staticmethoddef pcdTotxt(pcdpath, txtpath):txtfile = open(txtpath, "w")pcdfile = open(pcdpath, "r")flag = 0pcdNum = []while True:line = pcdfile.readline()if not line:breakif flag == 1:line = line[:-1]lineList = line.split(" ")pcdNum.append(lineList)if flag == 0 and re.findall("DATA ascii", line):flag = 1pcdfile.close()num_points = len(pcdNum)for i in range(num_points):content = pcdNum[i][0] + " " + pcdNum[i][1] + " " + pcdNum[i][2] + "\n"txtfile.write(content)txtfile.close()@staticmethoddef objTotxt(objpath, txtpath):txtfile = open(txtpath, "w")objfile = open(objpath, "r")objNum = []while True:line = objfile.readline()if line.startswith("#"):continueif not line:breakline = line[2:-1]lineList = line.split(" ")objNum.append(lineList)objfile.close()num_points = len(objNum)for i in range(num_points):content = objNum[i][0] + " " + objNum[i][1] + " " + objNum[i][2] + "\n"txtfile.write(content)txtfile.close()@staticmethoddef plyTopcd(plypath, pcdpath):pcdfile = open(pcdpath, "w")plyfile = open(plypath, "r")flag = 0plyNum = []while True:line = plyfile.readline()if not line:breakif flag == 1:line = line[:-1]lineList = line.split(" ")plyNum.append(lineList)if flag == 0 and re.findall("end_header", line):flag = 1plyfile.close()num_points = len(plyNum)FormatTrans.writePCDHeader(pcdfile, num_points)for i in range(num_points):content = plyNum[i][0] + " " + plyNum[i][1] + " " + plyNum[i][2] + "\n"pcdfile.write(content)pcdfile.close()@staticmethoddef plyToobj(plypath, objpath):objfile = open(objpath, "w")plyfile = open(plypath, "r")flag = 0plyNum = []while True:line = plyfile.readline()if not line:breakif flag == 1:line = line[:-1]lineList = line.split(" ")plyNum.append(lineList)if flag == 0 and re.findall("end_header", line):flag = 1plyfile.close()num_points = len(plyNum)for i in range(num_points):content = "v " + plyNum[i][0] + " " + plyNum[i][1] + " " + plyNum[i][2] + "\n"objfile.write(content)objfile.close()@staticmethoddef pcdToply(pcdpath, plypath):plyfile = open(plypath, "w")pcdfile = open(pcdpath, "r")flag = 0pcdNum = []while True:line = pcdfile.readline()if not line:breakif flag == 1:line = line[:-1]lineList = line.split(" ")pcdNum.append(lineList)if flag == 0 and re.findall("DATA ascii", line):flag = 1pcdfile.close()num_points = len(pcdNum)FormatTrans.writePLYHeader(plyfile, num_points)for i in range(num_points):content = pcdNum[i][0] + " " + pcdNum[i][1] + " " + pcdNum[i][2] + "\n"plyfile.write(content)plyfile.close()@staticmethoddef objToply(objpath, plypath):plyfile = open(plypath, "w")objfile = open(objpath, "r")objNum = []while True:line = objfile.readline()if line.startswith("#"):continueif not line:breakline = line[2:-1]lineList = line.split(" ")objNum.append(lineList)objfile.close()num_points = len(objNum)FormatTrans.writePLYHeader(plyfile, num_points)for i in range(num_points):content = objNum[i][0] + " " + objNum[i][1] + " " + objNum[i][2] + "\n"plyfile.write(content)plyfile.close()@staticmethoddef pcdToobj(pcdpath, objpath):objfile = open(objpath, "w")pcdfile = open(pcdpath, "r")flag = 0pcdNum = []while True:line = pcdfile.readline()if not line:breakif flag == 1:line = line[:-1]lineList = line.split(" ")pcdNum.append(lineList)if flag == 0 and re.findall("DATA ascii", line):flag = 1pcdfile.close()num_points = len(pcdNum)for i in range(num_points):content = "v " + pcdNum[i][0] + " " + pcdNum[i][1] + " " + pcdNum[i][2] + "\n"objfile.write(content)objfile.close()@staticmethoddef objTopcd(objpath, pcdpath):pcdfile = open(pcdpath, "w")objfile = open(objpath, "r")objNum = []while True:line = objfile.readline()if line.startswith("#"):continueif not line:breakline = line[2:-1]lineList = line.split(" ")objNum.append(lineList)objfile.close()num_points = len(objNum)FormatTrans.writePCDHeader(pcdfile, num_points)for i in range(num_points):content = objNum[i][0] + " " + objNum[i][1] + " " + objNum[i][2] + "\n"pcdfile.write(content)pcdfile.close()if __name__ == "__main__":f = FormatTrans()# f.txtToply("data/data_bunny.txt", "data/data_bunny.ply")# f.txtTopcd("data/data_bunny.txt", "data/data_bunny.pcd")# f.txtToobj("data/data_bunny.txt", "data/data_bunny.obj")# f.plyTotxt("data/data_bunny.ply", "data/data_bunny1.txt")# f.pcdTotxt("data/data_bunny.pcd", "data/data_bunny2.txt")# f.objTotxt("data/data_bunny.obj", "data/data_bunny3.txt")# f.plyTopcd("data/data_bunny.ply", "data/data_bunny1.pcd")# f.plyToobj("data/data_bunny.ply", "data/data_bunny2.obj")# f.pcdToply("data/data_bunny.pcd", "data/data_bunny2.ply")# f.objToply("data/data_bunny.obj", "data/data_bunny3.ply")# f.pcdToobj("data/data_bunny.pcd", "data/data_bunny3.obj")f.objTopcd("data/data_bunny.obj", "data/data_bunny2.pcd")
验证:
你可以把注释按照顺序一共12个,每一个都解开注释,解开一个之后,前面的都注释掉,进行测试,我这里解开了第一个。你可以用cloudcompare软件进行查看,每次测试生成的文件。
完整项目和实验数据:点云PLY、PCD、OBJ、TXT文件互相转换代码资源-CSDN文库