如何使用 cv2.fisheye.undistortPoints 将扭曲空间中的点转换为未扭曲空间中的点?

Posted

技术标签:

【中文标题】如何使用 cv2.fisheye.undistortPoints 将扭曲空间中的点转换为未扭曲空间中的点?【英文标题】:How do I use cv2.fisheye.undistortPoints to convert a point in distorted space to one in undistorted space? 【发布时间】:2021-08-18 17:35:01 【问题描述】:

我正在尝试使用 opencv 鱼眼功能将未扭曲空间中的特征映射回扭曲空间。我可以通过以下代码成功地将我的图像从相机扭曲的鱼眼图像转换为常规空间:

DIM = (953, 720)
K = np.array(
    [
        [407.0259762535615, 0.0, 488.89663712932474],
        [0.0, 409.25366832487896, 388.1998354574297],
        [0.0, 0.0, 1.0],
    ]
)
D = np.array(
    [
        [-0.04485892302426824],
        [0.0787884305594057],
        [-0.08374236678783106],
        [0.027626067632899026],
    ]
)
img = np.zeros((720, 953, 3), dtype=np.uint8)
img = cv2.rectangle(img, (200, 150), (300, 200), (255, 255, 255), -1)
map1, map2 = cv2.fisheye.initUndistortRectifyMap(K, D, np.eye(3), K, DIM, cv2.CV_16SC2)
undistorted_img = cv2.remap(
    img, map1, map2, interpolation=cv2.INTER_LINEAR, borderMode=cv2.BORDER_CONSTANT
)
# The rectangle is now found at 60, 43 in undistorted_img.  This code works.

但是,当我想映射一个点(任一方向)时,我无法使用 cv2.fisheye.undistortPoints 或 distortPoints 将一个点从一个空间移动到另一个空间。通过使用尺寸为 720 x 953 的图像,我在 x,y 200,150 处放置了一个点。在未失真的图像中,该点现在位于 60,43。但是,我无法使用任一函数映射这两个点。这是我的代码和输出:

cv2.fisheye.undistortPoints(np.array([[[200, 150]]], dtype=np.float32), K, D)
# returns array([[[-1.0488918, -0.8601203]]], dtype=float32)
cv2.fisheye.distortPoints(np.array([[[200, 150]]], dtype=np.float32), K, D)
# returns array([[[1064.9419,  822.5983]]], dtype=float32)
cv2.fisheye.undistortPoints(np.array([[[60, 34]]], dtype=np.float32), K, D)
# Returns array([[[-4.061374 , -3.3357866]]], dtype=float32)
cv2.fisheye.distortPoints(np.array([[[60, 34]]], dtype=np.float32), K, D)
# array([[[1103.0706 ,  738.13654]]], dtype=float32)

这些都不符合我在图像转换本身中看到的。我对 distortPoints 和 undistortPoints 有什么不了解的地方?谢谢!

【问题讨论】:

当然还有额外的参数,你必须指定内在函数和图像大小,在正确的地方扭曲和不扭曲。 【参考方案1】:

我认为您需要estimate new camera matrix 以确保不失真。

points = np.array([[[200, 150]]]).astype(np.float32)
newcameramtx = cv2.fisheye.estimateNewCameraMatrixForUndistortRectify(
    K, D, DIM, None, balance=1)
dst = cv2.fisheye.undistortPoints(points, K, D, None, newcameramtx)
# [[[323.35104 242.06458]]]

【讨论】:

以上是关于如何使用 cv2.fisheye.undistortPoints 将扭曲空间中的点转换为未扭曲空间中的点?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用本机反应创建登录以及如何验证会话

如何在自动布局中使用约束标识符以及如何使用标识符更改约束? [迅速]

如何使用 AngularJS 的 ng-model 创建一个数组以及如何使用 jquery 提交?

如何使用laravel保存所有行数据每个行名或相等

如何使用 Math.Net 连接矩阵。如何使用 Math.Net 调用特定的行或列?

WSARecv 如何使用 lpOverlapped?如何手动发出事件信号?