如何通过投影矩阵从KITTI获得鸟瞰图?

时间:2019-11-02 05:48:45

标签: python opencv matrix-transform kitti

目标是从KITTI图像(数据集)中获得鸟瞰图,而我有了投影矩阵(3x4)。

有很多方法可以生成转换矩阵。对于鸟瞰图,我已经阅读了一些友好的数学表达式,例如:

OpenCV - Projection, homography matrix and bird's eye view

H12 = H2 * H1-1 = A R A-1 = P * A-1

并且x = kitti dataset camera projection matrix中的Pi * Tr * X

但是这些选项都不符合我的目的。

PYTHON代码

将numpy导入为np 导入cv2

image = cv2.imread('Data / RGB / 000007.png')

maxHeight,maxWidth = image.shape [:2]

M具有3x4尺寸

M = np.array(([[721.5377,0.0,609.5593,44.85728],[0.0,721.5377,72.854,0.2163791],[0.0,0.0,1.0,.002745884])

在这里需要3x3尺寸的M矩阵

warped = cv2.warpPerspective(image,M,(maxWidth,maxHeight))

显示原始图像和变形的图像

cv2.imshow(“原始图片”

cv2.imshow(“变形”,变形)

cv2.waitKey(0)

我需要知道如何管理Projection Matrix以获得鸟瞰图。

到目前为止,我尝试过的所有操作都向我扔了变形的图像,甚至没有任何信息可以满足我的需求。

This is a example of image from the KITTI database.

This is other example of image from the KITTI database.

在左侧,显示了检测3D(上方)和2D(下方)汽车的图像。右边是我要获取的鸟瞰图。因此,我需要获取转换矩阵来转换界定汽车边界的盒子的坐标。

1 个答案:

答案 0 :(得分:1)

这是我的代码,用于手动构建鸟瞰图转换:

cv::Mat1d CameraModel::getInversePerspectiveMapping(double pixelPerMeter, cv::Point const & origin) const {
    double f = pixelPerMeter * cameraPosition()[2];
    cv::Mat1d R(3,3);
    R <<  0, 1, 0,
          1, 0, 0,
          0, 0, 1;

    cv::Mat1d K(3,3);
    K << f, 0, origin.x, 
         0, f, origin.y, 
         0, 0, 1;
    cv::Mat1d transformtoGround = K * R * mCameraToCarMatrix(cv::Range(0,3), cv::Range(0,3));
    return transformtoGround * mIntrinsicMatrix.inv();
}

函数内部使用的成员变量/函数是

  • mCameraToCarMatrix:一个4x4矩阵,用于保持从摄像机坐标系到汽车坐标系的均匀刚性变换。相机的轴为x右,y向下,z向前。汽车的轴为x向前,y向左,z向上。在此函数内,仅使用mCameraToCarMatrix的旋转部分。
  • mIntrinsicMatrix:保存摄像机固有参数的3x3矩阵
  • cameraPosition()[2]:摄像机在汽车坐标系中的Z坐标(高度)。与mCameraToCarMatrix(2,3)相同。

函数参数:

  • pixelPerMeter:鸟瞰图图像的分辨率。在XY平面上1米的距离将转换为鸟瞰图像中的pixelPerMeter像素。
  • origin:摄像机在鸟瞰图图像中的位置

您可以将变换矩阵作为cv::initUndistortRectifyMaps()传递到newCameraMatrix,然后使用cv::remap创建鸟瞰图图像。