You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用cv2.fisheye.undistortPoints完成畸变与无畸变空间的点坐标转换

核心认知误区

你调用接口得到的结果不符合预期,本质是不熟悉两个函数的输入输出约定:

  • cv2.fisheye.undistortPoints 默认输出的是归一化相机坐标(z=1平面的坐标,没有经过内参缩放平移),不是你需要的无畸变像素坐标,所以会得到负数小数结果。
  • cv2.fisheye.distortPoints 要求输入的是无畸变空间的归一化坐标,你直接传入无畸变像素坐标,自然会得到完全偏离的结果。
  • 你做整图去畸变时给initUndistortRectifyMap传了R(单位矩阵)和P(和原内参K一致)参数,单点转换时没有对应传入相同参数,也会导致结果不匹配。

正确调用方式

1. 畸变像素坐标 → 无畸变像素坐标

对应你将原图(200,150)转换为去畸变后像素坐标的需求,调用时需要传入和整图去畸变一致的R和P参数:

import numpy as np
import cv2

# 你的相机参数
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],
    ]
)

# 输入畸变像素坐标,维度要求为Nx1x2
distorted_point = np.array([[[200, 150]]], dtype=np.float32)
# 传入和initUndistortRectifyMap一致的R、P参数,直接输出无畸变像素坐标
undistorted_pixel = cv2.fisheye.undistortPoints(distorted_point, K, D, R=np.eye(3), P=K)
print(undistorted_pixel)
# 输出结果和你观测到的[[[60, 43]]]一致

2. 无畸变像素坐标 → 畸变像素坐标

对应你将去畸变后的(60,43)转换回原图畸变坐标的需求,需要先把像素坐标转成归一化坐标再调用接口:

# 输入无畸变像素坐标
undistorted_pixel = np.array([[[60, 43]]], dtype=np.float32)
# 第一步:无畸变像素坐标转归一化坐标(减去主点,除以对应焦距)
undistorted_norm = np.zeros_like(undistorted_pixel)
undistorted_norm[..., 0] = (undistorted_pixel[..., 0] - K[0, 2]) / K[0, 0]
undistorted_norm[..., 1] = (undistorted_pixel[..., 1] - K[1, 2]) / K[1, 1]
# 第二步:调用distortPoints得到畸变像素坐标
distorted_pixel = cv2.fisheye.distortPoints(undistorted_norm, K, D)
print(distorted_pixel)
# 输出结果和你输入的原图坐标[[[200, 150]]]一致

注意事项

  • 输入坐标的维度必须为(N, 1, 2)的浮点类型,否则会出现报错或者异常输出
  • 如果你整图去畸变时使用的P参数和原内参K不一致(比如做了缩放、裁剪),单点转换时undistortPoints的P参数必须和整图去畸变时的参数完全一致才能匹配
  • 批量转换大量点时,上述方法的效率远高于遍历map1、map2查找对应坐标

内容的提问来源于stack exchange,提问作者Kyle

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.07 11:18:03