Python 如何从存储在.csv文件中的三维对象创建相机将显示的图像?

Python 如何从存储在.csv文件中的三维对象创建相机将显示的图像?,python,csv,opencv,image-processing,computer-vision,Python,Csv,Opencv,Image Processing,Computer Vision,我有一个房子的三维图像存储在csv文件中。我想知道一台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.r

我有一个房子的三维图像存储在csv文件中。我想知道一台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')
以下是我的照片:


这是一个计算机图形学问题。它涉及矩阵乘法来变换这些点,直到它们位于图像平面上。我建议您查找一些基本的计算机图形数学(例如OpenGL)

OpenCV有一些过程,例如为您处理这些步骤。然而,它不是一个计算机图形库

我将向您介绍所涉及的数学知识:

首先,需要平移和旋转矩阵在场景中移动摄影机。这些矩阵都是4x4,您的三维点将表示为(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.]])
>>> 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.     ]])
均匀化:检查你的分数是否仍在最后一位。如果不是,将点/向量除以第四个坐标中的值。“点”是所有向量(x,y,z,1)*w表示任意w,并且(x,y,z,1)是正则表示

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

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

>>> 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.]])
>>> 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.     ]])

现在你有了屏幕坐标中的点。单独绘制点或在点之间绘制线。

阅读openGL书籍或计算机图形学课程,了解相机模型和3d渲染的基础知识。拥有三维模型和相机模型后,可以使用opencv projectPoints。