千张笔记

Email:rain_qian830@163.com
posts - 28, comments - 42, trackbacks - 0, articles - 0
  C++博客 :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理

【原】OpenGL显示视频(7月27日工作小记)

Posted on 2009-07-27 20:49 千张 阅读(7883) 评论(2)  编辑 收藏 引用 所属分类: 图形学

这周是实习的第三周了,坚持了两周,慢慢也就习惯上班了,好了,说正事吧,O(∩_∩)O~
今天小秦老师交给我的任务是用OpenGL显示摄像头中拍摄的画面,要全屏显示的。上周他已经把程序框架给了我,所以一些初始化的工作我就不用做了,直接加东西就行了。
从图像采集卡中读取图像采用的是小秦老师给我的dll,他们自己编写的类,可以参考OpenCV'中的ARFrameGrabber类。


获取当前帧后,显示图像就很容易了,可以用纹理映射,将当前帧映射到一个矩形上,该矩形大小为视口大小。

下面为初始化函数:
bool OpenGLDraw::Initialize()
{
    
//opengl Initialize

    
//获得屏幕分辨率
    int nFullWidth=GetSystemMetrics(SM_CXSCREEN); 
    
int nFullHeight=GetSystemMetrics(SM_CYSCREEN); 

    
//初始化视频设备
    PalCapture.Init( 0false768576330true);
    
    
//开启纹理映射和设置纹理参数
    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, 7685760, GL_RGB, GL_UNSIGNED_BYTE,NULL );

    
/********************观察视点设置*******************/            
    glViewport(
00, nFullWidth, nFullHeight);
    glMatrixMode(GL_PROJECTION);    
    glLoadIdentity();
    gluOrtho2D(
-11-11);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

    
return true;
}

下面为绘制函数:
void OpenGLDraw::Draw()
{
    glClear(GL_COLOR_BUFFER_BIT 
| GL_DEPTH_BUFFER_BIT);
    glClearColor(
0.0f0.0f0.0f0.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, 000768576, GL_RGB, GL_UNSIGNED_BYTE, pTempImg->imageData);
        
    glBegin(GL_QUADS);
      glTexCoord2f(
0.0f0.0f); glVertex2f(-1.0f,-1.0f);
      glTexCoord2f(
1.0f0.0f); glVertex2f(1.0f,-1.0f);
      glTexCoord2f(
1.0f1.0f); glVertex2f(1.0f,1.0f);
      glTexCoord2f(
0.0f1.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 abc

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理