Méthodes de lecture et d'écriture de certains formats de fichiers de nuage de points de base courants tels que ply las pcd

Méthodes de lecture et d'écriture de certains formats de fichiers de nuage de points de base courants tels que ply las pcd

1. Texte (txt)

1.1 Structure de stockage

La structure de fichier des données de nuage de points stockées au format texte est relativement simple, chaque point est une rangée d'enregistrements et le format de stockage des informations de point est xyz ou xyzrgb.

1.2, lire

Lors de la lecture de données de nuages ​​de points au format texte, vous pouvez suivre la méthode générale de lecture de texte. Voici comment utiliser open3d pour lire des données de nuages ​​de points au format txt.

import open3d as o3d
txt_file=r"D:\test_data\bildstein_station1_xyz_intensity_rgb.txt"

pcd=o3d.io.read_point_cloud(txt_file,format='xyz')
o3d.visualization.draw([pcd])

2. Format PCD

Un fichier PCD est composé d'une partie en-tête et d'une partie données

nom de domaine explication sur le terrain
VERSION Spécifie la version du fichier PCD
DES CHAMPS spécifie le nom de chaque dimension et champ qu'un point peut avoir
TAILLE Spécifiez la taille de chaque dimension en octets
TAPER Spécifiez le type de chaque dimension avec un caractère
COMPTER Spécifiez les données d'élément contenues dans chaque dimension
LARGEUR Le nombre de points non ordonnés ou le nombre de points dans une rangée de points ordonnés
HAUTEUR Il est défini sur 1 dans un nuage de points non ordonné et indique le nombre de lignes dans un nuage de points ordonné
POINTS Le nombre total de points dans le nuage de points
DONNÉES type de données, binaire ou ASCII

1.2, lire et écrire

1.2.1, lecture et écriture open3d (python)

Lire les fichiers de nuages ​​de points pcd

import open3d as o3d
import numpy as np

#读取pcd数据并可视化
pcd_file=r""
pcd=o3d.io.read_point_cloud(pcd_file,format='pcd')

#将点云的坐标和颜色转换为numpy格式
points=np.array(pcd.points)
colors=np.array(pcd.colors)

#可视化
o3d.visualization.draw([pcd])

#######保存pcd点云文件

#写入pcd格式
save_file="test2.pcd"

#手动定义点云
points=np.array([[8,5,3],
                 [9,0,1],
                 [2,5,3],
                 [0,4,2],
                 [7,2,9],
                 [8,8,4],
                 [9,5,8],
                 [2,5,9],
                 [0,7,5],
                 [11,2,8],
                 [10,9,0]
                 ])
colors=np.array([[255,0,0],
                 [255,0,0],
                 [0,255,0],
                 [0,255,0],
                 [0,0,255],
                 [0,0,255],
                 [255,0,255],
                 [255,0,255],
                 [255,255,0],
                 [255,255,0],
                 [255,255,0]
                 ])
colors=colors/255

pcd=o3d.geometry.PointCloud()

pcd.points=o3d.utility.Vector3dVector(points)
pcd.colors=o3d.utility.Vector3dVector(colors)

#可视化
o3d.visualization.draw_geometries([pcd])

#使用draw方法可视化需要将颜色归一化到0-1之间
# o3d.visualization.draw([pcd])

#保存
#o3d.io.write_point_cloud(save_file,pcd,write_ascii=True) #以ascii格式存储点数据集部分
o3d.io.write_point_cloud(save_file,pcd)#以二进制格式存储点数据集部分

image

Une partie du jeu de données de points pcd est enregistrée au format ASCII

image

Il convient de noter que si l'ensemble de données de points pcd est partiellement enregistré au format binaire, alors rgb est écrit en stockage de bits.

image

1.2.2, lecture et écriture PCL (C++)

Vous pouvez utiliser le fichier pcd généré ci-dessus pour tester

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

using namespace std;
int main()
{
    
    
	string pcd_file = "D:\\project\\Python\\PointCloud\\test2.pcd";
	//pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
	pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZRGB>);
	if (pcl::io::loadPCDFile<pcl::PointXYZRGB>(pcd_file,*cloud)==-1)
	{
    
    
		PCL_ERROR("couldn't read file\n");
		return(-1);
	}

	for (size_t i=0;i<cloud->points.size();++i)
	{
    
    
		cout << " " << cloud->points[i].x << " " <<
			cloud->points[i].y << " " <<
			cloud->points[i].z << " " <<
			(int)cloud->points[i].r<< " "<<
			(int)cloud->points[i].g<<" "<<
			(int)cloud->points[i].b<< endl;

	}

	return 0;
}


