如何将具有特定相机位置的 3D 世界中的 3D 点投影到 2D 图像中?

问题描述 投票:0回答:1

我很难理解如何将场景中的 3D 点转换为 2D 图像。

我在 Blender 中创建了一个场景,其中我的相机位于 P_cam(0|0|0),在 x 轴和 y 轴之间进行观察(x=90° 和 z=-45° 的旋转)。

我在 pos_c (5|5|0) 生成了一个测试立方体。

我看到的图片是这样的:

expected

我现在想用原生 python 创建相同的 img。因此我使用 opencv 将 3D 点映射到 2D 点。 我创建了相机矩阵((0|0)指的是图像的中间)

cx = width/2 #principal point is our image center
cy = height/2
camera_matrix = np.array([[fx, 0, cx], 
                          [0, fy, cy], 
                          [0, 0, 1]], np.float32) 

然后我使用 openvcs projectPoints 方法将我的立方体世界坐标转换为 2d img 点。 我没有对 tvec 的形式进行任何转换。 但我知道我需要旋转向量,这对我来说是棘手的部分。我尝试使用与搅拌机中相同值的向量,但它不起作用。

cam_rot_in_deg =  (90, 0, -45)
cam_rot_in_rad = np.radians(cam_rot_in_deg)
rvec = np.array([[cam_rot_in_rad]], np.float32).reshape((3,1))

我渲染的图像如下所示:

my fails

在图像中,我还可视化了坐标轴,因此我可以看到立方体绘制在世界中的正确位置,但我的相机视角完全关闭。

我错过了什么? 非常感谢你

我尝试了很多旋转角度,但没有找到想要的解决方案。

python opencv graphics 3d computer-vision
1个回答
0
投票

您的问题在这里:

cam_rot_in_deg =  (90, 0, -45)
cam_rot_in_rad = np.radians(cam_rot_in_deg)
rvec = np.array([[cam_rot_in_rad]], np.float32).reshape((3,1))

OpenCV 的“rvec”是轴角表示,而不是欧拉角。你在那里所做的是欧拉角。那就不好了。

您可以只处理矩阵,而不是 rvecs(和 tvecs)。我建议使用 4x4 进行 3D 仿射变换。使用矩阵乘法来组合它们很简单,对于 numpy 数组来说是

@
。这样您就可以围绕您喜欢的任何轴进行任何单独的原始旋转。

OpenCV 具有

cv.Rodrigues()
函数,可在轴角向量和 (3x3) 旋转矩阵之间来回转换。

为了方便起见,您应该定义实用函数来构建用于平移、缩放、旋转的矩阵,并给出每个矩阵的基本参数。

© www.soinside.com 2019 - 2024. All rights reserved.