Kitti Odometry .bin点云文件转pcd

时间:2024-04-03 15:32:43

最近在研究Kitti Odometry数据集,要做的一个事情是把velodyne中的.bin点云文件转成pcd并可视化。

本博客介绍用ROS pcl实现以上转换。

(备注:这里需要用到pcl_ros这个包,之前配置的ROS不知道为啥缺少了这个包,导致之后编译的时候一直报错,提示找不到pcl_rosConfig.cmake pcl_ros-config.cmake,之后卸载了ROS又重新安装了一下,就解决了!)

进入正文:

1.建立工作空间

打开终端,输入:

mkdir -p catkin_ws/src

2.创建程序包

cd catkin_ws/src
catkin_create_pkg kitti_velodyne pcl_ros roscpp

3.创建bin2pcd.cpp

在 kitti_velodyne文件夹中的src文件夹中创建一个.cpp文件,粘上以下代码:

#include <boost/program_options.hpp>
#include <pcl/point_types.h>
#include <pcl/io/pcd_io.h>
#include <pcl/common/point_operators.h>
#include <pcl/common/io.h>
#include <pcl/search/organized.h>
#include <pcl/search/octree.h>
#include <pcl/search/kdtree.h>
#include <pcl/features/normal_3d_omp.h>
#include <pcl/filters/conditional_removal.h>
#include <pcl/segmentation/sac_segmentation.h>
#include <pcl/segmentation/extract_clusters.h>
#include <pcl/surface/gp3.h>
#include <pcl/io/vtk_io.h>
#include <pcl/filters/voxel_grid.h>
 
#include <iostream>
#include <fstream>
 
using namespace pcl;
using namespace std;
 
namespace po = boost::program_options;
 
int main(int argc, char **argv){
	///The file to read from.
	string infile;
 
	///The file to output to.
	string outfile;
 
	// Declare the supported options.
	po::options_description desc("Program options");
	desc.add_options()
		//Options
		("infile", po::value<string>(&infile)->required(), "the file to read a point cloud from")
		("outfile", po::value<string>(&outfile)->required(), "the file to write the DoN point cloud & normals to")
		;
	// Parse the command line
	po::variables_map vm;
	po::store(po::parse_command_line(argc, argv, desc), vm);
 
	// Print help
	if (vm.count("help"))
	{
		cout << desc << "\n";
		return false;
	}
 
	// Process options.
	po::notify(vm);
 
	// load point cloud
	fstream input(infile.c_str(), ios::in | ios::binary);
	if(!input.good()){
		cerr << "Could not read file: " << infile << endl;
		exit(EXIT_FAILURE);
	}
	input.seekg(0, ios::beg);
 
	pcl::PointCloud<PointXYZI>::Ptr points (new pcl::PointCloud<PointXYZI>);
 
	int i;
	for (i=0; input.good() && !input.eof(); i++) {
		PointXYZI point;
		input.read((char *) &point.x, 3*sizeof(float));
		input.read((char *) &point.intensity, sizeof(float));
		points->push_back(point);
	}
	input.close();
 
	cout << "Read KTTI point cloud with " << i << " points, writing to " << outfile << endl;
 
    //pcl::PCDWriter writer;
 
    // Save DoN features
    pcl::io::savePCDFileBinary(outfile, *points);
    //writer.write<PointXYZI> (outfile, *points, false);
}

 4.修改 kitti_velodyne文件夹中的CMakeLists.txt文件,修改后的文件如下:

cmake_minimum_required(VERSION 2.8.3)
project(kitti_velodyne) 

add_compile_options(-std=c++11)


find_package(catkin REQUIRED COMPONENTS
pcl_ros
roscpp
)

find_package(PCL 1.7 REQUIRED)

catkin_package(
  INCLUDE_DIRS include
  CATKIN_DEPENDS roscpp pcl_ros
)

include_directories(
 include
 ${catkin_INCLUDE_DIRS}
)
link_directories(${PCL_LIBRARY_DIRS})

add_executable(bin2pcd src/bin2pcd.cpp)   