Le résultat de l'écriture d'un programme dans l'environnement Windows

image

Enregistrez le résultat dans un fichier pcd

#include <iostream>

#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>

using namespace std;
int main()
{
    
    
	string pcd_file = "test2.pcd";
	pcl::PointCloud<pcl::PointXYZRGB> cloud;

	int data[11][6] = {
    
    
		{
    
    8,5,3,255,0,0},
		{
    
    9,0,1,255,0,0},
		{
    
    2,5,3,0,255,0},
		{
    
    0,4,2,0,255,0},
		{
    
    7,2,9,0,0,255},
		{
    
    8,8,4,0,0,255},
		{
    
    9,5,8,255,0,255},
		{
    
    2,5,9,255,0,255},
		{
    
    0,7,5,255,255,0},
		{
    
    11,2,8,255,255,0},
		{
    
    10,9,0,255,255,0}};

	cloud.width = 11;
	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 = data[i][0];
		cloud.points[i].y = data[i][1];
		cloud.points[i].z = data[i][2];
		cloud.points[i].r = data[i][3];
		cloud.points[i].g = data[i][4];
		cloud.points[i].b = data[i][5];
	}

	pcl::io::savePCDFileASCII(pcd_file, cloud);
	//pcl::io::savePCDFileBinary(pcd_file, cloud);
	return 0;
}

Ouvrez le fichier pcd sortie test2.pcd par pcl::io::savePCDFileASCII(pcd_file, cloud);

image

Le fichier de nuage de points pcd généré par pcl est incohérent avec le fichier de nuage de points généré par open3d dans la partie couleur, ce qui est principalement dû au type de stockage de données. Après pcl1.7, la partie couleur sera enregistrée sous forme d'entier. Vous trouverez ci-dessous des explications de référence plus détaillées.

https://blog.csdn.net/weixin_37835423/article/details/105363615

problème résolu

Première option :

Basculez directement l'environnement pcl du système en fonction du type de stockage du nuage de points. Si le champ rvb du nuage de points est enregistré en tant que type flottant, basculez directement la version pcl vers une version antérieure à pcl-1.9, sinon basculez la version pcl à la version pcl-1.9

Option 2 (recommandée) :

Une fois la version pcl du système déterminée, elle est rarement modifiée, car de nombreux projets antérieurs sont développés sur la base de cette version. Une fois la version modifiée, il peut y avoir un problème de "un petit changement affectera tout le corps", donc il est recommandé d'éditer directement le fichier pcd Apporter des modifications en fonction de la version pcl du système.
Convertissez le type uint du champ rgb en type flottant :

#include <iostream>
#include <fstream>
#include <pcl/point_types.h>
#include <pcl/io/pcd_io.h>
#include <sstream>

using PointT = pcl::PointXYZRGB;
using namespace std;

int main(int argc, char** argv)
{
    ifstream in_file("temp_1_9.pcd");
    if (!in_file){
        cout<<"couldnt open file !!!!!!"<<endl;
        return 0;
    }

    string str;
    uint32_t row_num = 0;
    ofstream out_file("1_9_to_1_7.pcd");
    while (getline(in_file, str)){
        row_num++;
        // change rgb type in header
        if (row_num == 5){
            out_file<<"TYPE"<<" "<<"F"<<" "<<"F"<<" "<<"F"<<" "<<"F"<<endl;
            continue;
        }
        // skip header
        if (row_num < 12){
            out_file<<str<<endl;
            continue;
        }
        // read line data
        stringstream ss(str);
        float tmp_value = 0;
        vector<float> line_datas;
        line_datas.clear();
        while (ss >> tmp_value){
            line_datas.push_back(tmp_value);
        }
        
        if (line_datas.size() != 4){
            cout<<"line "<<row_num<<" format has problem"<<endl;
            return 0;
        }
        out_file<<line_datas[0]<<" "<<line_datas[1]<<" "<<line_datas[2]<<" ";
        // change rgb data
        uint32_t raw_rgb = static_cast<uint32_t>(line_datas[3]);
        uint8_t r = (raw_rgb >> 16) & 0x0000ff;
        uint8_t g = (raw_rgb >> 8)  & 0x0000ff;
        uint8_t b = (raw_rgb)     & 0x0000ff;
        uint32_t rgb = ((uint32_t)r << 16 | (uint32_t)g << 8 | (uint32_t)b);
        float cha_rgb = *reinterpret_cast<float*>(&rgb);
        out_file<<cha_rgb<<endl;
    }

    return 0;
}

