【发布时间】:2019-01-24 12:12:58
【问题描述】:
大家好,
我正在尝试使用镜筒失真进行模拟和成像。我创建了一个虚拟棋盘(只有角落),然后使用 OpenCV 将其投影到我的图像平面上。想法是用已知的畸变系数投影这些点,然后尝试进行镜头畸变校准(使用calibrateCamera),看看是否获得了相同的系数。
我的问题是关于以distCoeffs 为输入的projectPoints 函数。这些系数是否与必须用于不失真图像(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()
补充说明:
我的查询是关于创建了错误的失真类型。根据this网站的说法,如果我使用正畸变矩阵,那么我会期望桶形畸变:
下图显示了两种常见的径向畸变:桶形畸变(通常 k_1 > 0)和枕形畸变(通常 k_1
为了对此进行测试,我使用了以下 正 失真矩阵(如上面的代码所示),它产生了枕形失真。
distortion = np.array([0.3, 0.001, 0.0, 0.0, 0.01])
在这张图片中,我清楚地创建了枕形失真,而不是桶形失真。
同样,如果我将失真系数设为负,这会导致枕形失真,我会得到以下结果:
distortion = -np.array([0.3, 0.001, 0.0, 0.0, 0.01])
这是否意味着如果您使用projectPoints 函数,失真矩阵会被负面应用?
感谢您的帮助!
【问题讨论】:
-
我猜这只是opencv使用的针孔模型和你习惯的那个问题。您可以将其视为图像被倒置投影的
physical针孔。喜欢 (en.wikipedia.org/wiki/File:Pinhole-camera.svg) 但很多时候,我们使用投影在前面而不是倒置的模型 (openmvg.readthedocs.io/en/latest/_images/pinholeCamera.png)。这2个模型完全一样,只是尺寸的信号不同。 -
@Fred,感谢您的评论!我知道你所说的差异,但这会产生一个倒置的
x和y轴,这不是我正在努力解决的问题。而是创建了错误的失真类型。我更新了我的问题以使这一点更清楚。
标签: python opencv simulation distortion