ZED 景深攝影機範例#5/8 – Spatial mapping

本文為 ZED 景深攝影機原廠範例,共有八個範例,請根據 ZED 的範例程式頁面,取得 C++ / Python / C# 等範例原始碼。說明如下:

  1. Hello ZED: 入門範例,說明如何連接 ZED 攝影機,並於終端機中顯示裝置序列編號。
  2. Image Capture: 開啟 ZED 攝影機,取得影像,並於終端機中顯示時間戳記、影像尺寸。
  3. Depth Perception: 取得畫面的深度資料與點雲,並於終端機中顯示指定點的距離。
  4. Camera Tracking: 啟用位置追蹤,可即時更新攝影機的位置與指向。
  5. Spatial Mapping: 啟用地圖繪製,可擷取環境的網格或融合點雲。
  6. 3D Object Detection: 偵測畫面中的物體,並進行 3D 定位 (只適用於 ZED 2 機型)。
  7. Using Sensors: 取得攝影機的 IMU、氣壓計與磁力感測器資料。
  8. Body Tracking: 追蹤人體骨架

範例05 – 空間映射

本範例將說明如何操作 ZED 立體攝影機來取得您所在環境的即時 3D 重建結果。程式會對 500 張畫面進行空間映射、取得網格、濾波並將其存成一個 OBJ 檔。

註:原廠頁面每段都提供了 C++ / Python / C# 的範例程式,在此只列出 Python 範例

前置作業

  • 下載最新版的 ZED SDK (請點我)
  • 下載 Image Capture 範例程式,提供 C++, Python 與 C# 等版本
  • 在 Windows 或 Linux OS上,建置 C++ 環境(請點我) 或執行 Python 範例,本系列文章將使用 Python (教學請點我)

程式總覽

開啟攝影機

首先要初始化攝影機。本範例將使用 HD720 / 60 fps 模式 (這樣的視野較廣) 來確認攝影機追蹤結果是否可靠。另外也選定右手坐標系統,Y軸朝上為正,這也是 Meshlab 這類 3D 檢視軟體較常採用的坐標系統。

# Create a ZED camera object
zed = sl.Camera()

# Set configuration parameters
init_params = sl.InitParameters()
init_params.camera_resolution = sl.RESOLUTION.HD720  # Use HD720 video mode (default fps: 60)
init_params.coordinate_system = sl.COORDINATE_SYSTEM.RIGHT_HANDED_Y_UP # Use a right-handed Y-up coordinate system
init_params.coordinate_units = sl.UNIT.METER  # Set units in meters

# Open the camera
err = zed.open(init_params)
if err != sl.ERROR_CODE.SUCCESS:
    exit(1)
open the camera

啟用位置追蹤

首先用 enablePositionalTracking() 來啟用位置追蹤,接著才能啟用空間映射。

tracking_parameters = sl.PositionalTrackingParameters()
err = zed.enable_positional_tracking(tracking_parameters)
if err != sl.ERROR_CODE.SUCCESS:
    exit(1)
enable positional tracking

啟用空間映射

空間映射的前置作業與位置追蹤類似:先建立 SpatialMappingParameters 類別,並以此作為參數來呼叫 enableSpatialMapping()

mapping_parameters = sl.SpatialMappingParameters()
err = zed.enable_spatial_mapping(mapping_parameters)
if err != sl.ERROR_CODE.SUCCESS:
    exit(1)
enable spatial mapping

本範例無法詳細介紹 SpatialMappingParameters 類別,更多資訊請參考 API 文件。

執行即時 3D 重建

對指定區域進行空間映射時,不需要在 grab() 迴圈中呼叫任何函式。ZED SDK 會在背景檢查是否有新的影像、深度與位置資訊,並根據這些資料以非同步方式自動建立 3D 地圖。

本範例只會擷取 500 張畫面 (frame)、檢查 3D 映射狀態,接著停止迴圈來取得最終的網格。

# Grab data during 3000 frames
i = 0
py_mesh = sl.Mesh()  # Create a Mesh object
runtime_parameters = sl.RuntimeParameters()
while i < 3000:
    if zed.grab(runtime_parameters) == sl.ERROR_CODE.SUCCESS:
        # In background, spatial mapping will use new images, depth and pose to create and update the mesh. No specific functions are required here.
        mapping_state = zed.get_spatial_mapping_state()
        # Print spatial mapping state
        print("\rImages captured: {0} / 3000 || {1}".format(i, mapping_state))
        i = i + 1
run live 3D reconstruction

取得網格

取得 500 張畫面的 3D 地圖之後,即可透過 extractWholeSpatialMap() 語法取得儲存於Mesh 物件中的網格。本函式會持續執行直到取得完整的網格為止。

err = zed.extract_whole_spatial_map(py_mesh) # Extract the whole mesh
extract mesh

注意:映射過程中可能是以非同步方式來取得網格,詳細資訊請參考 Using Spatial Mapping API

This mesh can be filtered (如有必要) 來移除重複的點與不必要的面。接著將網格存為 OBJ 檔以便後續使用。

filter_params = sl.MeshFilterParameters()
filter_params.set(sl.MESH_FILTER.LOW)
py_mesh.filter(filter_params) # Filter the mesh (remove unnecessary vertices and faces)
py_mesh.save("mesh.obj") # Save the mesh in an obj file
filter and save as .obj file

停用模組並離開程式

網格取得並存檔完成之後,記得要依序停用映射與追蹤模組(順序要對!),並在結束程式之前關閉攝影機。

# Disable tracking and mapping and close the camera
zed.disable_spatial_mapping()
zed.disable_positional_tracking()
zed.close()
disable modules and exit

更多範例

如果您想知道如何擷取周遭環境的即時 3D 網格,並將其作為圖層顯示於攝影機影像上的畫,請參考 Live 3D Reconstruction 範例。

下一步

您現在已經知道如何取得來自 ZED 立體攝影機的 image, depth, odometry and 3D mapping data。後續的物件偵測範例將說明如何在 3D 環境中偵測與追蹤人體。

註:本文經授權之後翻譯自 https://www.stereolabs.com/docs/tutorials/spatial-mapping/

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。