相机投影模型与OpenGL矩阵投影矩阵的设置
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
相机投影模型与OpenGL矩阵的设置
摘要:
本文描述相机的投影模型与OpenGL模型视图矩阵和投影矩阵的关系。
阅读完本文,读者能够根据相机的参数(内参和外参)设置OpenGL矩阵,使得OpenGL模拟出相机的成像效果。
相机投影模型:
设空间点P3D={P x,P y,P z} ,其齐次坐标记为P3D̃={P x,P y,P z,1}。
旋转变换和平移变换均为3×3矩阵,分别记为R和T, R̃和T̃分别为它们的齐次形式。
经过旋转和平移变换之后,新的点为P3D′={P x′,P y′,P z′}
P3D′=RP3D+T
将P3D′投影到2D平面的过程为(小孔成像模型,图形坐标左上角为原点,y轴朝下):
{x=
fP x′
P z′
+
W
2
y=−fP y′
P z′
+
H
2
其中,W和H分别为成像面的宽度和高度(即图像宽度和高度)。
OpenGL投影过程:
OpenGL的投影过程为
P normal3D=M proj×M model×P3D̃
其中,P normal3D为规范化的3D点,它是一个齐次坐标,是4维向量。
M proj和M model分别
为OpenGL的投影矩阵和模型视图矩阵,它们都为4*4的矩阵。
模型视图矩阵和摄像机外参相关,对应于R和T,投影矩阵和摄像机的内参相关。
如果给定摄像机的内参f(焦距)、W和H,外参RotX,RotY,RotZ,以及TransX,TransY,TransZ。
为了使OpenGL模拟相机成像结果,则应如下设置:
//清理背景
glClearColor(0.0f, 0.0f, 1.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_DEPTH_TEST);
//设置内参
//为什么这么设置,参见参考文献2
//注意这里矩阵的排列是列优先排列
glViewport(0, 0, W, H);//设置成像面大小
glMatrixMode(GL_PROJECTION);
GLdouble projection[16]; // Where The 16 Doubles Of
memset(projection, 0, sizeof(GLdouble)*16);
projection[0]= -2.0f*focalLength/W;
projection[5]= 2.0f* focalLength /H;
projection[10] = -(Far + Near)/(Far - Near);//Far 和 Near分别为远、近裁剪平面
projection[11] = -1.0f; //这个固定要设为-1
projection[14] = -2.0f*Far*Near / (Far - Near);
glLoadMatrixd(projection);//保存投影矩阵
//设置外参,注意OpenGL中矩阵乘法的顺序
//按照RP+T模型
//应该先设置Translation矩阵, 再设置Rotation矩阵
glMatrixMode(GL_MODELVIEW);
glLoadIdentity(); //reset modelview matrix
gluLookAt(0.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, 1.0, 0.0);//把相机位置移到原点,朝向Z轴负方向glTranslatef(pTrans[0], pTrans[1], pTrans[2]);
glRotatef(pRotRad[0]/3.1415926*180.0f, 1, 0, 0);
glRotatef(pRotRad[1]/3.1415926*180.0f, 0, 1, 0);
glRotatef(pRotRad[2]/3.1415926*180.0f, 0, 0, 1);
说明:以上的远近裁剪平面是用于OpenGL做场景截取用,在此裁剪区域外的景物会被舍去。
关于OpenGL投影变换的结果可以参考如下资料:
1、OpenGL的矩阵
/red/appendixf.html
2、OpenGL矩阵的推导
/blog/post/4.html
/blog/post/5.html。