我正在尝试将 2D 图像点反投影到 3D 点,似乎有和关于如何做到这一点的信息一样多的错误信息。我在UE4中建模了这个问题,我知道:
摄像机位置:(1077,1133,450(
相机旋转(度(:偏航 = 90,俯仰 = 345,滚动 = 0
摄像机水平视场(度(:54.43224
摄像机垂直视场(度(:32.68799
相机剪切: 0
相机分辨率: 1280x720
对象在世界上的位置:(923,2500,0(
对象在图像框中的位置:(771,427(
从上面的数据和这种方法中,我有内在的相机矩阵:
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]]
我用这个工具验证了。
我首先尝试在不使用使用此方法的固有相机矩阵的情况下执行此操作,但这不起作用,因为实际上需要内部参数
接下来,我尝试了这个解决方案,它是用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
我相信上面的代码等同于C++这个编码的解决方案,但也许我犯了一个错误?
运行 deproject_pixel(771,427( 返回 (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(返回(929,1182,0(,它在X中很接近,但在Y中很远
谁能指出我在这里做错了什么?矩阵计算不正确吗?这两种实现是否以相同的方式同时出错?
更新 1我将相机系统移至零并删除了旋转。现在,如果我沿单个轴旋转,我可以计算出旋转偏移量,但是组合多个旋转轴会改变偏移量所需的内容,因此现在只有在存在单个旋转轴时,我才能正确解投影。建议?我了解到,虚幻引擎处理旋转的方式可能与标准符号不同。
延伸阅读:
将 2D 图像坐标转换为 z = 0 的 3D 世界坐标
OpenCV 将 2D 点取消投影到已知深度为"Z"的 3D
如果外禀参数和内在参数已知,则从 2D 图像像素获取 3D 坐标
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(,一切都可以完美运行。
结果是了解您的引擎以及它是否符合已发布的标准!