Le résultat après l'exécution du programme modifié

cat 1_9_to_1_7.pcd 
# .PCD v0.7 - Point Cloud Data file format
VERSION 0.7
FIELDS x y z rgb
SIZE 4 4 4 4
TYPE F F F F
COUNT 1 1 1 1
WIDTH 10
HEIGHT 1
VIEWPOINT 0 0 0 1 0 0 0
POINTS 10
DATA ascii
0 0 0 0
1 1 1 9.21942e-41
2 2 2 1.84388e-40
3 3 3 2.76583e-40
4 4 4 3.68777e-40
5 5 5 4.60971e-40
6 6 6 5.53165e-40
7 7 7 6.4536e-40
8 8 8 7.37554e-40
9 9 9 8.29748e-40

Le contenu du fichier temp_1_9.pcd est cohérent et la conversion est réussie.

3. Format LAS

3.1 Structure de stockage

LAS est un format de données public pour stocker des nuages ​​de points. Il est principalement utilisé pour stocker des données de nuages ​​de points radar. LAZ est une compression sans perte du format LAS.

La dernière version de la spécification LAS est LAS 1.4. La bibliothèque laspy peut prendre en charge les fichiers LAS de la version 1.2 ~ 1.4.

https://laspy.readthedocs.io/en/latest/index.html

Un fichier LAS se compose de trois parties : en-tête, enregistrements de longueur variable (VLR), enregistrements ponctuels

L'en-tête du fichier contient des informations telles que la version des données, le format de point (différentes dimensions stockées pour chaque point) et d'autres informations ; les enregistrements de longueur variable incluent certaines méta-informations, telles que les informations sur le système de coordonnées, des dimensions supplémentaires et d'autres informations ; la zone d'enregistrement de l'ensemble de points est le cœur du fichier las, enregistrez les informations de coordonnées x, y, z du point et d'autres informations d'attribut telles que r, g, b, la classification, l'intensité, etc.

Il existe 11 versions du format point, dont la version 0 est la base, et d'autres versions ultérieures ajoutent d'autres champs sur la base de la version 0. Pour des champs spécifiques, veuillez vous référer au site officiel pour plus d'explications

https://laspy.readthedocs.io/en/latest/intro.html

image-20220705205448416

3.2 Lecture et écriture

3.2.1. Utiliser laspy pour lire et écrire (Python)

import laspy
import numpy as np

las_file=r""
las=laspy.read(las_file)
#获取文件头
header=las.header
#点类型
point_format=las.point_format
print(point_format.id)
#属性字段名
dimension_names=point_format.dimension_names
print(list(dimension_names))

#点集的外边框
print(header.mins)
print(header.maxs)

#点个数
point_num=header.point_count

#获取坐标和颜色
las_x=np.array(las.x)
las_y=np.array(las.y)
las_z=np.array(las.z)
las_r=np.array(las.red)
las_g=np.array(las.green)
las_b=np.array(las.blue)

#组合
pt=np.stack([las_x,las_y,las_z],axis=1)
colors=np.stack([las_r,las_g,las_b],axis=1)

Utiliser laspy pour écrire les derniers fichiers

save_las_file=r"save_las.las"

#以x y z r g b的方式定义点云数据
my_data=np.array([[8,5,3,255,0,0],
                 [9,0,1,255,0,0],
                 [2,5,3,0,255,0],
                 [0,4,2,0,255,0],
                 [7,2,9,0,0,255],
                 [8,8,4,0,0,255],
                 [9,5,8,255,0,255],
                 [2,5,9,255,0,255],
                 [0,7,5,255,255,0],
                 [11,2,8,255,255,0],
                 [10,9,0,255,255,0]
                 ])
                 
 #创建点云文件
 las=laspy.create(file_version="1.2",points_format=3)
 las.x=my_data[:,0]
 las.y=my_data[:,1]
 las.z=my_data[:,2]
 las.red=my_data[:,3]
 las.green=my_data[:,4]
 las.blue=my_data[:,5]
	
 #保存las文件
 las.write(save_las_file)                

3.2.2. Utiliser laslib pour lire et écrire (C++)

L'utilisation de C++ pour faire fonctionner les fichiers las peut utiliser la bibliothèque laslib.

