手把手帶你玩轉Nuscenes資料集2——nuScenes lidarseg and panoptic教程
在之前的文章中,已經介紹了Nusences資料集的基本使用——包括資料集的簡介、下載下傳、資料讀取等等,還不清楚的可以點選連結跳轉學習本節将對Nusences的擴充包lidarseg 和 panoptic進行講解,lidarseg和panoptic在教程中有很多功能是類似的,是以我們把它們放在一個教程中。當然你也可以自己選擇lidarseg或panoptic資料集,即針對特定的任務使用某個資料集。下面就讓我們一起來學習,一起真正的玩轉Nuscenes資料集叭
準備工作✨✨✨
在上一節中,我們已經下載下傳了mini資料集,這裡依舊可以用到。但不同的是,這節我們還會下載下傳其他的資料(lidarseg 和 panoptic),我們需要讓這些資料集存儲在特定位置,即讓不同資料集之間有一定的檔案關系,以便後面成功讀取✅✅✅
再次強調,本次實驗我們将用到三個資料集,分别是v1.0_mini,lidarseg 和 panoptic。【注意:v1.0_mini在上節我們已經下載下傳,lidarseg 和 panoptic我們仍然使用其mini版本】下面先來介紹如何下載下傳lidarseg 和 panoptic資料集,方法很簡單,我們去官網直接點選下載下傳即可,下載下傳示意圖如下:
為了給大家帶來友善,這裡也可以在浏覽器搜尋框輸入下面網址直接下載下傳兩個資料集:
https://www.nuscenes.org/data/nuScenes-lidarseg-mini-v1.0.tar.bz2 #下載下傳lidarseg-mini資料集
https://www.nuscenes.org/data/nuScenes-panoptic-v1.0-mini.tar.gz #下載下傳panoptic資料集
上文提到,我們應将3個資料集提取到規定的特殊位置,即将剛剛下載下傳壓縮檔案解壓到/data/sets/nuscenes中,你的檔案夾結構應該是這樣的:
看到這個結構,可能大家還有些許疑惑,這裡貼出我檔案夾的路徑相信大家就一目了然了。【注意:這裡還是要提醒一下大家,在下圖中的v1.0-mini檔案夾中,包括各種.josn格式的檔案,其中包括lidarseg.json、panoptic.json、category.json三個檔案,這三個檔案都是從lidarseg和panoptic資料集中複制過來的】
資料讀取✨✨✨
上文已經下載下傳好了資料集,且檔案夾路徑配置妥當,現在就可以大展身手,讓我們一起來玩轉Nuscenes叭⚽⚽⚽
導入相關庫并加載資料集
這裡的dataroot為資料集存放位置【這裡我使用的是相對路徑,你也可以使用絕對路徑】,運作成功後應出現如下的資訊:
%matplotlib inline
from nuscenes import NuScenes
nusc = NuScenes(version='v1.0-mini', dataroot='data\\sets\\nuscenes', verbose=True)
可以從結果中看到,我們已經加載了nuscenes-lidarseg和nuscenes-panoptic,這裡和上一節加載資料集結果的不同之處就在這裡。
lidarseg和panoptic資料集的點統計
- lidarseg
讓我們通過檢視lidarseg資料集中有哪些類以及屬于每個類的點數來快速了解一下lidarseg資料集。類将根據點的數量按升序排序(因為下面的sort_by='count');你也可以通過設定sort_by='name'或sort_by='index'分别對類名或類索引進行排序。
# nuscenes-lidarseg
nusc.list_lidarseg_categories(sort_by='count')
輸出結果:
使用list_lidarseg_categories,您可以通過檢視最左邊的列來獲得每個類名所屬的索引。你也可以使用lidarseg_idx2name_mapping來擷取索引所對應的類名。
nusc.lidarseg_idx2name_mapping
輸出結果:
相反,你也可以使用lidarseg_name2idx_mapping來從類名屬性中獲得索引。
nusc.lidarseg_name2idx_mapping
輸出結果:
- panoptic
- 對于nuScenes-panoptic,它與nuScenes-lidarseg共享相同的成員變量lidarseg_idx2name_mapping和lidarseg_names2idx_mapping。類似地,您可以從nuScenes-panoptic資料集檢查每個語義類别的點數。唯一要做的就是添加gt_from='panoptic'參數。預設情況下,gt_from = ' lidarseg '。
-
# nuscenes-panoptic
nusc.list_lidarseg_categories(sort_by='count', gt_from='panoptic')
- 輸出結果:
- 您可能已經注意到某些類别的點數在lidarseg和panoptic資料集之間略有不同。原因是執行個體之間的重疊點在nuScenes-panoptic中被設定為noise(類别0),你可以看到noise類别的點數增加了,而總點數保持不變。
panoptic資料集的instance統計
執行個體統計資訊是專屬于全景資料集的。為此,我們提供了list_panoptic_instances()函數。你可以将sort_by設定為['count', 'index', 'name']之一。該函數将計算每幀的執行個體數,執行個體總數(唯一的對象ID)和執行個體狀态(一個執行個體可能有多個狀态)。它還計算每個類别的統計資料,包括一個執行個體跨越的幀數的平均值和标準偏差,以及每個執行個體的點數的平均值和标準偏差。
nusc.list_panoptic_instances(sort_by='count')
輸出結果:
擷取lidarseg和panoptic的sample token的統計資訊⭐⭐⭐
首先,讓我們擷取一個sample。
my_sample = nusc.sample[5]
之後使用get_sample_lidarseg_stats來擷取lidarseg的樣本統計資訊。通過執行sort_by='count',類和它們各自的頻率計數将按升序列印;你也可以在這裡執行sort_by='name'和sort_by='index'。
# nuscenes-lidarseg
nusc.get_sample_lidarseg_stats(my_sample['token'], sort_by='count')
輸出結果:
類似地,通過添加gt_from='panoptic',我們可以使用相同的函數來使用panoptic資料集獲得類别頻率計數。正如在list_lidarseg_categories()中提到的,點計數可能與lidarseg稍有不同,這是因為在nuscens -panoptic中,多個執行個體的重疊點被設定為noise。
# nuscenes-panoptic
nusc.get_sample_lidarseg_stats(my_sample['token'], sort_by='count', gt_from='panoptic')
輸出結果:
渲染lidarseg标簽⭐⭐⭐
在最初的nuScenes devkit中,即我們上一節所介紹的資料集中,您可以将一個sample_data_token傳遞到render_sample_data中,以呈現點雲的鳥瞰圖。這些點會根據與自我車的距離被着色。現在有了擴充的nuScenes devkit,您所需要做的就是設定show_lidarseg=True來顯示pointcloud的類标簽。【這裡你也可以設定with_anns = Ture,看看和with_anns=False的差別】
sample_data_token = my_sample['data']['LIDAR_TOP']
nusc.render_sample_data(sample_data_token,
with_anns=False,
show_lidarseg=True)
輸出結果:
但如果你隻想專注于特定的類别呢?考慮到前面列印的點雲統計資訊,假設您隻對卡車和汽車感興趣。你可以從統計資料中看到屬于這些類的類索引【汽車的索引為17,卡車的索引為23】,然後将這些索引的數組傳遞到filter_lidarseg_labels中,如下所示:
nusc.render_sample_data(sample_data_token,
with_anns=False,
show_lidarseg=True,
filter_lidarseg_labels=[17, 23])
輸出結果:
如上圖所示,現在隻有屬于卡車和拖車的點雲中的點被過濾出來,以滿足您的觀看需求。此外,還可以使用show_lidarseg_legend顯示一個圖例,該圖例訓示每個類的顔色。
nusc.render_sample_data(sample_data_token,
with_anns=False,
show_lidarseg=True,
show_lidarseg_legend=True)
輸出結果:
渲染panoptic标簽⭐⭐⭐
與lidarseg類似,也使用相同的函數來呈現panoptic标簽(全景标簽)。參數的差別是show_panoptic=True。預設情況下,show_lidarseg和show_panoptic都被設定為False。如果兩者都設定為True,即show_lidarseg=True, show_panoptic=True, lidarseg将會優先渲染。
sample_data_token = my_sample['data']['LIDAR_TOP']
nusc.render_sample_data(sample_data_token,
with_anns=False,
show_lidarseg=False,
show_panoptic=True)
輸出結果:
你可以看到同一類别的不同的車輛執行個體,會顯示不同的顔色。類似地,您可以使用filter_lidarseg_labels和show_lidarseg_legend=True來顯示特定事物和物品類别的全景标簽,以及類别圖例。注意這兩個參數在lidarseg和panoptic資料集之間也是共享的。
# show trucks and car
nusc.render_sample_data(sample_data_token,
with_anns=False,
show_panoptic=True,
filter_lidarseg_labels=[17, 23])
輸出結果:
# show stuff category legends
nusc.render_sample_data(sample_data_token,
with_anns=False,
show_lidarseg=False,
show_lidarseg_legend=True,
show_panoptic=True)
輸出結果:
在圖像中渲染lidarseg和panoptic 标簽⭐⭐⭐
如果你想要将點雲疊加到相機對應的圖像中,你可以像使用原始nuScenes devkit一樣使用render_pointcloud_in_image,但是要設定show_lidarseg=True(記住要設定render_intensity=False)。與render_sample_data類似,您可以使用filter_lidarseg_labels過濾檢視特定的類。您可以使用show_lidarseg_legend在渲染中顯示一個圖例。
# nuscenes-lidarseg
nusc.render_pointcloud_in_image(my_sample['token'],
pointsensor_channel='LIDAR_TOP',
camera_channel='CAM_FRONT',
render_intensity=False,
show_lidarseg=True,
filter_lidarseg_labels=[17, 23, 24],
show_lidarseg_legend=True)
輸出結果:
同樣,這個函數支援show_panoptic=True模式,将顯示全景标簽而不是語義标簽。隻顯示物品類别的圖例。【對語義标簽和全景标簽不清楚的戳傳送門了解詳情】
# nuscenes-panoptic
nusc.render_pointcloud_in_image(my_sample['token'],
pointsensor_channel='LIDAR_TOP',
camera_channel='CAM_FRONT',
render_intensity=False,
show_lidarseg=False,
filter_lidarseg_labels=[17, 23, 24],
show_lidarseg_legend=True,
show_panoptic=True)
渲染sample(例如lidar、radar and all camera)⭐⭐⭐
就像在原始的nuScenes devkit中一樣,可以使用render_sample一次渲染所有的傳感器。在擴充的nuScenes devkit中,你可以設定show_lidarseg=True來檢視lidarseg标簽。與上面的方法類似,您可以使用filter_lidarseg_labels隻顯示您希望看到的類。
# nuscenes-lidarseg
nusc.render_sample(my_sample['token'],
show_lidarseg=True,
filter_lidarseg_labels=[17, 23])
輸出結果:
要使用render_sample顯示panoptic标簽,隻需設定show_panoptic=True
# nuscenes-panoptic
nusc.render_sample(my_sample['token'],
show_lidarseg=False,
filter_lidarseg_labels=[17, 23],
show_panoptic=True)
輸出結果:
使用lidarseg/panoptic标簽為給定的相機傳感器渲染場景
你也可以使用你選擇的相機的lidarseg标簽來渲染整個場景(filter_lidarseg_labels參數也可以在這裡使用)。讓我們先選一個場景:
my_scene = nusc.scene[0]
然後我們将scene token傳遞給render_scene_channel_lidarseg,這裡設定了filter_lidarseg_labels=[18, 28],表示我們隻對建築車輛和人造物體感興趣(在這裡,我們設定verbose=True來生成一個視窗,讓我們可以看到随機的幀)。此外,您還可以使用dpi(調整雷射雷達點的大小)和imsize(調整渲染圖像的大小)來調整渲染的美學效果。
# nuscenes-lidarseg
import os
nusc.render_scene_channel_lidarseg(my_scene['token'],
'CAM_FRONT',
filter_lidarseg_labels=[18, 28],
verbose=True,
dpi=100,
imsize=(1280, 720))
通過添加show_panoptic=True,這個函數也适用于panoptic标簽。
# # nuscenes-panoptic
import os
nusc.render_scene_channel_lidarseg(my_scene['token'],
'CAM_BACK',
filter_lidarseg_labels=[18, 24, 28],
verbose=True,
dpi=100,
imsize=(1280, 720),
show_panoptic=True)
需要注意的是,這裡的輸出結果都是視訊,這裡不好進行展示,大家自己操作時就明白了。當然,我們可以通過out_folder參數傳遞一個路徑到你想要儲存視訊的檔案夾。
# nuscenes-lidarseg
nusc.render_scene_channel_lidarseg(my_scene['token'],
'CAM_BACK',
filter_lidarseg_labels=[18, 28],
verbose=True,
dpi=100,
imsize=(1280, 720),
render_mode='video',
out_folder=os.path.expanduser('video_image'))
渲染場景的所有cameras與lidarseg/panoptic标簽
你可以用lidarseg标簽為所有相機一次性渲染整個場景作為視訊。假設在這種情況下,我們對屬于driveable surfaces 和 cars【即标簽為17、24】的點感興趣。
# nuscenes-lidarseg
import os
nusc.render_scene_lidarseg(my_scene['token'],
filter_lidarseg_labels=[17, 24],
verbose=True,
dpi=100,
out_path=os.path.expanduser('video_image//my_rendered_scene.avi'))
這和上面的一樣都為視訊,大家練習時自行觀看。
可視化雷射雷達分割預測
在以上所有函數中,已經渲染的LiDAR點雲的标簽都是ground truth。如果您已經訓練了一個模型來分割LiDAR點雲,并在nuScenes-lidarseg資料集上運作它,您也可以使用nuScenes-lidarseg可視化您的模型的預測!你的每個.bin檔案應該是numpy.uint8數組。
import os
my_sample = nusc.sample[80]
sample_data_token = my_sample['data']['LIDAR_TOP']
my_predictions_bin_file = os.path.join('data\\sets\\nuscenes\\lidarseg\\v1.0-mini', sample_data_token + '_lidarseg.bin')
nusc.render_pointcloud_in_image(my_sample['token'],
pointsensor_channel='LIDAR_TOP',
camera_channel='CAM_BACK',
render_intensity=False,
show_lidarseg=True,
filter_lidarseg_labels=[22, 23],
show_lidarseg_legend=True,
lidarseg_preds_bin_path=my_predictions_bin_file)
輸出結果:
可視化雷射雷達全景預測
類似地,全景預測結果也可以被渲染!每個.npz檔案都應該是一個壓縮的 numpy.uint16數組
import os
my_sample = nusc.sample[87]
sample_data_token = my_sample['data']['LIDAR_TOP']
my_predictions_bin_file = os.path.join('/data/sets/nuscenes/panoptic/v1.0-mini', sample_data_token + '_panoptic.npz')
nusc.render_pointcloud_in_image(my_sample['token'],
pointsensor_channel='LIDAR_TOP',
camera_channel='CAM_BACK',
render_intensity=False,
show_lidarseg=False,
filter_lidarseg_labels=[17,22, 23, 24],
show_lidarseg_legend=True,
lidarseg_preds_bin_path=my_predictions_bin_file,
show_panoptic=True)
輸出結果:
總結
最後了,說點什麼呢,上面這些東西你看是很難看明白的,自己動手多敲一敲,哪裡不明白敲敲代碼看看輸出的結果,好記性不如爛筆頭,加油各位閱讀此文章前建議先看看上一節文章:對Nuscenes資料集一無所知,手把手帶你玩轉Nusences資料集
這部分官方是給了參考的代碼的,可以再Google colab上直接運作,這裡給出官方的連結:Nuscenes使用教程,但是我想大家還是自己敲一敲會印象更加深刻