Warm tip: This article is reproduced from serverfault.com, please click

python-如何从存储在.csv文件中的3D对象创建相机显示的图像?

(python - How to create an image a camera would display from an 3D object stored in a .csv file?)

发布于 2020-11-28 22:01:02

我在csv文件中存储了房屋的3D图像。我想知道f = 400像素,640 x 480的相机如何拍摄不同姿势的照片。我可以在csv(第一张图片)中显示该图片,但我想获得类似于第二张图片的图片。

import pandas as pd
import numpy as np
import cv2 as cv
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D


#load data
data1 = pd.read_csv('house.csv',sep=' ')
x = data1.drop(data1.columns[[0,2,3]], axis=1)
y = data1.drop(data1.columns[[0,1,3]], axis=1)
z = data1.drop(data1.columns[[1,2,3]], axis=1)

fig = plt.figure()
ax1 = fig.add_subplot(111,projection='3d')
# Hide grid lines
plt.grid(b=None)
ax1.scatter(x,y,z)
plt.axis('off')
plt.savefig('house.png')

这是我的图像:

在此处输入图片说明

在此处输入图片说明

Questioner
Corisco
Viewed
0
Christoph Rackwitz 2020-11-29 07:54:29

这是计算机图形学问题。它涉及矩阵乘法以转换这些点,直到它们在图像平面上为止。我建议你查找一些基本的计算机图形数学(例如OpenGL)。

OpenCV具有诸如cv :: projectPoints()之类的过程来为你处理其中一些步骤。但是,它不是计算机图形库。

我将为你简要介绍所涉及的数学:

首先,你需要平移和旋转矩阵来使摄像机在场景中移动。这些矩阵都是4x4,你的3D点将表示为(x,y,z,1)向量。多余的坐标使翻译(甚至更多)成为可能。你将矩阵相乘为一,然后将这一点应用于你的点。这种转换将所有点从世界空间移到摄影机空间(摄影机周围的空间移动)。

+ Z中5个单位的简单翻译为:

>>> T = np.eye(4)
>>> T[0:3,3] = (0, 0, +5)
>>> T
array([[1., 0., 0., 0.],
       [0., 1., 0., 0.],
       [0., 0., 1., 5.],
       [0., 0., 0., 1.]])

同质化:检查你的点数最后是否仍为1。如果不是,则将点/矢量除以第四坐标中的值。“点”是任何w的所有向量(x,y,z,1)* w,而(x,y,z,1)是规范表示。

现在是投影矩阵。计算机图形学也在这里使用4x4矩阵,但是我对这种表述没有经验。我将改用OpenCV中常用的3x3矩阵。它会将你的点作为相机空间中的(x,y,z)向量,并在屏幕空间中输出(x,y,1)* w向量(是,再次均化)。

640x480摄像机和60度水平视场的摄像机矩阵为:

>>> M = np.eye(3)
>>> M[0:2,2] = (640/2, 480/2)
>>> M[0,0] = M[1,1] = (640/2) / atan(60/2 * pi/180)
>>> M
array([[663.42156,   0.     , 320.     ],
       [  0.     , 663.42156, 240.     ],
       [  0.     ,   0.     ,   1.     ]])

现在,你的点已在屏幕坐标中。单独画点或在点之间画线。