毕业设计论文基于OpenGL的时分立体图像显示研究.doc
基于OpenGL的时分立体图像显示研究作者:摘要:本文详细讨论了时分式的立体显示的基本概念、形成条件以及数学模型。在此基础上,编程实现了基于windows的OpenGL时分立体显示,刷新频率达到120HZ/s,可产生无闪烁的立体显示效果,只需要立体眼镜等配套设备即可支持,使显示效果更加逼真。关键词:OpenGL 视差 时分 立体显示Field sequential stereoscopic image display with OpenGLAuthor :Abstract: This thesis particularly introduces the concepts of field-sequential stereoscopic display ,forming condition and mathematical model .On this principle, I programmed field-sequential stereoscopic display based on windows with OpenGL, renovation frequency can be achieved to 120Hz/sec. The stereoscopic display effect is very good and image has no flicker. only need some equipments such as CrystalEyes , than you can get a more reality display.Keywords :OpenGL Parallax field-sequential stereoscopic display目 录引言 1 第1章 立体显示技术 2 1.1 深度信号 2 1.2 立体视觉概述 2 1.3 视差 21.4 立体视觉显示方法 2第2章 立体透视摄影图像生成原理 3 2.1 立体透视投影原理的数学描述 3 第3章 软件编程实现3.1 系统设置 5 3.2 实现原理 6 3.3 编程实现 6 3.3.1 初始化窗口以支持立体格式 6 3.3.1 写入各个立体缓冲区 6 结论 7 参考文献 8 后记 11 附录A 程序清单 12 附录B 外文资料翻译 13 外文资料翻译原文部分 13 外文资料翻译译文部分 13 引言普通照相只能存贮被摄物体光强度的空间分布,不能满足人们希望在特定环境下能够感知真实3D场景的要求。长期以来,人们为实现动态三维显示技术做了不懈的努力,并在三维显示方法和系统实现方面做了不少研究,使得各种三维立体显示技术得到长足的发展。立体显示是三维显示中主要的一类,它是运用视差来实现人眼的深度感度。立体显示又可分为需要佩带辅助眼镜装置(如滤色眼镜和液晶光阀眼镜)的立体显示和无需佩带任何辅助眼镜装置的自动立体显示。本文主要介绍液晶眼镜辅助的立体显示技术,即时分立体显示技术。时分立体显示技术,在军事、CADCAM、工业生产、模拟和训练、3D显示与电子游戏、显微技术和医疗等领域已经得到广泛的应用,成为当前世界上显示技术领域研究的一个热点。本文所实现的时分式立体显示技术,是根据人的双眼视差效应,利用红外液晶眼睛,在非常高的频率轮流遮挡单眼的方法进行视觉观看,如此造成一个空间虚拟的感觉。第1章 立体显示技术在这一章中,先介绍一些有关立体显示技术的背景知识,以便于更好的了解立体显示技术以及相应的编程的原理。 1.1 深度信号深度信号是立体视觉显示器感知深度的基础。其重要性就如立体镜在产生经过透视的真正的三维图像中的作用。这些深度信号包括明暗、相关尺寸、插入、材质梯度、空中透视、运动视差和透视等,其中最重要的是透视。包含的深度信号越多, 图像将越容易产生立体视觉。明暗是一个基本的深度信号。通过明暗处理可以使物体看起来更有立体感,投射阴影会使物体看起来象静止在表面上。明亮的物体比灰暗的物体近;色彩明亮的物体看起来比黑的物体近。相关尺寸相关尺寸是指出眼睛的晶状体投射到视网膜上的物体的图像的尺寸。我们知道,距离越近,物体看起来更大;距离越远,物体看上去越小。记忆帮助我们判断常见物体的距离。看较远处的人,给我们的第一感觉是远而不是小。插入插入这个概念是最容易想象的。我们有时会有这样的感觉,正在读一本书的时,忽然觉书离我们更近了,或者说书就放在它后面的某个物体的前面,比如说书桌。人无法通过书去看它后面东西的,书就插入在人和远处的什么物体之间。材质梯度材质梯度是唯一的出现代心理学家提出的深度信号。这种深度信号早在文艺复兴时就被画家提出并用于作品中。一种结构材料,就像绿草坪都包含一种深度信号,因为这种结构更实在,给人的感觉像物体更接近观察者。空中透视空中时是由雾的影响造成的远处景物可见度的削弱。通常观望远景将拾取浅蓝色的雾,这是由于大气干涉引起红光散射造成的。在大雾弥漫时,远处的景物根本无法看到。运动视差运动视差这个深度信号来自视觉信号或运动难过,可以通过物体的转动获得。一个较为熟悉的例子可以从一辆运动的小车观察到,车外的电线杆比远处的小山通过的更快。并非所有的图形合成物都包含运动视差,但是利用运动视差可以产生好的深度效果,而不必管旋转轴的空间方位。这种轴向独立性说明运动视差和立体影像是分离的。如果这两者相关,只有绕垂直轴旋转能产生深度效果,但是事实上,绕水平轴旋转也有这种效果。之所以指出这点是因为一些人认为立体影像与运动视差是同一个实体的表现。运动视差在旋转体中是一个很好的深度信号。透视透视有时也称为“几何”、“直线”、或“投影”透视,它扩大了立体深度的范围。计算机生成的有强烈透视感的图像看起来更深,更给人以立体感。深度信号深度信号是用于计算机图形学上的一个技术的名字,深度信号根据物体与观察者之间的距离,按比例减小物体的明亮程度,使物体看起来更有空间的感觉。1.2 立体视觉概述做这样一个实验:伸出拇指放在脸前,当看拇指时,眼睛会聚在拇指上,也就是说,两只眼睛的视轴通过拇指。有很多面部肌肉参与使拇指在两个视网膜中心城乡。如果继续将两眼会聚在拇指上,注意一下背景,将会发现背景成了双的。利益方面,当眼睛会聚在背景上时,拇指又会变成双的。如果能够采到左右视网膜上物体所称的两个像并以某种方式叠加,将看到两个几乎完全重叠的图像。而左右视网膜图像上的对应透视点,存在心理学家所说的视差。这里所说的视差是视网膜视差,与后面谈到的视差是由区别的。视网膜视差是左右视网膜上的图像的对应点在水平方向上的距离。左右视网膜图像的各对应点中,眼睛会聚的两个对应点由零视差。视网膜视差的产生源于每只眼睛从不同的观察点看客观世界。而眼睛和大脑共同作用的这个视网膜视差又给人们带来了一个单一的视觉世界。成年人的两眼间的平均距离是6.4厘米。当观察某一个特定点时,左右眼在目标处聚焦,人眼的角度随其到目标点之间的距离变化。眼睛和大脑根据左右眼图像的不同决定距离,人的眼睛能够根据测量距离将物体看成三维的。大脑根据细微的不同得到信息,对得到的信息的细节解释使人有距离和深度的感觉。当两副图像有合适的距离时,就会有立体的感觉。立体图像是观察者在看客观世界时,左右眼从不同的观察点所得到的两幅图像的一个综合体现。人眼和大脑将这两幅来自客观世界的图像合成一幅具有立体深度的图像,结果看到一个单一的图像,而不是两个图像。因为大脑已将这两幅图像完全熔合在一起形成一幅立体图像,这就比两幅图像的直接叠加看起来效果好很多。在客观世界中观察一个实际物体,在某一时刻,两个不同的图像进入左右眼,人脑通过分析两幅图像得到距离和深度。如果实际物体不存在,可以通过计算机生成图像来虚拟这种立体效果。目前对立体计算机动画的研究主要集中在如何生成有合适距离的图像序列,以及如何将两个图像序列组合在一起,使观察者有空间的感觉。1.3 视差当我们在不戴立体眼镜的情况下直接观察立体图像,我们彷佛看到两幅图像层叠在一起,当刷新率足够高时,我们将看不到任何闪烁,在左右眼图像中的相同像点(也称为同源像点)的位置差,就称为视差。下面将介绍四种典型的视差。·零视差左右眼图像的同源像点落在屏幕的同一位置,即视差值为零。左右眼的视线交于屏幕一点。·正视差有一种正视差是左右眼的实现是平行的,在现实生活中,这种情况往往发生在观察者与被观察物体的距离较远时。在立体显示时,当两眼之间距离与视差相等时,产生正视差。任何一种介于零和两眼间距的视差都可以由CRT显示并观察。还有一种正视差是发散视差。·发散视差 当左右图像的拭擦画质大于两眼之间距离时称为发散视差,即左右眼视线是发散的,在现实生活中,我们观察一个物体时,不会出现这种情况。·负视差 两眼的视线在屏幕之前相交,这种情况被称为负视差。这是,屏幕所显示的物体好像在屏幕的前方,也就是说在观察者和屏幕之间。1.4 立体视觉显示方法·立体镜法 把一被摄景物用两台摄影机同时拍摄,两摄像机镜头光轴之间距离为65毫米,男这立体镜观看两个画面影像时,就可以看到被拍摄景物的立体图像了。这种方法在商业上很难应用。这种方法不破坏颜色,也不引起色偏,但是它需要电子线路,生产制造较为复杂。·色差法 把左眼图像染上红色,有眼图像让染上红色的互补色,即兰-绿色,把这两个带颜色的图像重叠的放映到屏幕上,观察者左眼戴红色镜片,右眼戴绿色镜片,这是看到的是黑白色的立体影像。这种方法需要增加预处理的工作量,现在见得比较多的是用于显示静止画面。·偏振光法 利用光的偏振理论,在放映机前加快偏振光滤光片。偏振光滤光片像一把梳子,把向各个方向振动的光波梳去一部分,使剩余的一部分光沿着一个规定方向前进,如果把两块偏振方向相同的滤光片摆在光路上,就会起到阻光的作用。因此,在左眼光路装一个滤光片,把右眼光线滤掉,在右眼光路装一个滤光片,将左眼光线滤掉,观察者戴上这样的偏光眼镜,就可以保证左右眼同时看到相应的左右眼影像,得到彩色的立体效果。·光栅法光栅法即柱镜法,它的基本原理是把左右眼两个影像分成垂直的细长条,再把这些条交错编线成一个集合画面,这个合成画面实际上是由许多条组成。每隔一个线条构成一个集合画面,形成相对应的立体影像。当把一个柱状屏幕放在合成画面前面,就产生出选择效果。·交变画幅法 即用一套分时系统交替显示对应于左右眼图像,并且把代表左右眼的图像分别送入相应的那只眼睛里,从而在观察者的意念中产生具有纵深立体感的画面。这种方法现在用的比较多,而且有较多的硬件支持,象红外液晶眼镜等。本系统就是采用这种方法来显示立体图像。·激光全息摄影法 这是一种新的产生立体效果的方法,它的原理是被摄体被光源照射后,被摄体 每个点同样是一个光源,它以球面波的形式向四面八方辐射,这些反射波传到人眼里,人们才能看到物体。如果采用一种方法,使这些反射波“保留”在空间,而把被摄体拿掉,人们仍然可以看到原来的被摄体第2章 立体透视摄影图像生成原理在本章,将介绍立体透视投影图像的基本概念和生成原理。把三维物体变成二维图形的表示过程为投影变换,根据投影中心和投影平面之间的距离不同,投影可以分为平行投影和透视投影。平行投影的投影中心与投影平面的距离为无穷大。而对透视投影而言,这个距离是有限的。2.1立体透视投影原理的数学描述 将不同的图像材料分别放置入左右眼缓冲区,经透视投影,将产生一个无论在几何外观上还是感觉上都非常好的立体效果。一个高质量的立体图像,都包括两个立体部分,这两部分都是透视投影,且它们的投影中心(摄像机)在位置上平行对称。从一个简单的非立体投影的数学模型入手。假设摄像机位于z轴的正半轴的点( 0 ,0 ,d )处,d是摄像机到x-y平面的距离 ,点(x,y,z)投影到x-y平面为:( 方程1) 图1两点的透视投影下面说明计算机产生立体图像的基本几何模型。两摄像机的轴间距是c,由于两个摄像机之间存在水平距离c,故它们将产生两幅不同的透视投影图。点(x,y,z)经左摄像机投影的位置为:(方程2) 点(x,y,z)经右摄像机投影的位置为:(方程3) 在一个立体显示系统中,如果一个投影物是叠加在其他投影之后,这将导致任意点出现光学家称之的“负视差” ,也就是说它会出现在显示屏的前面。反之,如果左摄像机看到的投影出现在右摄像机看到的投影的左侧,将出现“正视差” ,也就是说该点看上去好像位于显示屏里面的某处。当左右投影完全重合时就会出现“零视差”,“零视差”的景物投影在显示屏表面上。图2体现了正视差和负视差的效果。 图2:视差效果一般的,一个平衡的很好的,而且看上去很舒服的立体图像将同时利用正负视差,一些三维场景就投影到零视差或接近零视差。但是,利用方程式2、3来计算一对立体投影时,所有可能的三维点将投影到负视差区,而所有的负视差都使观看者感到不舒服。对于上述问题的解决仅需将左摄像机投影值沿x轴左移,右摄像机投影值右移。如果以原摄像机间隔c的一半来移动投影点,经几何作图后,原来的投影平面将精确位于零视差平面。对左眼,(方程4)对右眼,(方程5)利用方程式4、5式计算出来的投影被称为“平行轴不对称平截面透视投影”。注意,即使先沿x轴的一个方向移动场景,再沿x轴的相反方向移动场景的投影,投影轴,即两个摄像机的方向矢量仍然保持平行。最后一步移动投影使得平行透视投影的截面不对称,意味着左、右摄像机的透视投影能很好的平衡视差效果,使合成结果更添立体感。小结 : 本章中介绍了立体透视投影图像的基本概念和生成原理。从数学模型的角度对立体透视投影图像进行了分析。第3章 软件编程实现 在本章,将进行软件编程以实现图像的时分立体显示。这里用到了Visual C+6.0的编程环境,使用OpenGL(开放式图形界面)技术,它是由Silicon Graphics公司(即SGI)开发,能够在windows 95、windows NT、Macos、OS/2、以及unix上应用的API。它除了提供许多个运算功能外,也提供了不少图形处理功能。实现编程所采用的具体开发环境及硬件选择如下:·windows xp 操作系统·Visual C+6.0 开发环境·NVIDIA Quadro FX 3400·OpenGL·CrystalEyes立体眼镜、红外发射器3.1 系统设置在进行程序代码编写之前,首先需要在windows xp环境下进行立体显示的设置,具体实施步骤如下:1.安装立体驱动程序,本实验中安装的是91.31版本。2.重启计算机,改变显示设置为800×600×65536色,640×480×65536色,或640×480×16777216色。并把刷新频率定为100Hz或者更高。3.返回“控制面板”,选择“显示”,然后是“Configuration”,在对话面板中选择“STEREO”,然后单击“OK”,重启计算机。4.运行一个简单的立体测试程序,以检查是否设置正确。5.如果经过上述步骤,还未得到立体工作模式,检查一下所有的硬件连接。3.2 实现原理要编程实现时分立体显示主要采取的步骤包括以下几步:为运行安装立体设备 要求图形硬件支持立体缓冲区 能够使立体缓冲区在windows中运行 写到各个缓冲区中三维场景的时分立体显示主要是通过显示程序控制显示卡和液晶眼镜的同步来实现的。具体实现是这样的:显示卡的缓存分为四个部分,分别是左眼前台,左眼后台,右眼前台,右眼后台。“左眼”和“右眼”之间有一个距离。假设显示卡控制显示器的场频是120Hz,那么每秒钟“左眼”看到的图像出现在显示器上60次,“右眼”看到的图像也出现在显示器上60次。由于“左眼”看到的图像和“右眼”看到的图像每隔一次出现在显示器上,所以显示器每次刷新的图像信息只是四部分缓存中的一部分。当“左眼”看到的图像出现在显示器上时,显示卡控制液晶眼镜的左镜片打开,右镜片闭合,人就只通过左眼看到显示器上的图像;当“右眼”看到的图像出现在显示器上时,显示卡控制液晶眼镜的右镜片打开,左镜片闭合,人就只通过右眼看到显示器上的图像。由于视觉暂留,人好像是同时接受到了“左眼”和“右眼”的信息,在视网膜上就形成了视差,于是在人的大脑里便形成了关于物体的立体图像。3.3 编程实现3.3.1初始化窗口以支持立体格式为 了初始化程序以支持立体缓冲,图像窗口必须调用windows API函数SetPixelFormat():要注明PFD_STEREO属性。PIXELFORMATDESCRIPTOR pfd;int iFormat;hDC=GetDC(hWnd);ZeroMemory(&pfd,sizeof(pfd); pfd.nSize=sizeof(pfd);pfd.nVersion=1;pfd.dwFlags= PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER |PFD_STEREO;pfd.cColorBits = 32;pfd.cDepthBits = 32; pfd.iLayerType = PFD_MAIN_PLANE;iFormat = ChoosePixelFormat(hDC, &pfd); SetPixelFormat(hDC, iFormat, &pfd);hRC=wglCreateContext(hDC);wglMakeCurrent(hDC,hRC); 只有当系统已经有一个有效的设备句柄时,函数SetPixelFormat()才可以被调用。注意:对于任意一个指定的窗口,Microsoft Windows只允许调用一次SetPixelFormat()函数。对于以后的SetPixelFormat()函数,该窗口会忽略而不去调用。所以PFD_STEREO属性必须在第一次调用函数SetPixeIFormat()时进行设定。如果用户的图形卡不支持立体缓冲或者尚未设置好,则调用函数SetPixelFormat()设定的PFD_ STEREO属性无效。3.3.2写入各个立体缓冲区 OpenGL中的glDrawBuffer()函数允许规定缓冲区的结果并且可以直接赋值。当不支持双缓冲区的时候,可以调用“后缓冲区”(glDrawBuffer(GL_BACK);)和“交换缓冲区“(wg1SwapLayerBuffers(hdc,WGL_SWA_MAIN_PLANE);),可以将后缓冲区和前缓冲区互换,这样就可以产生视觉效果。一旦使SetPixelFormat()初始化窗口使它能够支持立体缓冲区,以使用GL_BACK_LEFT下函数或者GL_BACK_RIGHT函数来规定视图缓冲区,这将导致OpenGL视图出现在某一个人的眼睛的视图缓冲区,画完左后和右后缓冲区以后。就可以使用wglSwapLayerBuffers()函数来将后缓冲区的内容换到前缓冲区,以下是把左右眼的图像分别写入左右缓冲区中去的代码:/清后台缓冲区glDrawBuffer(GL_BACK);glClearColor(0.2f,0.2f,0.2f,0.0f);glClear(GL_COLOR_BUFFER_BIT|GL_ DEPTH_ BUFFER_ BIT);/显示左眼图像glDrawBuffer(GL_BACK_LEFT):glPixelzoom(Xzoom,Yzoom);glRasterPos2d(XposLeft,YposLeft);glDrawPixels(ImgWidthLeft,ImgHeightLeft,GL_RGB,GL_UNSIGNED_ BYTE,ImageLeft);glClear(GL_ DEPTH_BUFFER_BIT);/显示右眼图像glDrawBuffer(GL_BACK_RIGHT);glPixelzoom(Xzoom,Yzoom);glR asterPos2d(Xpos,Ypos);glDrawPixels(ImgWidth,ImgHeight,GL_RGB,GL_UNSIGNED_BYTE,ImageRight);/页面反转g1Flush();BOOL bSuccess=SwapBuffers (hdc);上面的代码可以看出我们可以使用glDrawBuffer(GL_BACK),立刻调出左后和右后缓冲区,也可以使用glDrawBuffer()直接写入左前和右前缓冲区(GL_FRONT_LEFT和GL_FRONT_RIGHT)。小结:在本章中,我们利用OpenGL技术,通过编程实现了图像的时分立体显示,在100Hz的显示器刷新率下,图像显示无任何闪烁感。在立体眼镜的支持下,可以获得很强的立体真实感。结论论文的结论是最终的、总体的结论,不是正文中各段的小结的简单重复。结论应该准确、完整、明确、精练。*注结论格式:单起一页1.结论:标题黑体三号字,居中2.清单正文为小四号,宋体,行距24磅,间距:段前0.5行,段后0行。 参考文献1 廖朵朵:OpenGL三维图形程序设计,北京,星球地图出版社。2刘长松(译):3D图形编程指南,西北工业大学出版社,1998-1999年。3 Writing Stereoscopic Software for stereo graphics systems using MicrosoftWindowsOpenGL,By Bob Akka 1999。4 Adding Stereo Support to Graphics Board Subsystems,By Bob Akka and Jeff Haln on 1999。5 Calculating Stereo Pairs,By Paul Bourke,19996 3D Stereo Rendering Using OpenGL (and GLUT) ,By Paul Bourke,2002。7 Advanced Graphics Programming Using OpenGL,By Ganesh Rao,2005。8 Stereo Rendering: An Overview, By Jamie Brettle,2005。9 三维立体显示技术研究新进展, 郑华东,2008。后记整个毕业设计,从08年12月份就开始了,在老师的指导下,首先到图书馆借阅资料,了解了整个毕设的基本流程,从而着手于自己的毕设。第一个月,首先学会的是如何查找资料,通过关键字查找,从现存的各种相关网站、搜索引擎、论坛、数据库找到自己所需要的文献。由此得到的文献,相关程度不同,这时候需要细读查找到的每篇文献。在我查找到的文献中,英文资料居多,这就需要在加深对专业词汇的了解和学习。与此同时,由于我的论文涉及到编程,也就开始了在VC+下的OpenGL基本编程的学习。第二个月,在大量资料的支撑下,对毕设的主题-时分立体显示有了深刻的了解,包括其原理及其实现,于是进行了相关文献的翻译和编程。第一个调试的程序是色差式的立体显示。色差式较时分式编程容易些,但是程序模块相同,可以通过这个程序熟悉所要使用的函数以及格式。通过红绿眼镜,可以观察到一个旋转的立体茶壶。第三个月,主要解决时分立体显示的编程问题。这个过程是漫长的,需要耐心的。起初,运行的每个程序,编译通过,但是窗口总显示:GLUT:Fatal error in (unamed):pixel format with necessary capabilites not found.这是像素格式的问题。通过请教老师,同时通过网上查找相关问题的解决方案,发现关于入口函数。Win32 application是运行在windows上的32位应用程序,入口函数是WinMain,而console则是运行在dos上的程序,入口函数为main。因此,当选用WinMain位入口函数后,就不再出现这个问题了。经过老师的指导,最后完成了我的毕设。附录A 程序清单*注程序清单格式:单起一页1.程序清单:标题黑体三号字,居中2.清单正文为小五号,宋体,行距15磅附录B 外文资料翻译外文资料翻译原文部分:文章出处:xxx外文资料翻译译文部分:文章出处:xxx*注:1.外文资料翻译原文部分:(*黑体小四号,左顶格*)2. 外文资料翻译原文应为复印稿或打印稿,如是打印稿,字体为Times New Roman小四号,行距24磅,间距:段前2.5磅,段后0行(0磅)3. 文章出处:xxx (* “文章出处:”为黑体小四号,“xxx”宋体小四号,右顶格*) 4.外文资料翻译译文部分:(*黑体小四号,左顶格*)(*外文资料翻译译文为宋体小四号,行距24磅,间距:段前2.5磅,段后0行(0磅)*)文章出处:xxx(*“文章出处”为黑体小四号,“xxx”宋体小四号,右顶格*)