如何通过nuscenes数据集中的image_name导出homography矩阵

地平线bev参考算法的官方文档中介绍了单帧可视化推理脚本infer.py的使用,输入为6V环视图像和homography矩阵,6V环视图像可以从解压的nuscenes数据集中获取,homography矩阵则是需要从nuscenes数据集中获取相机参数信息后经计算获得。

本文将介绍一种简单的homography矩阵导出方法,输入为nuscens数据集中6张环视图片的文件名"fileneme",输出为homography矩阵。

1. 安装nuscenes-devkit

首先在python环境中安装nuscenes-devkit,参考命令如下 :

pip install nuscenes-devkit

2. v1.0-mini数据集下载

在nuscenes官网(https://www.nuscenes.org/nuscenes#download)下载v1.0-mini数据集后解压,解压后的目录如下所示:

├── v1.0-mini
    ├── maps
    ├── samples
    ├── sweeps
    └── v1.0-mini

3. 导出homography矩阵的代码

from nuscenes.nuscenes import NuScenes 
import numpy as np
from pyquaternion import Quaternion

def get_homography_by_cam(sensor2ego_translation, sensor2ego_rotation, camera_intrinsic):
    #将旋转矩阵转为四元数
    rotation = Quaternion(sensor2ego_rotation).rotation_matrix
    ego2sensor_r = np.linalg.inv(rotation)
    ego2sensor_t = sensor2ego_translation @ ego2sensor_r.T
    ego2sensor = np.eye(4)
    ego2sensor[:3, :3] = ego2sensor_r.T
    ego2sensor[3, :3] = -np.array(ego2sensor_t)

    camera_intrinsic = np.array(camera_intrinsic)

    viewpad = np.eye(4)
    viewpad[
            : camera_intrinsic.shape[0], : camera_intrinsic.shape[1]
        ] = camera_intrinsic
    ego2img = viewpad @ ego2sensor.T
    return ego2img
if __name__ == "__main__":
    #初始化,这里以v1.0-mini数据集为例
    nusc = NuScenes(version='v1.0-mini', dataroot='../v1.0-mini', verbose=True)

    #6张图像的文件名
    #要注意这里的输入顺序必须遵循:
    #FRONT_LEFT,FRONT,FRONT_RIGHT,BACK_LEFT,BACK,BACK_RIGHT
    image_list=[
    'n008-2018-08-01-15-16-36-0400__CAM_FRONT_LEFT__1533151603504799.jpg',
    'n008-2018-08-01-15-16-36-0400__CAM_FRONT__1533151603512404.jpg',
    'n008-2018-08-01-15-16-36-0400__CAM_FRONT_RIGHT__1533151603520482.jpg',
    'n008-2018-08-01-15-16-36-0400__CAM_BACK_LEFT__1533151603547405.jpg',
    'n008-2018-08-01-15-16-36-0400__CAM_BACK__1533151603537558.jpg',
    'n008-2018-08-01-15-16-36-0400__CAM_BACK_RIGHT__1533151603528113.jpg'
    ]
    # 获取数据集中所有的sample
    # 包含'token','calibrated_sensor_token','filename','channel'等信息
    sample_data=nusc.sample_data 
    # 获取传感器定义:
    # 包含'token','sensor_toker','translation','rotation','camera_intrinsic'等信息
    cali_sensor=nusc.calibrated_sensor
    
    translation=[]
    rotation=[]
    cam_intrinsic=[]
    ego2imgs=[]
    for i,img in enumerate(image_list):
        print(img) 
        for sample in sample_data:
            if img in sample["filename"]:
                #1. 选择输入图片的name来获取捕获该图片的"calibrated_sensor_token"
                calibrated_sensor_token=(sample["calibrated_sensor_token"])
                print("calibrated_sensor_token:",calibrated_sensor_token)
                #2.根据"calibrated_sensor_token"获取传感器的"translation"、
                # "rotation"、和"camera_intrinsic"等参数
                for sensor in cali_sensor:
                    if sensor["token"]==calibrated_sensor_token: 
                        #获取translation矩阵
                        sensor2ego_translation=np.array(sensor["translation"])
                        translation.append(sensor2ego_translation)
                        #获取rotation矩阵
                        sensor2ego_rotation=np.array(sensor["rotation"])
                        rotation.append(sensor2ego_rotation)
                        #获取相机内参矩阵
                        camera_intrinsic=np.array(sensor["camera_intrinsic"])
                        cam_intrinsic.append(camera_intrinsic)
                        #计算homography矩阵
                        ego2img=get_homography_by_cam(
                        sensor2ego_translation,
                        sensor2ego_rotation, 
                        camera_intrinsic
                        )
                        ego2imgs.append(ego2img)
    #导出translation矩阵,旋转矩阵、相机内参矩阵、homo矩阵
    translation=np.array(translation)
    np.save("translation",translation)
    rotation=np.array(rotation)
    np.save("rotation",rotation)
    cam_intrinsic=np.array(cam_intrinsic)
    np.save("cam_intrinsic",cam_intrinsic)
    ego2imgs=np.array(ego2imgs)
    np.save("ego2imgs",ego2imgs)

生成的ego2imgs.npy即为homography矩阵。

4. 参考链接

https://blog.csdn.net/zyw2002/article/details/128292100