我正在尝试使用 OpenCV 的 solvePnPRansac 方法来定位在 Blender 中加载的 3D 模型周围的相机位置。但是,手动输入点会给我一个不正确的 t/r 向量,而 cv2.projectPoints 得到的图像坐标是错误的,所以我怀疑输入的某些内容搞砸了。
我在 Blender 的任意单位中手动选择了 3D 模型上的 10 个点,并将它们用作世界坐标。我在 960x540 渲染图像中找到了这些点的相应位置,这些是我输入的 2D 坐标(按像素)。
相机的焦距和传感器尺寸设置为 40mm 焦距和 40x18mm 传感器,因为这是毫米,所以我手动测量了它们的长度(以像素为单位),大约为 916 像素和 412 像素 - 但是,这两组值都给了我坐标完全关闭。
对我来说,projectPoints 的输出是范围从 -13,000 到 20,000 的坐标。我认为我的输入值不正确,但我该如何解决?
size = (960, 540)
image_points = np.array([
(315, 279), # 1
(440, 273), # 2
(407, 386), # 3
(369, 372), # 4
(440, 317), # 5
(457, 373), # 6
(439, 385), # 7
(369, 337), # 8
(407, 358), # 9
(313, 291), # 10
], dtype="double")
model_points = np.array([
(0.77644, -0.63806, 2.55822), # stripe of adidas 1/3 down
(0.75437, 0.49247, 2.75569), # first curve up on the logo
(0.82970, 0.17763, 1.58873), # lower right part of hole in a
(0.82900, -0.16946, 1.68983), # 1/3 down left side of i
(0.84466, 0.52011, 2.37269), # bottom of gold circle left of F
(0.67476, 0.59525, 1.68853), # left side of thick top 's'
(0.74288, 0.46100, 1.58926), # inwards (left) of right below e joint
(0.82560, -0.14537, 2.07217), # middle of f top bar, left of upwards
(0.83161, 0.17382, 1.88820), # middle line of a near bottom of Y
(0.78115, -0.66043, 2.46363) # 1/4 up 2nd d circle in adidas
], dtype = "double")
f = 916.8
sx = 916.8
sy = 412.56
width, height = (size[1], size[0])
camera_matrix = np.array([
[width*f/sx, 0, width/2],
[0, height*f/sy, height/2],
[0, 0, 1]
], dtype = "double")
dist_coeffs = np.zeros((4,1))
s,t,r, i = cv2.solvePnPRansac(model_points, image_points, camera_matrix, dist_coeffs)
img, x = cv2.projectPoints(model_points, r, t, camera_matrix, dist_coeffs)
print(img)