|
Posted on 2009-07-27 20:49 千张 阅读(7950) 评论(2) 编辑 收藏 引用 所属分类: 图形学
这周是实习的第三周了,坚持了两周,慢慢也就习惯上班了,好了,说正事吧,O(∩_∩)O~ 今天小秦老师交给我的任务是用OpenGL显示摄像头中拍摄的画面,要全屏显示的。上周他已经把程序框架给了我,所以一些初始化的工作我就不用做了,直接加东西就行了。 从图像采集卡中读取图像采用的是小秦老师给我的dll,他们自己编写的类,可以参考OpenCV'中的ARFrameGrabber类。
获取当前帧后,显示图像就很容易了,可以用纹理映射,将当前帧映射到一个矩形上,该矩形大小为视口大小。 下面为初始化函数:
bool OpenGLDraw::Initialize() { //opengl Initialize
//获得屏幕分辨率 int nFullWidth=GetSystemMetrics(SM_CXSCREEN); int nFullHeight=GetSystemMetrics(SM_CYSCREEN);
//初始化视频设备 PalCapture.Init( 0, false, 768, 576, 3, 30, true); //开启纹理映射和设置纹理参数 glEnable(GL_TEXTURE_2D); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); //线性滤波 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); //线性滤波 //生成空纹理 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 768, 576, 0, GL_RGB, GL_UNSIGNED_BYTE,NULL );
/**//********************观察视点设置*******************/ glViewport(0, 0, nFullWidth, nFullHeight); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluOrtho2D(-1, 1, -1, 1); glMatrixMode(GL_MODELVIEW); glLoadIdentity();
return true; }
下面为绘制函数:
void OpenGLDraw::Draw() { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glClearColor(0.0f, 0.0f, 0.0f, 0.0f); glLoadIdentity(); pFrmImage = PalCapture.GetImage(); IplImage *pTempImg = cvCloneImage( pFrmImage); if (pFrmImage->origin == IPL_ORIGIN_TL) //将图像原点统一设置成左下角 { cvFlip(pFrmImage, pTempImg, 0); //翻转图像 pTempImg->origin = IPL_ORIGIN_BL; //将pTempImg图像的原点设置成左下角 } //更新纹理 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 768, 576, GL_RGB, GL_UNSIGNED_BYTE, pTempImg->imageData); glBegin(GL_QUADS); glTexCoord2f(0.0f, 0.0f); glVertex2f(-1.0f,-1.0f); glTexCoord2f(1.0f, 0.0f); glVertex2f(1.0f,-1.0f); glTexCoord2f(1.0f, 1.0f); glVertex2f(1.0f,1.0f); glTexCoord2f(0.0f, 1.0f); glVertex2f(-1.0f,1.0f); glEnd(); glFlush(); cvReleaseImage(&pTempImg); }
其中PalCapture是视频采集卡类的对象,获取一帧图像即pFrmImage,pFrmImage是IplImage类型的图像,此处直接对pFrmImage的imageData进行操作。 关于显示视频 (AVI视频) ,NEHE的OpenGL课程的第35课中有详细介绍,我也是参考那个的~~只不多OpenCV中有翻转函数cvFlip函数,我就不用自己写了~~ NEHE的课程还提到:使用glTexSubImage2D()另一个重要原因.不仅因为在许多OpenGL实现中它很快,还因为目标区不必是2的幂.这对视频重放很方便,因为一帧的维通常不是2的幂(而是像320*200之类的).这样给了你很大机动性,你可以按视频流原本的样子播放,而不是扭曲或剪切每一帧来适应纹理的维。
所以这里我没有把图像转换成纹理要求的大小(大小为2的非负n次幂),不知道这样做对不对,不过画面显示效果看起来还不错。 这么几行代码,我还弄了一天,貌似红宝书上有的,还是基础不牢噢 。明天有网络传输数据方面的任务,关于网络,我可是一点都不懂 ,慢慢看吧 。
Feedback
# re: 【原】OpenGL显示视频(7月27日工作小记) 回复 更多评论
2009-07-28 15:14 by
奥斯卡大家阿斯顿!
# re: 【原】OpenGL显示视频(7月27日工作小记) 回复 更多评论
2012-09-06 18:46 by
赞
|