#include <iostream>
#include "lasreader.hpp"
#include "laswriter.hpp"
using namespace std;
int main()
{
	const string las_file="";
	
	LASreadOpener lasreadopener;
	lasreadopener.set_file_name(las_file.data());
	
	LASreader* lasreader=lasreadopener.open();

	LASheader header=lasreader->header;
	lasreader->header.unlink();

	int nbPoints = header.number_of_point_records;

	float x,y,z;
	int r,g,b;

	while(lasreader->read_point())
	{
		LASpoint& pointReader= lasreader->point;

		x=pointReader.get_x();
		y=pointReader.get_y();
		z=pointReader.get_z();

		r=pointReader.get_R();
		g=pointReader.get_G();
		b=pointReader.get_B();
	}
	delete lasreader;
}


écrire le dernier fichier

#include <iostream>
#include "lasreader.hpp"
#include "laswriter.hpp"
using namespace std;
int main()
{
	const string las_file="test.las";
	
	int data[11][6] = {
			{8,5,3,255,0,0},
			{9,0,1,255,0,0},
			{2,5,3,0,255,0},
			{0,4,2,0,255,0},
			{7,2,9,0,0,255},
			{8,8,4,0,0,255},
			{9,5,8,255,0,255},
			{2,5,9,255,0,255},
			{0,7,5,255,255,0},
			{11,2,8,255,255,0},
			{10,9,0,255,255,0}
			};
	LASwriteOpener laswriteropener;
	laswriteropener.set_file_name(las_file.data());
	
	LASheader header;
	header.point_data_format=3;
	header.point_data_record_length=34;
	header.number_of_point_records=11;

	LASWriter* laswriter = laswriteropener.open(&header);
	LASpoint point;
	point.init(&header,header.point_data_format,header.point_data_record_length,&header);

	double minx=DBL_MAX,miny=DBL_MAX,minz=DBL_MAX;
	double maxx=-DBL_MAX,maxy=-DBL_MAX,maxz=-DBL_MAX;
	
	for(size_t i=0;i<header.point_data_record_length;++i)
	{
		point.set_x(data[i][0]);
		point.set_y(data[i][1]);
		point.set_z(data[i][2]);
		point.set_R(data[i][3]);
		point.set_G(data[i][4]);
		point.set_B(data[i][5]);

		if(data[i][0]<minx)
		{
			minx=data[i][0];
		}
		if(data[i][1]<miny)
		{
			minx=data[i][1];
		}
		if(data[i][2]<minz)
		{
			minx=data[i][2];
		}
		if(data[i][0]>maxx)
		{
			maxx=data[i][0];
		}
		if(data[i][1]>maxy)
		{
			maxy=data[i][1];
		}
		if(data[i][2]>maxz)
		{
			maxx=data[i][2];
		}

		laswriter->write_point(&point);
		laswriter->update_inventory(&point);
	}

	header.set_bounding_box(minx,miny,minz,maxx.maxy.maxz);
	laswriter->update_header(&header);
	I64 total_bytes=laswriter->close();
	delete laswriter;
}

4. Format PLI

4.1 Structure de stockage

PLY (Polygon File Format) est un format commun de stockage de nuages ​​de points développé par l'Université de Stanford. Il était à l'origine utilisé pour stocker des données de nuages ​​de points d'instruments de numérisation 3D.

Le fichier PLY est composé de deux parties : l'en-tête du fichier et la zone de données.

en-tête de fichier

L'en-tête du fichier enregistre les commentaires, les catégories d'éléments et les attributs dans le fichier de nuage de points, en commençant par ply et en terminant par end header.

ply
...
...
end header

La deuxième ligne de l'en-tête du fichier est la méthode de stockage et la version du fichier, en commençant par le format, suivi de la méthode d'encodage et de la version. Il existe trois méthodes d'encodage : ascii, binary_little_endian et binary_big_endian. Actuellement, PLY n'a que la version 1.0.

ply
format ascii 1.0
...
...
end header

Le format est suivi des informations de commentaire, en commençant par le commentaire, le créateur peut ajouter des informations sur l'auteur et des informations de base sur le nuage de points.

ply
format ascii 1.0
comment made by anonymous
comment this file is a cube
...
end header

