无论方法如何,从 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/
只是UE4对旋转矩阵有点奇怪。我在 Blender 2.79 中对问题进行了建模,如果您使用 ZYX (ypr) 旋转相机并在代码中向滚动添加 180 度偏移(因此 180-reported_angle),一切都会完美无缺。
结果是了解您的引擎以及它如何符合或不符合已发布的标准!
我正在尝试将 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 = 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/
只是UE4对旋转矩阵有点奇怪。我在 Blender 2.79 中对问题进行了建模,如果您使用 ZYX (ypr) 旋转相机并在代码中向滚动添加 180 度偏移(因此 180-reported_angle),一切都会完美无缺。
结果是了解您的引擎以及它如何符合或不符合已发布的标准!