OpenCV - 镜头畸变系数是否为项目点反转?
OpenCV - Are Lens Distortion Coefficients inverted for projectPoints?
大家好,
我正在尝试使用镜筒畸变进行模拟和成像。我创建了一个虚拟棋盘(只有角),然后使用 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 网站,如果我使用正失真矩阵,那么我会期望桶形失真,其中指出:
The next figure shows two common types of radial distortion: barrel distortion (typically k_1 > 0) and pincushion distortion (typically k_1 < 0).
为了对此进行测试,我使用了以下 positive 失真矩阵(如上面的代码所示),它产生了枕形失真。
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
函数,失真矩阵将被负向应用?
感谢您的帮助!
projectPoints
中的 distCoeffs
似乎与 calibrateCamera
输出的类型相同。我 运行 一个更彻底的模拟,我使用 projectPoints
添加失真,然后使用 calibrateCamera
再次估计它,它给了我 相同的 失真矩阵.
例如使用以下代码
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)
创建了以下具有桶形失真的投影图像
结果:
distortion_given = [[-0.2, -0.01, 0.0, 0.0, -0.01]]
distortion_estimated = [[-0.19999985 -0.01000031 0. 0. -0.00999981]]
这意味着当我在问题中提到的this网站应该更加强调通常这个词,正如我观察到的相反。
barrel distortion (typically k_1 > 0) and pincushion distortion (typically k_1 < 0).
大家好,
我正在尝试使用镜筒畸变进行模拟和成像。我创建了一个虚拟棋盘(只有角),然后使用 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 网站,如果我使用正失真矩阵,那么我会期望桶形失真,其中指出:
The next figure shows two common types of radial distortion: barrel distortion (typically k_1 > 0) and pincushion distortion (typically k_1 < 0).
为了对此进行测试,我使用了以下 positive 失真矩阵(如上面的代码所示),它产生了枕形失真。
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
函数,失真矩阵将被负向应用?
感谢您的帮助!
projectPoints
中的 distCoeffs
似乎与 calibrateCamera
输出的类型相同。我 运行 一个更彻底的模拟,我使用 projectPoints
添加失真,然后使用 calibrateCamera
再次估计它,它给了我 相同的 失真矩阵.
例如使用以下代码
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)
创建了以下具有桶形失真的投影图像
结果:
distortion_given = [[-0.2, -0.01, 0.0, 0.0, -0.01]]
distortion_estimated = [[-0.19999985 -0.01000031 0. 0. -0.00999981]]
这意味着当我在问题中提到的this网站应该更加强调通常这个词,正如我观察到的相反。
barrel distortion (typically k_1 > 0) and pincushion distortion (typically k_1 < 0).