Après les informations de commentaire, les informations d'élément d'élément + les informations d'attribut de propriété de l'élément. Les informations d'élément d'élément incluent le type et le numéro, et les informations d'attribut de propriété incluent le type de stockage et le nom d'attribut du champ d'attribut. Les éléments d'un fichier PLY incluent généralement un sommet, une face, une arête, etc. Les informations sur les éléments et les informations sur les attributs doivent apparaître en combinaison, le format est le suivant

element <element name> <number in file>
property <data_type> <property name 1>
property <data_type> <property name 2>
property <data_type> <property name 3>
1234

Nous définissons un fichier de plis contenant 6 sommets et 8 éléments de face, l'en-tête du fichier est le suivant,

ply
format ascii 1.0
comment made by anonymous
comment this file is a cube
element vertex 6
property float32 x
property float32 y
property float32 z
property uchar red
property uchar green
property uchar blue
element face 8
property list uint8 int32 vertex_index
end_header
1234567891011121314

zone de données

Les données sont stockées directement après l'en-tête du fichier et la forme de stockage est divisée en ASCII et binaire. En prenant ASCII comme exemple, enregistrez d'abord chaque point par ligne, puis enregistrez chaque surface par ligne une fois que tous les points ont été enregistrés.

0 0 0 0 0 0 (开始记录点,按照x,y,z,r,g,b方式排列)
0 100 0 0 0 0
100 100 0 0 0 0
100 0 0 0 0 0
50 50 75 255 255 255
50 50 -75 255 255 255
3 0 1 4 (开始记录面,按照点个数,点的序号排列,3表示这个面由3个点组成,0,1,4代表该面由第0,1,4个点组成)
3 1 2 4
3 2 3 4
3 0 3 4
3 0 1 5
3 1 2 5
3 2 3 5
3 0 3 5
1234567891011121314

Une lime à plis complète

ply
format ascii 1.0
comment made by anonymous
comment this file is a cube
element vertex 6
property float32 x
property float32 y
property float32 z
property uchar red
property uchar green
property uchar blue
element face 8
property list uint8 int32 vertex_index
end_header
0 0 0 0 0 0
0 100 0 0 0 0
100 100 0 0 0 0
100 0 0 0 0 0
50 50 75 255 255 255
50 50 -75 255 255 255
3 0 1 4 
3 1 2 4
3 2 3 4
3 0 3 4
3 0 1 5
3 1 2 5
3 2 3 5
3 0 3 5

4.2, lire et écrire

4.2.1. Utiliser plyfile pour lire et écrire (Python)

Lire les fichiers ply à l'aide de plyfile

from plyfile import PlyData,PlyElement

file=r"C:\Users\123\Desktop\test2.ply"
plydata=PlyData.read(file)

print(plydata)
print("*************************************************")
#第一种读取方法
elements=plydata.elements
for element in elements:
    for data in element.data:
        print(data)
print("*************************************************")
#第二种读取方法
vertex_data=elements[0].data
face_data =elements[1].data
print(vertex_data)
print(face_data)

résultat d'impression

ply
format ascii 1.0
comment made by anonymous
comment this file is a cube
element vertex 6
property float x
property float y
property float z
property uchar red
property uchar green
property uchar blue
element face 8
property list uchar int vertex_index
end_header
*************************************************
(0., 0., 0., 0, 0, 0)
(0., 100., 0., 0, 0, 0)
(100., 100., 0., 0, 0, 0)
(100., 0., 0., 0, 0, 0)
(50., 50., 75., 255, 255, 255)
(50., 50., -75., 255, 255, 255)
(array([0, 1, 4]),)
(array([1, 2, 4]),)
(array([2, 3, 4]),)
(array([0, 3, 4]),)
(array([0, 1, 5]),)
(array([1, 2, 5]),)
(array([2, 3, 5]),)
(array([0, 3, 5]),)
*************************************************
[(  0.,   0.,   0.,   0,   0,   0) (  0., 100.,   0.,   0,   0,   0)
 (100., 100.,   0.,   0,   0,   0) (100.,   0.,   0.,   0,   0,   0)
 ( 50.,  50.,  75., 255, 255, 255) ( 50.,  50., -75., 255, 255, 255)]
[(array([0, 1, 4]),) (array([1, 2, 4]),) (array([2, 3, 4]),)
 (array([0, 3, 4]),) (array([0, 1, 5]),) (array([1, 2, 5]),)
 (array([2, 3, 5]),) (array([0, 3, 5]),)]

Écrire des fichiers de plis à l'aide de plyfile

