因研究需要,这几天想把Opecv获取的视频帧转到OSG中作为纹理背景输出,关键的一步就是Opencv帧图像的传递。
那么问题来了:Opencv存放图像数据的格式和OSG的差异大吗?
因为自己也是个新手,首先找到了
osg抓帧放到openCV里
http://wenku.baidu.com/link?url=PXeAHmmV7vyA7s2fEK30_gEQvJzpHA9uDl9y1YIUHstCXCj_HKOTGjs_5PMnesuFDocCapTlBOyp5UjzWDu0LE7VayoDq98X3jzpPpyiQCm
原作者无从可考,但是留下了一句重要的代码:
memcpy((unsigned char*)pIplImg->imageData,pCImg->data(),pCImg->getImageSizeInBytes());
给出的信息就是两者数据转换,只要知道长和宽,以及像素数据的指针位置就可以了。完整的代码如下:
IplImage* CImage2IplImage(osg::ref_ptr<osg::Image> pCImg,IplImage *pIplImg){//输出图像设置pIplImg->origin=IPL_ORIGIN_BL;//输入图像信息memcpy((unsigned char*)pIplImg->imageData,pCImg->data(),pCImg->getImageSizeInBytes());//将RGB存储为BGRunsigned int temp=0;for (int y=0;y<pIplImg->height;y++){uchar* ptr=(uchar*)(pIplImg->imageData+y*pIplImg->widthStep);for (int x=0;x<pIplImg->width;x++){temp=ptr[3*x];//保存原始的R值ptr[3*x]=ptr[3*x+2];ptr[3*x+2]=temp;}}return pIplImg;}
顺藤摸瓜,再重申下我的目的是Opencv的图转成OSG的,因为配置了Opencv2.0,所以使用了最新的图像格式Mat(同时包括了老版本的IplImage和cvMat)
于是任务变成:Opencv Mat->OSG::Image
去Image看构造函数,只有setImage中要求设定长款和char* data,数据格式相符。OSG源码:
/** Set the image dimensions, format and data. */
virtual void setImage(int s,int t,int r,
GLint internalTextureformat,
GLenum pixelFormat,GLenum type,
unsigned char* data,
AllocationMode mode,
int packing=1, int rowLength=0);
之后试了一下居然成了。我的代码:
osg::ref_ptr<osg::Image> mat2img::mat2image(Mat cvimg){osgframe=new osg::Image;osgframe->setImage(cvimg.cols,cvimg.rows,3,GL_BGR,GL_BGR,GL_UNSIGNED_BYTE,cvimg.data,osg::Image::NO_DELETE,1);if(osgframe)printf("convert done!");osgDB::writeImageFile(*osgframe,"D:\\OV2OV\\OV2OV\\osgframe.bmp");return osgframe;}
调试输出的图片和文字信息全部正确。
之后就是重新加工视频流了,用osg纹理贴图即可。