3d 三维到二维投影矩阵

3d 三维到二维投影矩阵,3d,geometry,matrix,2d,projection,3d,Geometry,Matrix,2d,Projection,我在3D空间中有3个点,我知道它们的确切位置。假设它们是:(x0,y0,z0),(x1,y1,z1)和(x2,y2,z2) 另外,我有一个摄像头,可以看到这三个点,我知道这三个点在摄像头视图平面上的二维位置。因此,例如(x0,y0,z0)将是(x0',y0'),(x1,y1,z1)将是(x1',y1'),(x2,y2,z2)从相机的角度来看将是(x2',y2') 找到将这些3D点投影到摄影机视图平面上的2D点的投影矩阵的最简单方法是什么。我们对摄像机的位置一无所知。这将为您提供两个集合,每个集合

我在3D空间中有3个点,我知道它们的确切位置。假设它们是:
(x0,y0,z0)
(x1,y1,z1)
(x2,y2,z2)

另外,我有一个摄像头,可以看到这三个点,我知道这三个点在摄像头视图平面上的二维位置。因此,例如
(x0,y0,z0)
将是
(x0',y0')
(x1,y1,z1)
将是
(x1',y1')
(x2,y2,z2)
从相机的角度来看将是
(x2',y2')


找到将这些3D点投影到摄影机视图平面上的2D点的投影矩阵的最简单方法是什么。我们对摄像机的位置一无所知。

这将为您提供两个集合,每个集合包含三个变量中的三个方程:

a*x0+b*y0+c*z0 = x0'
a*x1+b*y1+c*z1 = x1'
a*x2+b*y2+c*z2 = x2'

d*x0+e*y0+f*z0 = y0'
d*x1+e*y1+f*z1 = y1'
d*x2+e*y2+f*z2 = y2'
只要使用在你的情况下最简单的联立方程组求解方法就行了(用手求解这些方程甚至不难)。那么你的变换矩阵就是((a,b,c)(d,e,f))

实际上,这过于简化了,并且假设摄影机指向三维坐标系的原点,而没有透视图

对于透视图,转换矩阵的工作原理更像:

               ( a, b, c, d )   ( xt )
( x, y, z, 1 ) ( e, f, g, h ) = ( yt )
               ( i, j, k, l )   ( zt )

( xv, yv ) = ( xc+s*xt/zt, yc+s*yt/zt ) if md < zt;
所以你应该有4个点来得到8个方程来覆盖摄像机位置和角度的6个变量,还有1个用于缩放二维视点,因为我们可以消除“中心”坐标(xc,yc)

因此,如果您有4个点,并将二维视点转换为相对于显示器的中心,那么您可以得到13个变量中的14个联立方程并求解


不幸的是,其中六个方程不是线性方程。幸运的是,这些方程中的所有变量都被限制在-1和1之间的值,因此解决这些方程仍然可能是可行的。

我认为没有足够的信息来找到最终的解决方案。在不知道相机位置和视图平面的情况下,有无数个矩阵可以解决此问题。

您的相机(至少)有7个自由度-3个用于位置,3个用于方向,1个用于视野。如果我错了,我肯定会有人纠正我,但3分似乎不足以解决问题


要获得此问题的通用解决方案,请在Graphics Gems II中查找“视图相关性”。

您要查找的是一种姿势估计算法。查看OpenCV中的POSIT实现:

您将需要四个或更多点,并且它们可能不在同一平面上

此实现的教程如下所示:

但请注意:在本教程中使用了方形视口,因此所有视图坐标都在-1,-1到1,1范围内。这导致人们假设这些应该在相机坐标系中(在纵横比校正之前)。情况并非如此,因此如果使用纵横比为4:3的视口,则输入坐标应在-1.3333,-1到1.3333,1范围内


顺便说一下,如果您的点必须位于同一平面上,那么您也可以查看OpenCV中的CameraCalibration算法,但这需要更多的设置,需要更多的点作为输入。不过,它也会为您提供相机的失真信息和固有参数。

这不是我的家庭作业!不,他的意思是,有无限多的矩阵,可以满足你对给定点集的要求。要解决此问题,您可能需要更多的点,也可能需要更少的自由度(例如,固定摄影机的FOV)。如果您知道摄影机的视图平面(与摄影机的Z距离),使用这些点,您可以计算出摄影机的位置,因为它只是3条线的交点。从那里,我认为矩阵的轴可能可以计算。你的解决方案可能是我找到的解决问题的最佳答案。请详细描述一下解决方案的第二部分。xv和yv也是md和zt以及xt-yt-zt。感谢lot7通常是正确的,尽管有些系统允许FOV有两个参数:垂直和水平。通常它们彼此成比例(即4:3屏幕=4:3视场比),但在某些情况下,如果用户愿意,这可能会出现偏差。
a*a+b*b+c*c = e*e+f*f+g*g = i*i+j*j+k*k = 1
a*a+e*e+i*i = b*b+f*f+j*j = c*c+g*g+k*k = 1