KITTI-二進位制點雲資料集使用筆記
歡迎訪問我的個人Blog:zengzeyu.com
前言
官網資料集說明:http://www.cvlibs.net/datasets/kitti/raw_data.php
資料集詳細說明論文:http://www.cvlibs.net/publications/Geiger2013IJRR.pdf
KITTI的鐳射雷達型號為 Velodyne HDL-64E ,具體資訊如下:
Velodyne HDL-64E rotating 3D laser scanner
- 10 Hz
- 64 beams
- 0.09 degree angular resolution
- 2 cm distanceaccuracy
- collecting∼1.3 million points/second
- field of view: 360°
- horizontal, 26.8°
- vertical, range: 120 m
針對鐳射雷達點雲資料集使用的資訊在 KITTI_README.TXT 中有詳細說明,檔案下載地址:Code to use the KITTI data set with PCL
Velodyne 3D laser scan data
===========================
The velodyne point clouds are stored in the folder 'velodyne_points'. To
save space, all scans have been stored as Nx4 float matrix into a binary
file using the following code:
stream = fopen (dst_file.c_str(),"wb");
fwrite(data,sizeof(float),4*num,stream);
fclose(stream);
Here, data contains 4*num values, where the first 3 values correspond to
x,y and z, and the last value is the reflectance information. All scans
are stored row-aligned, meaning that the first 4 values correspond to the
first measurement. Since each scan might potentially have a different
number of points, this must be determined from the file size when reading
the file, where 1e6 is a good enough upper bound on the number of values:
// allocate 4 MB buffer (only ~130*4*4 KB are needed)
int32_t num = 1000000;
float *data = (float*)malloc(num*sizeof(float));
// pointers
float *px = data+0;
float *py = data+1;
float *pz = data+2;
float *pr = data+3;
// load point cloud
FILE *stream;
stream = fopen (currFilenameBinary.c_str(),"rb");
num = fread(data,sizeof(float),num,stream)/4;
for (int32_t i=0; i<num; i++) {
point_cloud.points.push_back(tPoint(*px,*py,*pz,*pr));
px+=4; py+=4; pz+=4; pr+=4;
}
fclose(stream);
x,y and y are stored in metric (m) Velodyne coordinates.
KITTI點雲資料集讀取與轉換
官方原始碼解讀
Code to use the KITTI data set with PCL下載的原始碼資料夾中的src/kitti2pcd.cpp 中這個函式:
void readKittiPclBinData(std::string &in_file, std::string& out_file)
{
// load point cloud
std::fstream input(in_file.c_str(), std::ios::in | std::ios::binary);
if(!input.good()){
std::cerr << "Could not read file: " << in_file << std::endl;
exit(EXIT_FAILURE);
}
input.seekg(0, std::ios::beg);
pcl::PointCloud<pcl::PointXYZI>::Ptr points (new pcl::PointCloud<pcl::PointXYZI>);
int i;
for (i=0; input.good() && !input.eof(); i++) {
pcl::PointXYZI point;
input.read((char *) &point.x, 3*sizeof(float));
input.read((char *) &point.intensity, sizeof(float));
points->push_back(point);
}
input.close();
// g_cloud_pub.publish( points );
std::cout << "Read KTTI point cloud with " << i << " points, writing to " << out_file << std::endl;
pcl::PCDWriter writer;
// Save DoN features
writer.write< pcl::PointXYZI > (out_file, *points, false);
}
這個函式是最重要的從 KITTI 中讀取 .bin 檔案轉 .pcd 檔案。
可執行完整程式碼
下面貼本人完整程式碼,程式碼功能:
- 讀取資料夾下.bin 檔案
- 按照檔名進行排序(雖然預設已經排好序)
- 轉為.pcd 檔案,並儲存
- 傳送到 rviz 進行顯示(可選)
//
// Created by zzy on 3/14/18.
//
#include <ctime>
#include "ros/ros.h"
#include "fcn_data_gen/ground_remove.h"
static ros::Publisher g_cloud_pub;
static std::vector<std::string> file_lists;
void read_filelists(const std::string& dir_path,std::vector<std::string>& out_filelsits,std::string type)
{
struct dirent *ptr;
DIR *dir;
dir = opendir(dir_path.c_str());
out_filelsits.clear();
while ((ptr = readdir(dir)) != NULL){
std::string tmp_file = ptr->d_name;
if (tmp_file[0] == '.')continue;
if (type.size() <= 0){
out_filelsits.push_back(ptr->d_name);
}else{
if (tmp_file.size() < type.size())continue;
std::string tmp_cut_type = tmp_file.substr(tmp_file.size() - type.size(),type.size());
if (tmp_cut_type == type){
out_filelsits.push_back(ptr->d_name);
}
}
}
}
bool computePairNum(std::string pair1,std::string pair2)
{
return pair1 < pair2;
}
void sort_filelists(std::vector<std::string>& filists,std::string type)
{
if (filists.empty())return;
std::sort(filists.begin(),filists.end(),computePairNum);
}
void readKittiPclBinData(std::string &in_file, std::string& out_file)
{
// load point cloud
std::fstream input(in_file.c_str(), std::ios::in | std::ios::binary);
if(!input.good()){
std::cerr << "Could not read file: " << in_file << std::endl;
exit(EXIT_FAILURE);
}
input.seekg(0, std::ios::beg);
pcl::PointCloud<pcl::PointXYZI>::Ptr points (new pcl::PointCloud<pcl::PointXYZI>);
int i;
for (i=0; input.good() && !input.eof(); i++) {
pcl::PointXYZI point;
input.read((char *) &point.x, 3*sizeof(float));
input.read((char *) &point.intensity, sizeof(float));
points->push_back(point);
}
input.close();
// g_cloud_pub.publish( points );
std::cout << "Read KTTI point cloud with " << i << " points, writing to " << out_file << std::endl;
pcl::PCDWriter writer;
// Save DoN features
writer.write< pcl::PointXYZI > (out_file, *points, false);
}
int main(int argc, char **argv)
{
// ros::init(argc, argv, "ground_remove_test");
// ros::NodeHandle n;
// g_cloud_pub = n.advertise< pcl::PointCloud< pcl::PointXYZI > > ("point_chatter", 1);
std::string bin_path = "../velodyne/binary/";
std::string pcd_path = "../velodyne/pcd/";
read_filelists( bin_path, file_lists, "bin" );
sort_filelists( file_lists, "bin" );
for (int i = 0; i < file_lists.size(); ++i)
{
std::string bin_file = bin_path + file_lists[i];
std::string tmp_str = file_lists[i].substr(0, file_lists[i].length() - 4) + ".pcd";
std::string pcd_file = pcd_path + tmp_str;
readKittiPclBinData( bin_file, pcd_file );
}
return 0;
}
以上。
相關文章
- HWS二進位制筆記筆記
- 使用POST方法傳輸二進位制資料
- 複雜二進位制資料
- CentOS安裝使用二進位制方式mysql5.6筆記CentOSMySql筆記
- JavaScript 讀寫二進位制資料JavaScript
- 僅做筆記用:base64字串轉換為十六進位制形式表示的二進位制資料筆記字串
- iOS 二進位制流轉化-專案筆記iOS筆記
- 二進位制與二進位制運算
- Erlang學習筆記(七)二進位制型與位語法筆記
- 進位制詳解:二進位制、八進位制和十六進位制
- 利用vstruct解析二進位制資料Struct
- Redis中快取二進位制資料Redis快取
- JavaScript 二進位制、八進位制與十六進位制JavaScript
- SQLite入門(二)讀寫二進位制資料SQLite
- nodeJS-使用buffer類處理二進位制資料NodeJS
- (二進位制)
- 二進位制
- 十進位制——二 (八、十六 )進位制
- ORACLE使用函式對二進位制、十進位制、十六進位制數互相轉換Oracle函式
- 二進位制,八進位制,十進位制,十六進位制的相互轉換
- java之二進位制與資料型別Java資料型別
- 6-二進位制資料-字串-字元列表字串字元
- 【進位制轉換】二進位制、十六進位制、十進位制、八進位制對應關係
- 二進位制、十進位制與十六進位制相互轉化
- java中二進位制、八進位制、十進位制、十六進位制的轉換Java
- 二進位制,八進位制,十進位制,十六進位制之間的轉換
- Python 進位制互相轉換(二進位制、十進位制和十六進位制)Python
- 計算機基礎進位制轉換(二進位制、八進位制、十進位制、十六進位制)計算機
- 二進位制轉十進位制快速方法
- JAVA 二進位制,八進位制,十六進位制,十進位制間進行相互轉換Java
- 什麼是二進位制?二進位制如何轉換?
- JavaScript二進位制陣列建立注意點JavaScript陣列
- 有趣的二進位制3—浮點數
- 04 二進位制
- 記憶體資料的十六進位制Print記憶體
- Mysql資料庫二進位制日誌的管理MySql資料庫
- 大話二進位制,八進位制,十進位制,十六進位制之間的轉換
- JavaScript十進位制轉換為二進位制JavaScript