【问题标题】:Which openCv function can be used to compute BEV perspective transformation given a point coordinates and the camera extrinsics/intrinsics?哪个 openCv 函数可用于计算给定点坐标和相机外部/内部的 BEV 透视变换?
【发布时间】:2021-03-22 21:18:09
【问题描述】:

我的相机有3x3intrinsics4x3extrinsics矩阵,通过cv2.calibrateCamera()获得

现在我想使用这些参数来计算从相机获得的帧中任何给定坐标的BEV (Bird Eye View) 变换。

哪个openCv函数可用于计算给定点坐标和相机extrinsics和/或intrinsics3x3 matricesBEV透视变换?

我在以下帖子中发现了一些非常相关的内容:https://deepnote.com/article/social-distancing-detector/ 基于https://www.pyimagesearch.com/2014/08/25/4-point-opencv-getperspective-transform-example/

他们使用cv2.getPerspectiveTransform() 来获得3X3 matrix,但我不知道这个矩阵是否代表intrinsicsextrinsecs 或其他东西。然后他们通过以下方式使用这样的矩阵转换点列表:

#Assuming list_downoids is the list of points to be transformed and matrix is the one obtained above
list_points_to_detect = np.float32(list_downoids).reshape(-1, 1, 2)
transformed_points = cv2.perspectiveTransform(list_points_to_detect, matrix)

我真的需要知道是否可以使用cv2.perspectiveTransform 函数来计算转换,或者是否有其他更好的方法可以使用extrinsicsintrinsics 或两者兼而有之,而无需重复使用框架,因为我已经将检测到/选择的坐标保存在数组中。

【问题讨论】:

    标签: python-3.x matrix computer-vision cv2 camera-calibration


    【解决方案1】:

    答案是:如果您没有关于图像像素的距离相关信息,就不可能计算场景的 BEV。

    想一想:假设您有一个垂直屏幕的图片:鸟瞰图将是一条线。现在假设这个屏幕正在显示风景的图像,并且这个屏幕的图片与风景本身的图片无法区分。 BEV 仍然是一条线(虽然是一条彩色的)。

    现在,假设您有完全相同的图片,但这次不是屏幕图片,而是风景图片。然后,鸟瞰图不是一条线,更接近我们通常想象的 BEV。

    最后,让我声明一下,OpenCV 无法知道您的图片是否在描述其他物体的平面(即使给定相机参数),因此,它无法计算场景的 BEV。函数cv2.perspectiveTransform 需要您向其传递一个单应性 矩阵(您可以使用cv2.findHomography() 获得一个矩阵,但您还需要一些有关图像的距离信息)。

    很抱歉给出否定的答案,但仅考虑到相机的内在和外在校准矩阵,无法解决您的问题。

    【讨论】:

    • 如果您有至少 3 个点的 3D 坐标(我认为您只需要三个,但越多越好),那么您应该可以使用 cv2.findHomography 来完成。那里几乎没有技术,所以我建议您寻找教程。我记得在那里发现了一些非常有趣的:)
    • 例如,如果你的图片代表一个斜面(我认为道路足够像平面一样)我认为本教程会对你有所帮助:learnopencv.com/tag/findhomography
    • 非常感谢您的宝贵时间。每个点我都有xywidthheight。我认为这可行。
    • 不客气!祝你好运 ! (顺便说一句,如果您能接受我的回答,我将不胜感激,谢谢!):)
    • 透视变换需要四个点对(两个视图各有四个点)。我会回答是,因为如果您将“鸟瞰图”理解为平面到平面的转换,那么 getPerspectiveTransform 和 warpPerspective 将起作用。只有当您尝试扭曲不是平面的 3D 场景图片时,事情才会崩溃。可以合理地假设“BEV”意味着映射平面。
    【解决方案2】:

    经过深入调查,我找到了一个很好的解决方案:

    projection matrixextrinsicintrinsic 相机矩阵之间的乘积

    cv2.getPerspectiveTransform() 在我们没有相机参数时给我们Projection Matrix

    cv2.warpPerspective() 转换图像本身。

    对于上述问题,我们不需要这两个函数,因为我们已经有了extrinsicsintrinsecs 和图像中点的坐标。

    考虑到上面介绍的情况,我编写了一个函数来转换为BEV 一个列表o 点list_x_y 给定intrinsicsextrinsics

        def compute_point_perspective_transformation(intrinsics, extrinsics, point_x_y):
        """Auxiliary function to project a specific point to BEV
            
            Parameters
            ----------
            intrinsics (array)     : The camera intrinsics matrix
            extrinsics (array)     : The camera extrinsics matrix
            point_x_y (tuple[x,y]) : The coordinates of the point to be projected to BEV
            
            Returns
            ----------
            tuple[x,y] : the projection of the point
        """
            # Using the camera calibration for Bird Eye View
            intrinsics_matrix = np.array(intrinsics, dtype='float32')
            #In the intrinsics we have parameters such as focal length and the principal point
    
            extrinsics_matrix = np.array(extrinsics, dtype='float32')
            #The extrinsic matrix stores the position of the camera in global space
            #The 1st 3 columns represents the rotation matrix and the last is a translation vector
            extrinsics = extrinsics[:, [0, 1, 3]]
    
            #We removed the 3rd column of the extrinsics because it represents the z coordinate (0)
            projection_matrix = np.matmul(intrinsics_matrix, extrinsics_matrix)
    
            # Compute the new coordinates of our points - cv2.perspectiveTransform expects shape 3
            list_points_to_detect = np.array([[point_x_y]], dtype=np.float32)
            transformed_points = cv2.perspectiveTransform(list_points_to_detect, projection_matrix)
            return transformed_points[0][0][0], transformed_points[0][0][1]
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-04-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-01-22
      • 1970-01-01
      相关资源
      最近更新 更多