无论方法如何,从 2D 到 3D 的投影都是错误的

Deprojection from 2D to 3D is wrong regardless of method

我正在尝试将 2D 图像点反投影到 3D 点,似乎有很多错误信息,因为那里有关于如何做到这一点的信息。我有在 UE4 中建模的问题,我知道:

相机位置:(1077,1133,450)

相机旋转(度):yaw = 90,pitch = 345,roll=0

相机水平视野(度):54.43224

相机垂直视野(度):32.68799

相机剪切:0

摄像头分辨率:1280x720

对象在世界中的位置:(923,2500,0)

图像帧中的对象位置:(771,427)

根据以上数据和this method,我有内在的相机矩阵:

K = [[1.24444399e+03 0.00000000e+00 6.40000000e+02]
     [0.00000000e+00 1.22760403e+03 3.60000000e+02]
     [0.00000000e+00 0.00000000e+00 1.00000000e+00]]

和旋转矩阵:

R = [[ 5.91458986e-17 -1.00000000e+00 -1.58480958e-17]
     [ 9.65925826e-01  6.12323400e-17 -2.58819045e-01]
     [ 2.58819045e-01  0.00000000e+00  9.65925826e-01]]

我用 this tool.

验证了

我第一次尝试使用这个 method but that did not work because the intrinsic parameters are, in fact,

在不使用固有相机矩阵的情况下做到这一点

接下来我尝试了 this solution,我在 python 中实现了它,删除了计算我已经拥有的内在和外在参数的代码:

def deproject_pixel(u,v):
   inv_camera_rotation_matrix = np.linalg.inv(camera_rotation_matrix)
   inv_camera_intrinsic_matrix = np.linalg.inv(K)

   uv_matrix = np.array([
       [u],
       [v],
       [1]])

   tx = 1077
   ty = 1133
   tz = 450

   txyz_matrix = np.array([
       [-tx],
       [-ty],
       [-tz]])

   Tx_Ty_Tz = np.dot(camera_rotation_matrix,txyz_matrix)

   ls = inv_camera_rotation_matrix @ inv_camera_intrinsic_matrix @ uv_matrix
   rs = inv_camera_rotation_matrix @ Tx_Ty_Tz

   s = rs[2][0] / ls[2][0]
   world_point = s*ls-rs

   return world_point

我相信上面的代码等同于 this coded solution in C++ 但也许我弄错了?

运行 deproject_pixel(771,427) returns (929,1182,0), 在X上很近,在Y上很远

然后我尝试 需要完整的相机矩阵 M:

M = K@np.concatenate((camera_rotation_matrix,Tx_Ty_Tz),1)
def deproject_pixel_2(u,v):
   A = (M[0][1]-M[2][1]*u)/(M[1][1]-M[2][1]*v)
   B = (M[2][0]*u-M[0][0])/(M[2][0]*v-M[1][0])

   X = ((M[1][3]-M[2][3]*v)*A-M[0][3]+M[2][3]*u ) / (A*(M[2][0]*v-M[1][0])-M[2][0]*u+M[0][0])
   Y = (M[0][3]-M[2][3]*u-B*(M[1][3]-M[2][3]*v)) / (B*(M[1][1]-M[2][1]*v)-M[0][1]+M[2][1]*u)

   world_point = [X,Y,0]
   return world_point

但又一次,运行 deproject_pixel_2(771,427) returns (929,1182,0),在 X 中很近但很远在 Y

任何人都可以指出我在这里做错了什么吗?矩阵计算不正确?这两种实现是否同时以同样的方式出错?

更新 1 我将相机系统移至零并移除了旋转。如果我沿单个轴旋转,我现在可以计算出旋转偏移量,但是组合多个旋转轴会改变偏移量所需的值,因此我现在可以仅在存在单个旋转轴时正确地反投影。建议?我了解到 Unreal may deal with rotation differently 比标准符号建议的要多。

进一步阅读:

Get 3D coordinates from 2D image pixel if extrinsic and intrinsic parameters are known

https://answers.opencv.org/question/62779/image-coordinate-to-world-coordinate-opencv/

http://ksimek.github.io/2013/08/13/intrinsic/

只是UE4对旋转矩阵有点奇怪。我在 Blender 2.79 中对问题进行了建模,如果您使用 ZYX (ypr) 旋转相机并在代码中向滚动添加 180 度偏移(因此 180-reported_angle),一切都会完美无缺。

结果是了解您的引擎以及它如何符合或不符合已发布的标准!