OpenGL与OpenCV间传输图像数据

来源:互联网 发布:淘宝店铺怎么能排前面 编辑:程序博客网 时间:2024/05/07 23:35

之前一直苦于寻找OpenGL与OpenCV间的数据传输方法,对这两个库运用得不是很熟,在网上找的的方法却是OpenCV往OpenGL传输纹理和数据,即OpenCV把图做出来然后把数据传给OpenGL,让OpenGL来显示。但是我想要的方法是OpenGL往OpenCV传输数据,即OpenGL把图画好之后把图像的像素数据传输给OpenCV作一些处理(如平滑,提取边缘之类的),于是到冒着被墙的危险到国外论坛发帖求助,一哥们说glGetTexImage函数即可,于是去查阅此函数,发现也不过是把数据读入buffer,和glReadPixels函数类似。经过一番搜索,发现把buffer的数据copy到一个IplImage中就行了,具体方法如下:

1. OpenGL往OpenCV传输数据

IplImage* SaveCvImg(){        /* 获取视口数据 */GLint viewPort[4] = { 0 };glGetIntegerv(GL_VIEWPORT, viewPort);GLubyte* buffer = (GLubyte*)malloc(viewPort[2] * viewPort[3] * sizeof(GLubyte) * 3);/* 读取图像缓冲区数据 */glReadPixels(viewPort[0], viewPort[1], viewPort[2], viewPort[3], GL_BGR, GL_UNSIGNED_BYTE, buffer);/* 将数据保存在IplImage中 *//* 深度为8,通道数为3,24位图 */IplImage* model2DImg = cvCreateImage(mImgSize, IPL_DEPTH_8U, 3);/* 复制地址,所以最后不能free(buffer) */model2DImg->imageData = (char*)buffer;/* 由于OpenGL与OpenCv读取buffer的方向在y轴上相反,所以作x轴翻转,第二个参数为 * NULL表示作原地翻转. */cvFlip(model2DImg, NULL, 0);return model2DImg;}

上面的代码中我直接让model2DImg->imageData的地址等于buffer的地址,如果大家担心指针及内存释放的问题,可以直接使用memcpy:

...memcpy(model2DImg->imageData, buffer, Width*Heigh*3);...free(buffer);

再有就是上面的翻转。由于我之前用的方法是把buffer的数据直接加上一个文件头,以bmp的方式存储,也许读取buffer的方向与OpenCV的方向不一致,主要是y轴方向上的不一致,所以作了一个翻转。

2. OpenCV往OpenGL传数据

这个就比较简单了,直接读取IplImage的三个通道的数据行了,单通道的话就只读取单通道,下面以读取纹理数据为例:

//////////////////////////////////////////////////////////////////////////// 载入图像纹理数据void loadTextureToGL(IplImage* img){      CvScalar ss;   //accessing the image pixels   for (int i=0;i<height;i++)   {       for (int j=0;j<width;j++)      {         ss=cvGet2D(img,i,j);         // ss.val[0] = red, ss.val[1] = green, ss.val[2] = blue         texture[i][j][2] = ss.val[0];         texture[i][j][1] = ss.val[1];         texture[i][j][0] = ss.val[2];      }   }    }

发现了解一下函数库的底层还是比较有用的,从原理入手才能更加灵活地运用!