OpenCV-镜头失真系数是否针对projectPoints颠倒了?

时间:2018-08-17 12:36:31

标签: python opencv simulation lens distortion

伙计们,

我正在尝试模拟和镜筒失真的图像。我创建一个虚拟棋盘(仅在角落),然后使用OpenCV将其投影到我的图像平面上。想法是用已知的失真系数投影这些点,然后尝试进行镜头失真校准(使用calibrateCamera),看看是否获得了相同的系数。

我的问题是关于projectPoints函数,该函数以distCoeffs作为输入。这些系数是否必须与扭曲图像(calibrateCamera的输出)相同?这意味着函数将必须计算该操作的逆函数。还是使用这些系数直接使目标点失真?这意味着在例如calibrateCamera

我问,因为我注意到当我期望桶形时,我的模拟会产生枕形失真,反之亦然。似乎失真与我认为的相反。

我用来模拟图像的最小工作代码(在Python中):

# The distortion matrix that I vary
distortion = np.array([0.3, 0.001, 0.0, 0.0, 0.01])

# Generate Grid of Object Points
grid_size, square_size = [20, 20], 0.2
object_points = np.zeros([grid_size[0] * grid_size[1], 3])
mx, my = [(grid_size[0] - 1) * square_size / 2, (grid_size[1] - 1) * square_size / 2]
for i in range(grid_size[0]):
    for j in range(grid_size[1]):
        object_points[i * grid_size[0] + j] = [i * square_size - mx, j * square_size - my, 0]

# Setup the camera information
f, p = [5e-3, 120e-8]
intrinsic = np.array([[f/p, 0, 0], [0, f/p, 0], [0, 0, 1]])
rvec = np.array([0.0, 0.0, 0.0])
tvec = np.array([0.0, 0.0, 3.0])

# Project the points
image_points, jacobian = cv2.projectPoints(object_points, rvec, tvec, intrinsic, distortion)

# Plot the points (using PyPlot)
plt.scatter(*zip(*image_points[:, 0, :]), marker='.')
plt.axis('equal')
plt.xlim((-4000, 4000))
plt.ylim((-4000, 4000))
plt.grid()
plt.show()

其他说明:

我的查询是关于错误的变形类型。根据{{​​3}}网站的说法,如果我使用正失真矩阵,那么我会期望桶形失真,它指出:

  

下图显示了两种常见的径向变形类型:桶形变形(通常k_1> 0)和枕形变形(通常k_1 <0)。

为了对此进行测试,我使用了以下失真矩阵(如上面的代码所示),并创建了枕形失真。

distortion = np.array([0.3, 0.001, 0.0, 0.0, 0.01])

this

在此图像中,我清楚地创建了枕形失真,而不是桶形失真。

类似地,如果我使失真系数为负,这会导致枕形失真,则得到以下结果:

distortion = -np.array([0.3, 0.001, 0.0, 0.0, 0.01])

Expected Barrel Distortion, but got Pincushion

这是否意味着如果您使用projectPoints函数,则会对失真矩阵施加负面影响?

谢谢您的帮助!

1 个答案:

答案 0 :(得分:1)

似乎distCoeffs中的projectPointscalibrateCamera输出的类型相同。我进行了更彻底的仿真,其中我使用projectPoints添加了失真,然后再次使用calibrateCamera对其进行了估计,这给了我 same 失真矩阵。

例如,使用以下代码

distortion_given = np.array([[0.2, 0.01,  0.0, 0.0, 0.01]])# Note the negative sign
... = projectPoints(... , distortion_given , ...)
... , distortion_estimated , ... = calibrateCamera (...)
print (distortion_given)
print (distortion_estimated)

创建了以下具有桶形失真的投影图像

enter image description here

结果:

distortion_given = [[-0.2, -0.01,  0.0, 0.0, -0.01]]
distortion_estimated = [[-0.19999985 -0.01000031  0.          0.         -0.00999981]]

这意味着当我在问题中提到的this网站时,应该更加强调一词,因为我发现相反。

  

桶形失真(通常为k_1> 0)和枕形失真(通常为k_1 <0)。