Ogre中使用Opencv加载视频作为纹理贴图
2011-09-21 11:06
471 查看
增强现实中经常要用到真实的2D视频图片再配合虚拟对象(如三维模型)结合,以达到增强现实的效果。这里使用Ogre结合Opencv来实现
在开始前要先了解到纹理贴图的长宽必须是2的n次方,所以假如加载的视频没有达到这个值,必须做一下resize
1.创建动态纹理、背景框矩形,并添加到场景
在CreateScene中加入如下代码
2.初始化视频图像获取相关数据
3.更新顶点缓存
void UpdateTextureImage()
{
m_pVideoImage=cvQueryFrame(m_pFileCamer);
if(m_pDrawImage==0)
{
cvReleaseCapture(&m_pFileCamer);
m_pFileCamer=cvCreateFileCapture(m_szVideoPath);
m_pVideoImage=cvQueryFrame(m_pFileCamer);
}
cvShowImage("img",m_pVideoImage);
cvResize(m_pVideoImage,m_pDrawImage);
HardwarePixelBufferSharedPtr buffer=m_pTex->getBuffer(0,0);
buffer->lock(HardwareBuffer::HBL_DISCARD);
const PixelBox &pb = buffer->getCurrentLock();
uint32 *data = static_cast<uint32*>(pb.data);
size_t height = pb.getHeight();
size_t width = pb.getWidth();
size_t pitch = pb.rowPitch; // Skip between rows of image
for(size_t y=0; y<m_pDrawImage->height; ++y)
{
unsigned char *pImgLine=(unsigned char *)(m_pDrawImage->imageData+y*m_pDrawImage->widthStep);
for(size_t x=0; x<m_pDrawImage->width; ++x)
{
// 0xRRGGBB -> fill the buffer with yellow pixels
unsigned char B=pImgLine[3*x];
unsigned char G=pImgLine[3*x+1];
unsigned char R=pImgLine[3*x+2];
uint32 pixel=(R<<16)+(G<<8)+(B);
data[pitch*y + x] =pixel ;
}
}
buffer->unlock();
}[/code]
值得一提的是,在更新顶点缓存的过程中,即lock到unlock之间,由于操作硬件缓存效率低,为了提高效率,应该尽量减少代码的操作量,可选的做法是在外面将数据打包好,然后在更新的时候直接memcpy
在开始前要先了解到纹理贴图的长宽必须是2的n次方,所以假如加载的视频没有达到这个值,必须做一下resize
1.创建动态纹理、背景框矩形,并添加到场景
在CreateScene中加入如下代码
void CreateScene() { MaterialPtr material = MaterialManager::getSingleton().create( "DynamicTextureMaterial", // name ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); material->getTechnique(0)->getPass(0)->createTextureUnitState("DynamicBg"); material->getTechnique(0)->getPass(0)->setDepthCheckEnabled(false); material->getTechnique(0)->getPass(0)->setDepthWriteEnabled(false); material->getTechnique(0)->getPass(0)->setLightingEnabled(false); // Create background rectangle covering the whole screen Rectangle2D* rect = new Rectangle2D(true); rect->setCorners(-1.0, 1.0, 1.0, -1.0); rect->setMaterial("DynamicTextureMaterial"); // Render the background before everything else rect->setRenderQueueGroup(RENDER_QUEUE_BACKGROUND); // Hacky, but we need to set the bounding box to something big // NOTE: If you are using Eihort (v1.4), please see the note below on setting the bounding box rect->setBoundingBox(AxisAlignedBox(-100000.0*Vector3::UNIT_SCALE, 100000.0*Vector3::UNIT_SCALE)); // Attach background to the scene SceneNode* node = mSceneMgr->getRootSceneNode()->createChildSceneNode("Background"); node->attachObject(rect); //add other scene node here }
2.初始化视频图像获取相关数据
void InitVideoQuery(char *szVideoPath) { m_szVideoPath = szVideoPath; m_pFileCamer=cvCreateFileCapture(szVideoPath ); m_pVideoImage=cvQueryFrame(m_pFileCamer); m_pDrawImage=cvCreateImage(cvSize(1024,1024),8,3); m_pTex=TextureManager::getSingleton().createManual("DynamicBg","General", TEX_TYPE_2D,m_pDrawImage->width,m_pDrawImage->height,1,0,PF_A8B8G8R8,TU_WRITE_ONLY);}
3.更新顶点缓存
void UpdateTextureImage()
{
m_pVideoImage=cvQueryFrame(m_pFileCamer);
if(m_pDrawImage==0)
{
cvReleaseCapture(&m_pFileCamer);
m_pFileCamer=cvCreateFileCapture(m_szVideoPath);
m_pVideoImage=cvQueryFrame(m_pFileCamer);
}
cvShowImage("img",m_pVideoImage);
cvResize(m_pVideoImage,m_pDrawImage);
HardwarePixelBufferSharedPtr buffer=m_pTex->getBuffer(0,0);
buffer->lock(HardwareBuffer::HBL_DISCARD);
const PixelBox &pb = buffer->getCurrentLock();
uint32 *data = static_cast<uint32*>(pb.data);
size_t height = pb.getHeight();
size_t width = pb.getWidth();
size_t pitch = pb.rowPitch; // Skip between rows of image
for(size_t y=0; y<m_pDrawImage->height; ++y)
{
unsigned char *pImgLine=(unsigned char *)(m_pDrawImage->imageData+y*m_pDrawImage->widthStep);
for(size_t x=0; x<m_pDrawImage->width; ++x)
{
// 0xRRGGBB -> fill the buffer with yellow pixels
unsigned char B=pImgLine[3*x];
unsigned char G=pImgLine[3*x+1];
unsigned char R=pImgLine[3*x+2];
uint32 pixel=(R<<16)+(G<<8)+(B);
data[pitch*y + x] =pixel ;
}
}
buffer->unlock();
}[/code]
值得一提的是,在更新顶点缓存的过程中,即lock到unlock之间,由于操作硬件缓存效率低,为了提高效率,应该尽量减少代码的操作量,可选的做法是在外面将数据打包好,然后在更新的时候直接memcpy
相关文章推荐
- Ogre中使用Opencv加载视频作为纹理贴图
- 使用glfw库将OpenCV读取到的图片作为OpenGL的背景纹理贴图
- Lnux环境下,用opencv加载纹理贴图
- opencv 处理视频并使用Qt窗口作为输出
- Ogre利用OpenCV实现视频纹理
- 使用二维纹理贴图,从24位位图加载,用vertex方式绘制
- 使用Ogre快速渲染视频纹理
- Ogre利用OpenCV实现视频纹理
- 使用 Visual Studio 2008 和 OpenCV 在窗口显示图片或视频
- Opencv step by step - 加载视频
- OGRE 3D使用resources_d.cfg加载模型(类的实现)
- Android使用WebView加载有声音或视频的网页时,关闭webView时,声音没有关闭的问题
- Python OpenCV学习笔记之:使用KNN对视频背景消除
- 【OpenCV开发】OpenCV:使用VideoCapture类进行视频读取和显示
- 使用视频作为网页背景的技术探讨
- 使用opencv进行多路视频的播放
- 在Ogre中使用DirectShow来播放视频--重新封装并测试通过
- 从OGRE纹理到CEGUI纹理 —— 使用RTT实现3D角色预览
- 利用opencv读取图片将其作为opengl的纹理图片的实现方法
- 在linux中安装opencv 2.1-正常使用视频文件