点云PCD解析
点云头部信息
£ .PCD v0.7 - Point Cloud Data file format
VERSION 0.7
FIELDS x y z timestamp intensity ring azimuth
SIZE 4 4 4 8 1 2 4
TYPE F F F F U U F
COUNT 1 1 1 1 1 1 1
WIDTH 3378
HEIGHT 128
VIEWPOINT 0 0 0 1 0 0 0
POINTS 432384
DATA binary
实现逻辑
var { resolve } = require('path')
const { Buffer } = require('node:buffer');
fs.readFile(resolve(__dirname,'2.pcd'),(err,buffer) => {
if (err) {
console.error('Error reading file:',err);
return;
}
const headerEndIndex = buffer.indexOf(Buffer.from('DATA binary')) + 'DATA binary'.length;
const header = buffer.slice(0,headerEndIndex).toString('utf-8');
console.log(header)
// 提取文件头部信息
const headerLines = header.split('\n');
let width,height,pointsCount,fields;
headerLines.forEach(line => {
if (line.startsWith('FIELDS')) {
fields = line.split(' ').slice(1); // 获取字段名(x, y, z, rgb)
}
if (line.startsWith('WIDTH')) {
width = parseInt(line.split(' ')[1]); // 获取点云的宽度
}
if (line.startsWith('HEIGHT')) {
height = parseInt(line.split(' ')[1]); // 获取点云的高度
}
if (line.startsWith('POINTS')) {
pointsCount = parseInt(line.split(' ')[1]); // 获取点的总数
}
});
const pointData = buffer.slice(headerEndIndex); // 获取二进制数据部分
let points = [];
let offset = 0;
// 每个点包含 4 字节 x, 4 字节 y, 4 字节 z, 4 字节 rgb (一共 16 字节)
for (let i = 0; i < pointsCount; i++) {
const x = pointData.readFloatLE(offset); // 读取 4 字节的浮动类型 x
const y = pointData.readFloatLE(offset + 4); // 读取 4 字节的浮动类型 y
const z = pointData.readFloatLE(offset + 8); // 读取 4 字节的浮动类型 z
const rgb = pointData.readUInt32LE(offset + 12); // 读取 4 字节的 RGB(整数)
const intensity = pointData.readFloatLE(offset + 16);
// 提取 RGB 颜色值的红、绿、蓝分量(假设是以 8 位的形式存储)
const r = (rgb >> 16) & 0xFF;
const g = (rgb >> 8) & 0xFF;
const b = rgb & 0xFF;
// 将每个点的数据存储到数组中
points.push({ x,y,z,rgb: { r,g,b } ,intensity});
// 移动到下一个点的位置(16 字节)
offset += 20;
}
});