什么是Project Tango镜头失真模型?

rha*_*oto 6 opencv google-project-tango

项目探戈C API文档说,TANGO_CALIBRATION_POLYNOMIAL_3_PARAMETERS镜头失真建模为:

x_corr_px = x_px(1 + k1*r2 + k2*r4 + k3*r6)y_corr_px = y_px(1 + k1*r2 + k2*r4 + k3*r6)

也就是说,无失真的坐标是一个幂级数功能扭曲的坐标.Java API中还有另一个定义,但该描述不够详细,无法确定函数映射的方向.

我在使事情正确注册方面遇到了很多麻烦,我怀疑映射实际上可能是相反的方向,即失真的坐标是未失真坐标的幂级数.如果摄像机校准是使用OpenCV生成的,那么问题的原因可能是OpenCV文档与自身相矛盾.最容易找到和理解的描述是OpenCV摄像机校准教程,它与Project Tango文档一致:

在此输入图像描述

但另一方面,OpenCV API文档指定映射采用另一种方式:

在此输入图像描述

我在OpenCV上的实验表明它的API文档看起来是正确的并且教程是错误的.正k1(所有其他失真参数设置为零)表示枕形失真,负k1表示桶形失真.这与维基百科关于布朗康拉迪模型的说法相符,并且与Tsai模型相反.请注意,失真可以通过任何方式建模,具体取决于使数学更方便的原因.我针对这种不匹配打开了一个针对OpenCV 的错误.

所以我的问题是:Project Tango镜头失真模型是否与OpenCV中实现的相同(尽管文档)?

这是我从彩色相机拍摄的图像(可以看到轻微的枕形):

在此输入图像描述

以下是Tango服务报告的相机校准:

distortion = {double[5]@3402}
[0] = 0.23019999265670776
[1] = -0.6723999977111816
[2] = 0.6520439982414246
[3] = 0.0
[4] = 0.0
calibrationType = 3
cx = 638.603
cy = 354.906
fx = 1043.08
fy = 1043.1
cameraId = 0
height = 720
width = 1280
Run Code Online (Sandbox Code Playgroud)

以下是如何在python中使用OpenCV解决:

>>> import cv2
>>> src = cv2.imread('tango00042.png')
>>> d = numpy.array([0.2302, -0.6724, 0, 0, 0.652044])
>>> m = numpy.array([[1043.08, 0, 638.603], [0, 1043.1, 354.906], [0, 0, 1]])
>>> h,w = src.shape[:2]
>>> mDst, roi = cv2.getOptimalNewCameraMatrix(m, d, (w,h), 1, (w,h))
>>> dst = cv2.undistort(src, m, d, None, mDst)
>>> cv2.imwrite('foo.png', dst)
Run Code Online (Sandbox Code Playgroud)

这产生了这个,这可能在顶部边缘有点过度修正,但比我对反向模型的尝试要好得多:

在此输入图像描述

vpr*_*eep 6

探戈C-API文档状态 (x_corr_px, y_corr_px)"修正后的输出位置".然后需要通过焦距缩放该校正的输出位置并且通过投影中心偏移以对应于失真的像素坐标.

因此,要将点投影到图像上,您必须:

  1. 变换3D点,使其位于相机的框架中
  2. 将点转换为标准化图像坐标(x,y)
  3. 计算标准化图像坐标的r2,r4,r6(r2 = x*x + y*y)
  4. 计算(x_corr_px, y_corr_px)基础上,提到的公式:

    x_corr_px = x (1 + k1 * r2 + k2 * r4 + k3 * r6)
    y_corr_px = y (1 + k1 * r2 + k2 * r4 + k3 * r6)
    
    Run Code Online (Sandbox Code Playgroud)
  5. 计算失真的坐标

    x_dist_px = x_corr_px * fx + cx
    y_dist_px = y_corr_px * fy + cy
    
    Run Code Online (Sandbox Code Playgroud)
  6. (x_dist_px, y_dist_px)在原始的扭曲图像缓冲区上绘图.

这也意味着校正的坐标是由一化图像坐标的大小的幂级数缩放的归一化坐标.(这与问题所暗示的相反)

看看cvProjectPoints2OpenCV 的实现(参见[opencv] /modules/calib3d/src/calibration.cpp),OpenCV中的"Poly3"失真应用于与Tango相同的方向.所有3个版本(Tango Docs,OpenCV Tutorials,OpenCV API)都是一致且正确的.

祝你好运,希望这有帮助!

(更新:仔细查看代码,看起来校正的坐标和扭曲的坐标是不一样的.我已经删除了我的响应中不正确的部分,这个答案的其余部分仍然是正确的.)

  • 三个版本之后,`tango_client_api.h`仍然错误地声称使用了Tsai模型. (3认同)