点云的处理
一、激光点云
激光点云指的是由三维激光雷达设备扫描得到的空间点的数据集,每一个点云都包含了三维坐标(XYZ)和激光反射强度(Intensity),其中强度信息会与目标物表面材质与粗糙度、激光入射角度、激光波长以及激光雷达的能量密度有关。
上述自定义数据包中的自定义点云(CustomPoint)格式 :
uint32 offset_time # offset time relative to the base time
float32 x # X axis, unit:m
float32 y # Y axis, unit:m
float32 z # Z axis, unit:m
uint8 reflectivity # reflectivity, 0~255
uint8 tag # livox tag
uint8 line # laser number in lidar
Livox雷达驱动程序发布点云格式CustomMsg、PointCloud2、pcl::PointXYZI、pcl::PointXYZINormal解析_代码多少钱一两的博客-CSDN博客
二、基于python的点云相加及保存
2.1 两个单独点云
# coding:utf-8
import open3d as o3d
import numpy as np# --------------------------- 加载点云 ---------------------------
print("->正在加载点云... ")
pcd1 = o3d.io.read_point_cloud("lidar1.pcd")
pcd2 = o3d.io.read_point_cloud("lidar2.pcd")print("原始点云pcd1:", pcd1)
print("原始点云pcd2:", pcd2)pcd_all = pcd2 + pcd1
print("原始点云pcd_all:", pcd_all)
# ==============================================================
o3d.visualization.draw_geometries([ pcd_all], window_name="wechat 394467238 ")
path_new = '/home/nvidia/LVI_ws/src/r3live_tools/calib/pcds/final_4.pcd'
o3d.io.write_point_cloud(path_new, pcd_all)
2.2 文件夹下所有点云相加
# coding:utf-8
import open3d as o3d
import numpy as np
import glob
import os
import shutil
import sysdef find_glob(pathname):# type:(str) -> list"""Find files by glob."""files = glob.glob(pathname)if len(files) > 0:return fileselse:print("Error: " + pathname + " is not found")exit()
# --------------------------- 加载点云 ---------------------------
print("->正在加载点云... ")
pcd_dir = "/home/nvidia/LVI_ws/src/r3live_tools/calib/pcds/"
pcd_files = find_glob(pcd_dir + "out_*.pcd")
print(len(pcd_files))
pcd_all=o3d.io.read_point_cloud(pcd_files[0])
for i in range(1,len(pcd_files)):print(pcd_files[i])pcd_dir_single = pcd_files[i]pcd= o3d.io.read_point_cloud(pcd_dir_single)print("原始点云pcd:", pcd)pcd_all=pcd_all+pcdprint("原始点云pcd_all:", pcd_all)
# ==============================================================
o3d.visualization.draw_geometries([ pcd_all], window_name="wechat 394467238 ")
path_new = '/home/nvidia/LVI_ws/src/r3live_tools/calib/pcds/final_5.pcd'
o3d.io.write_point_cloud(path_new, pcd_all)
存在的问题:该点云相加的方法,没有办法完成强度信息的载入,对激光雷达进行相加会丢失轻度信息。
三、基于c++的点云相加
3.1 简单的点云的输出
CMakeLists.txt
cmake_minimum_required(VERSION 2.6)project(pcl_test)find_package(PCL REQUIRED)include_directories(${PCL_INCLUDE_DIRS})link_directories(${PCL_LIBRARY_DIRS})add_definitions(${PCL_DEFINITIONS})add_executable(pcl_test pcl_test.cpp)target_link_libraries (pcl_test ${PCL_LIBRARIES})install(TARGETS pcl_test RUNTIME DESTINATION bin)
pcl_test.cpp
#include <iostream>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>int main (int argc, char argv)
{pcl::PointCloud<pcl::PointXYZ> cloud;// Fill in the cloud datacloud.width = 5;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 = 1024 * rand () / (RAND_MAX + 1.0f);cloud.points[i].y = 1024 * rand () / (RAND_MAX + 1.0f);cloud.points[i].z = 1024 * rand () / (RAND_MAX + 1.0f);}pcl::io::savePCDFileASCII ("test_pcd.pcd", cloud);std::cerr << "Saved " << cloud.points.size () << " data points to test_pcd.pcd." << std::endl;for (size_t i = 0; i < cloud.points.size (); ++i)std::cerr << " " << cloud.points[i].x << " " << cloud.points[i].y << " " << cloud.points[i].z << std::endl;return (0);
}
2.2 带强度信息的点云的读取和保存
#include <iostream>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/visualization/cloud_viewer.h>
#include <iostream>
#include <pcl/io/io.h>
#include <pcl/io/pcd_io.h>//pcd 读写类相关的头文件。
#include <pcl/io/ply_io.h>
#include <pcl/point_types.h>//PCL中支持的点类型头文件。
#include <boost/thread/thread.hpp>using namespace std; void viewerOneOff(pcl::visualization::PCLVisualizer& viewer)
{viewer.setBackgroundColor(0.0, 0.5, 0.0);//设置背景颜色
}
int main (int argc, char argv)
{typedef pcl::PointXYZI PointType;typedef pcl::PointCloud<PointType> PointCloud;std::string filename = "/home/nvidia/LVI_ws/src/r3live_tools/calib/pcds/out_1681117387928485.pcd";std::string pcd_file = "/home/nvidia/LVI_ws/src/r3live_tools/calib/pcds/01.pcd";PointCloud::Ptr cloud_in(new PointCloud);//pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);if (-1 == pcl::io::loadPCDFile<PointType>(filename, *cloud_in)){std::cout << "Load pcd file fail!" << std::endl;return -1;}std::cout << cloud_in->points.size() << std::endl;pcl::PCDWriter writer;writer.write(pcd_file, *cloud_in); std::cout << "从点云数据中读取: " << (*cloud_in).width * (*cloud_in).height <<"字节,数据中所包含的有效字段为: " << pcl::getFieldsList(*cloud_in) << std::endl;std::cout << (*cloud_in).points.size() << std::endl;// pcl::visualization::CloudViewer viewer("First Cloud Viewer");// viewer.showCloud(cloud_in);//显示// viewer.runOnVisualizationThreadOnce(viewerOneOff);// std::cout << "PCL Test OK!\\n";}