target_link_libraries(bin2pcd
  ${catkin_LIBRARIES}
  ${PCL_LIBRARIES}
)

注意:

add_executable(bin2pcd src/bin2pcd.cpp)   

target_link_libraries(bin2pcd
  ${catkin_LIBRARIES}
  ${PCL_LIBRARIES}
)

里面的bin2pcd是命名的可执行程序。

5.编译

打开终端,

cd catkin_ws
catkin_make

编译成功后提示:

Kitti Odometry .bin点云文件转pcd

6.程序测试

使用kitti odometry 中的velodyne, 01序列中的000000.bin 到 000020.bin 进行测试。

(1)在catkin_ws新建一个文件夹bin,放入000000.bin到000020.bin 共21个.bin文件;

Kitti Odometry .bin点云文件转pcd

(2)在catkin_ws新建一个文件夹pcd,用来储存转换后的pcd文件。

(3)打开终端输入:

i=1;
for x in /home/ywyue/catkin_ws/bin/*.bin; 
do /home/ywyue/catkin_ws/devel/lib/kitti_velodyne/bin2pcd --infile $x --outfile /home/ywyue/catkin_ws/pcd/$i.pcd; 
let i=i+1; 
done

注意:以上命令中有一些参数需要根据实际情况修改:

/home/ywyue/catkin_ws/bin/*.bin  是储存 .bin文件的路径;

/home/ywyue/catkin_ws/devel/lib/kitti_velodyne/bin2pcd  是可执行程序的路径;

/home/ywyue/catkin_ws/pcd/$i.pcd  是放转换后的pcd文件的路径;

如果程序正常运行的话,会在pcd文件夹里看到转换后的文件:

Kitti Odometry .bin点云文件转pcd

7.pcd 可视化

这里可视化的具体编译过程就不赘述了,我这里没用catkin编译,直接用的cmake,相应文件如下:

(1)view_pcd.cpp如下:

#include <iostream>
#include <pcl/io/pcd_io.h> //PCL的PCD格式文件的输入输出头文件 
#include <pcl/point_types.h> //PCL对各种格式的点的支持头文件 
#include <pcl/visualization/cloud_viewer.h>//点云查看窗口头文件

 
int main(int argc, char **argv) {
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>); // 创建点云(指针)
    if (pcl::io::loadPCDFile<pcl::PointXYZ>("/home/ywyue/catkin_ws/pcd/1.pcd", *cloud) == -1) //* 读入PCD格式的文件,如果文件不存在,返回-1
{
        PCL_ERROR("Couldn't read file test_pcd.pcd \n"); //文件不存在时,返回错误,终止程序。
       return (-1);
    }
    pcl::visualization::CloudViewer viewer("Simple Cloud Viewer");//直接创造一个显示窗口
    viewer.showCloud(cloud);//在这个窗口显示点云
    while (!viewer.wasStopped())
      {
      }
    return 0;
}

其中代码行:

pcl::io::loadPCDFile<pcl::PointXYZ>("/home/ywyue/catkin_ws/pcd/1.pcd", *cloud) == -1

中的 /home/ywyue/catkin_ws/pcd/1.pcd 请改成相应的pcd文件的路径。

(2)CMakeLists.txt如下:

cmake_minimum_required(VERSION 2.6) 
project(view_pcd) 
find_package(PCL 1.2 REQUIRED) 
include_directories(${PCL_INCLUDE_DIRS}) 
link_directories(${PCL_LIBRARY_DIRS}) 
add_definitions(${PCL_DEFINITIONS}) 
add_executable(view_pcd view_pcd.cpp) 
target_link_libraries (view_pcd ${PCL_LIBRARIES}) 
install(TARGETS pcl_test RUNTIME DESTINATION bin)

(3)编译之后运行程序,便可看到pcd文件啦~

Kitti Odometry .bin点云文件转pcd

 

感谢:

https://github.com/yanii/kitti-pcl/blob/master/src/kitti2pcd.cpp

https://www.e-learn.cn/content/qita/1862427

https://blog.csdn.net/qq_35491306/article/details/82903371

https://blog.csdn.net/qq_16949707/article/details/53311083