def write_ply(output_file,text=True):
    points=[
        (0,0,0),
        (0,100,0),
        (100,100,0),
        (100,0,0),
        (50,50,75)
    ]

    face=np.array([
        ((0,1,2),255,0,0),
        ((0,2,3),255,0,0),
        ((0, 1, 4),0,255,0),
        ((1,2,4),0,0,255),
        ((2,3,4),255,255,0),
        ((0,3,4),0,0,0)],
        dtype=[('vertex_index','i4',(3,)),
               ('red','u1'),('green','u1'),
               ('blue','u1')]
    )
    print(face)
    vertex = np.array(points, dtype=[('x', 'f4'), ('y', 'f4'), ('z', 'f4')])
    el = PlyElement.describe(vertex, 'vertex')
    face = PlyElement.describe(face, 'face')
    PlyData([el,face], text=text).write(out_file)

les fichiers ply peuvent généralement être ouverts et visualisés à l'aide du logiciel MESHLAB

image

4.2.2. Utiliser pcl pour lire et écrire (C++)

Lire les fichiers de nuage de points de pli

#include <iostream>

#include <pcl-1.8/pcl/io/pcd_io.h>
#include <pcl-1.8/pcl/point_types.h>
#include <pcl-1.8/pcl/visualization/cloud_viewer.h>
#include <pcl-1.8/pcl/io/ply_io.h>

using namespace std;
int main()
{
    
    
	string ply_file = "C:\\Users\\123\\Desktop\\test7.ply";
	pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);

  	if (pcl::io::loadPLYFile<pcl::PointXYZ>(ply_file,*cloud)==-1)
  	{
    
    
  		return (-1);
  	}
  
  	cout << cloud->width << " " << cloud->height << endl;

	for (size_t i=0;i<cloud->points.size();++i)
	{
    
    
		cout << cloud->points[i].x << " " << cloud->points[i].y << " " << cloud->points[i].z << endl;
	}
  
  	return	(0);
}

Enregistrez le fichier de nuage de points de pli

#include <iostream>

#include <pcl/io/ply_io.h>
#include <pcl/point_types.h>

using namespace std;
int main()
{
    
    
	string ply_file = "test2.ply";
	pcl::PointCloud<pcl::PointXYZRGB> cloud;

	int data[11][6] = {
    
    
		{
    
    8,5,3,255,0,0},
		{
    
    9,0,1,255,0,0},
		{
    
    2,5,3,0,255,0},
		{
    
    0,4,2,0,255,0},
		{
    
    7,2,9,0,0,255},
		{
    
    8,8,4,0,0,255},
		{
    
    9,5,8,255,0,255},
		{
    
    2,5,9,255,0,255},
		{
    
    0,7,5,255,255,0},
		{
    
    11,2,8,255,255,0},
		{
    
    10,9,0,255,255,0}};

	cloud.width = 11;
	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 = data[i][0];
		cloud.points[i].y = data[i][1];
		cloud.points[i].z = data[i][2];
		cloud.points[i].r = data[i][3];
		cloud.points[i].g = data[i][4];
		cloud.points[i].b = data[i][5];
	}


	pcl::io::savePLYFile(ply_file, cloud);
	
	return 0;
}

Enregistrez le fichier de nuage de points de pli

#include <iostream>

#include <pcl/io/ply_io.h>
#include <pcl/point_types.h>

using namespace std;
int main()
{
    
    
	string ply_file = "test2.ply";
	pcl::PointCloud<pcl::PointXYZRGB> cloud;

	int data[11][6] = {
    
    
		{
    
    8,5,3,255,0,0},
		{
    
    9,0,1,255,0,0},
		{
    
    2,5,3,0,255,0},
		{
    
    0,4,2,0,255,0},
		{
    
    7,2,9,0,0,255},
		{
    
    8,8,4,0,0,255},
		{
    
    9,5,8,255,0,255},
		{
    
    2,5,9,255,0,255},
		{
    
    0,7,5,255,255,0},
		{
    
    11,2,8,255,255,0},
		{
    
    10,9,0,255,255,0}};

	cloud.width = 11;
	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 = data[i][0];
		cloud.points[i].y = data[i][1];
		cloud.points[i].z = data[i][2];
		cloud.points[i].r = data[i][3];
		cloud.points[i].g = data[i][4];
		cloud.points[i].b = data[i][5];
	}


	pcl::io::savePLYFile(ply_file, cloud);
	
	return 0;
}

Je suppose que tu aimes

Origine blog.csdn.net/qq_46084757/article/details/125628082
conseillé
Classement