使用PCL库将KITTI数据集可视化
PCL點云可視化
- KITTI數據集淺析
- KITTI數據集簡介
- KITTI基本結構
- Calib
- Velodyne
- 標簽數據解析
- 點云數據可視化
- 創建點云對象
- 創建視窗對象
- 添加點云到視窗
- 相機參數的設置
- 保持窗口打開
- 3D標簽數據可視化
- 先定義一個標簽結構體
- 讀取label,寫入成員變量
- 坐標轉換
- 矩形框繪制
KITTI數據集淺析
KITTI數據集的數據采集平臺裝配有2個灰度攝像機,2個彩色攝像機,一個Velodyne 64線3D激光雷達,4個光學鏡頭,以及1個GPS導航系統。
本次重點討論激光雷達數據部分
KITTI數據集簡介
1.KITTI是目前國際上最大的自動駕駛場景下的計算機視覺算法評測數據集
2.KITTI包含市區、鄉村和高速公路等場景采集的真實圖像數據,每張圖像中最多達15輛車和30個行人,還有各種程度的遮擋與截斷。
3.對于3D物體檢測,label細分為car, van, truck, pedestrian, pedestrian(sitting), cyclist, tram以及misc組成。
4. 激光雷達為1臺Velodyne HDL-64E激光,掃描頻率10Hz,64線,0.09°角度分辨率,2cm探測精度,每秒130萬點數,探測距離120m
KITTI基本結構
Calib: 000000~007480.txt 傳感器標定數據
Image_2: 000000~007480.png 彩色相機圖像
Label_2: 000000~007480.txt 標注數據集合
Velodyne: 000000~007480.bin 激光點云數據
Velodyne_reduced: 空
Calib
Velodyne
激光雷達點云數據采用浮點數二進制文件保存。保存激光雷達坐標系下,激光點( x , y , z ) 坐標和反射率r信息,每一幀平均12萬個激光點。
讀取KITTI數據集中velodyne的.bin文件
pcl::PointCloud<PointXYZI>::Ptr points (new pcl::PointCloud<PointXYZI>); for (int 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();寫入.pcd文件
pcl::PCDWriter writer; writer.write<PointXYZI> (outfile, *points, false); PointCloud<PointXYZ>::Ptr cloud(new PointCloud<PointXYZ>);用vscode打開.pcd文件,可以直觀的看到每行都由x,y,z,r(反射強度,一般沒用)組成
標簽數據解析
先打開一個label看一下
一共15個字段
值得提一下的是alpha和rotation_y的區別和聯系,rotation_y和alpha都是以逆時針方向為負。它們之間可以互相轉換。
從示意圖可以分析得到:alpha = rotation_y - theta
注意:直接對數據集轉換,會有輕微的精度損失
點云數據可視化
本文主要使用PCL庫中的PCLVisualizer類對點云數據進行可視化操作
創建點云對象
讀取pcd文件,載入點云數據
PointCloud<PointXYZ>::Ptr cloud(new PointCloud<PointXYZ>); if (io::loadPCDFile("test.pcd", *cloud) == -1)return -1;創建視窗對象
給標題欄定義名稱“3D viewer”。viewer的類型為boost::shared_ptr,只能共享指針,保證該指針在整個程序中全局使用,不引起內存錯誤
boost::shared_ptr<visualization::PCLVisualizer> viewer(new visualization::PCLVisualizer("3D viewer"));設置窗口viewer的背景為全黑色
viewer->setBackgroundColor(0, 0, 0);如果不想要單色的點云,可以按z軸方向深度渲染一下點云的色彩
pcl::visualization::PointCloudColorHandlerGenericField<pcl::PointXYZ> fildColor(cloud, "z");添加點云到視窗
viewer->addPointCloud<PointXYZ>(cloud, fildColor, "sample cloud"); viewer->setPointCloudRenderingProperties(visualization::PCL_VISUALIZER_POINT_SIZE, 2, "sample cloud"); /*設置XYZ三個坐標軸的大小和長度,該值也可以缺省 查看復雜的點云圖像會讓用戶沒有方向感,為了讓用戶保持正確的方向判斷,需要顯示坐標軸。三個坐標軸X(R,紅色)Y(G,綠色)Z(B,藍色)分別用三種不同顏色的圓柱體代替 */將點云數據添加到視窗中,并為其定義一個唯一的字符串作為ID號,利用此ID號保證其他成員方法也能表示該點云。
*多次調用addPointCloud()可以實現多個點云的疊加
*還有updatePointCloud()方法實現點云的更新
相機參數的設置
這張圖清楚地展示了相機坐標系和雷達坐標系的關系
? Camera: x = right, y = down, z = forward
? Velodyne: x = forward, y = left, z = up
? GPS/IMU: x = forward, y = left, z = up
而物理距離可以由上圖獲得
由此可以確定點云中相機的視角和方向
解釋一下setCameraPostion中的幾個變量
posX,posY,posZ: 觀察點坐標
viewX,viewY,viewZ: 視角朝向
upX,upY,upZ: 向上方向
看下效果
還沒有涉及可視化label,此處只是為了方便對照
可以看到,不用手動拖拽,設置好后,運行窗口默認和相機同一視角
保持窗口打開
通過while循環保持窗口一直處于打開狀態,并且按照規定時間刷新窗口
while (!viewer->wasStopped()) {viewer->spinOnce(100);boost::this_thread::sleep(boost::posix_time::microseconds(1000)); }3D標簽數據可視化
在KITTI數據集的標簽里,我們用到它標簽數據里的x,y,z,length,height,width6個數據,來求解pcl繪制矩形所需要的6個角點坐標
先定義一個標簽結構體
struct Kitti_Label {//類別std::string cls;// 9 classes//截斷程度 from 0(截斷)-1(非截斷)float truncated;//遮擋程度 0 完全可見 1 小部分遮擋 2 大部分遮擋 3 完全遮擋short occlusion;//物體的觀察角度 范圍[-pi,pi]float alpha;//物體的2維邊界框,左上角和右下角的像素坐標float pt1[2];float pt2[2];//三維物體的尺寸,單位mfloat height;float width;float length;//三維物體的位置(相機坐標系下,單位m)float x;float y;float z;//三維物體的空間方向,在相機坐標系下,相對于y軸的旋轉角,范圍[-pi,pi]float rotation_y; }讀取label,寫入成員變量
ifstream txtfile("test.txt"); Kitti_Label test[100]; string s;int num_tar = 0; while (getline( txtfile, s)) {string sTmp[15];istringstream istr(s);int i = 0;while(!istr.eof()){istr >> sTmp[i];i++;}test[num_tar].cls = sTmp[0]test[num_tar].x = atof(sTmp[11].c_str());test[num_tar].y = atof(sTmp[12].c_str());test[num_tar].z = atof(sTmp[13].c_str());test[num_tar].height = atof(sTmp[8].c_str());test[num_tar].width = atof(sTmp[9].c_str());test[num_tar].length = atof(sTmp[10].c_str());}坐標轉換
參照文章上面圖片的坐標系,從相機三維坐標到激光雷達坐標,對應關系如下:
z->x
y->-z
x->-y
還有一點要注意的,點云標簽的坐標定義是以底面中心為準
由此得到如下轉換:
矩形框繪制
viewer->addCube (x_min, x_max, y_min, y_max, z_min, z_max, 255, 0, 0, name, 0); viewer->setShapeRenderingProperties(pcl::visualization::PCL_VISUALIZER_REPRESENTATION,pcl::visualization::PCL_VISUALIZER_REPRESENTATION_WIREFRAME, name);參考的一些博客:
https://blog.csdn.net/zjguilai/article/details/90168564
https://blog.csdn.net/qq_37534947/article/details/106628308
參考的資料不勝枚舉,本文如有使用您的資料,卻遺漏引出鏈接,請與博主聯系,謝謝!
總結
以上是生活随笔為你收集整理的使用PCL库将KITTI数据集可视化的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 舍弗勒城市车辆转向系统研究完成,可实现全
- 下一篇: 基于计算机视觉的梦幻西游辅助脚本(只用于