日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

使用PCL库将KITTI数据集可视化

發布時間:2024/3/12 编程问答 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 使用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

而物理距離可以由上圖獲得
由此可以確定點云中相機的視角和方向

viewer->addCoordinateSystem(1.0); /* 通過設置相機參數是用戶從默認的角度和方向觀察點 */ viewer->initCameraParameters(); viewer->setCameraPosition(0.27, 0, -0.08, 1, 0, 0, 0, 0, 1);

解釋一下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
還有一點要注意的,點云標簽的坐標定義是以底面中心為準
由此得到如下轉換:

float x_min = test[num_tar].z - test[num_tar].length/2; float y_min = -test[num_tar].x - test[num_tar].length/2; float z_min = -test[num_tar].y; float x_max = test[num_tar].z + test[num_tar].length/2; float y_max = -test[num_tar].x + test[num_tar].length/2; float z_max = -test[num_tar].y + test[num_tar].length;

矩形框繪制

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数据集可视化的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。