将OpenGL纹理转换为OpenCV矩阵



我一直在寻找一种将OpenGL纹理转换为OpenCV矩阵类型的方法。我已经找到了许多指南,显示了从OpenCV矩阵到OpenGL纹理的转换,但遗憾的是,没有相反的方式。我也读过这篇文章和它的答案,但它并没有让我变得更聪明。我用C++编写,使用OpenCV3.1和OpenGL4.4。

编辑:更新的代码

main.cpp:

#include "CameraCapture.h"
#include "GUIMainWindow.h"
#include "glfw3.h"
#include "Texture.h"
using namespace std;
int main(int argc, char* argv[]) {
    if (!glfwInit()) {
        fprintf(stderr, "Failed to initialize GLFW n");
        return -1;
    }
    glfwWindowHint(GLFW_VISIBLE, GL_FALSE);
    GLFWwindow* window = glfwCreateWindow(1929, 1341, "OpenGL", NULL, NULL);
    if (window == NULL) {
        fprintf(stderr, "Failed to make GLFW window.");
        glfwTerminate();
        return -1;
    }
    glfwMakeContextCurrent(window);
    CameraCapture *cc = new CameraCapture();
    cc->CameraCapture::AvailableCameras();
    GLuint texture = cc->CameraCapture::OpenCamera(0);
    glEnable(GL_TEXTURE_2D);
    glBindTexture(GL_TEXTURE_2D, texture);
    drawGLTexture(window);
    Mat out = textureToMat(texture);
    namedWindow("Raytrix feed", WINDOW_AUTOSIZE);
    imshow("Raytrix feed", out);
    waitKey(0);
    return 0;
}

纹理.cpp:

Mat textureToMat(GLuint texture_id) {
    glBindTexture(GL_TEXTURE_2D, texture_id);
    GLenum texture_width, texture_height;
    glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, (GLint*)&texture_width);
    glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, (GLint*)&texture_height);
    unsigned char* texture_bytes = (unsigned char*)malloc(sizeof(unsigned char)*texture_width*texture_height * 4);
    glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, texture_bytes);
    return Mat(texture_height, texture_width, CV_8UC4, texture_bytes);
}
void drawGLTexture(GLFWwindow *window) {
    glColor3f(1.0f, 1.0f, 1.0f);
    glBegin(GL_TRIANGLES);
    glTexCoord2f(0, 1);
    glVertex2f(-1, -1);
    glTexCoord2f(1, 1);
    glVertex2f(1, -1);
    glTexCoord2f(0, 0);
    glVertex2f(-1, 1);
    glTexCoord2f(1, 1);
    glVertex2f(1, -1);
    glTexCoord2f(1, 0);
    glVertex2f(1, 1);
    glTexCoord2f(0, 0);
    glVertex2f(-1, 1);
    glEnd();
    glfwSwapBuffers(window);
    glfwPollEvents();
    glFlush();
    glFinish();
}

标题:

#ifndef TEXTURE_H
#define TEXTURE_H
#include "glew.h"
#include "glfw3.h"
#include <string>
#include <iostream>
#include <vector>
#include <opencvhighgui.h>
#include <opencvcv.h>
#include <opencv2opencv.hpp>
using namespace std;
using namespace cv;
Mat textureToMat(GLuint textureID);
void drawGLTexture(GLFWwindow *window);
#endif /*!TEXTURE_H*/

我已经测试了下面的代码,它似乎可以工作。(注意GL_BGRglGetTexImage()中的用法)。

cv::Mat get_ocv_img_from_gl_img(GLuint ogl_texture_id)
{
    glBindTexture(GL_TEXTURE_2D, ogl_texture_id);
    GLenum gl_texture_width, gl_texture_height;
    glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, (GLint*)&gl_texture_width);
    glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, (GLint*)&gl_texture_height);
    unsigned char* gl_texture_bytes = (unsigned char*) malloc(sizeof(unsigned char)*gl_texture_width*gl_texture_height*3);
    glGetTexImage(GL_TEXTURE_2D, 0 /* mipmap level */, GL_BGR, GL_UNSIGNED_BYTE, gl_texture_bytes);
    return cv::Mat(gl_texture_height, gl_texture_width, CV_8UC3, gl_texture_bytes);
}
  1. 首先需要绑定要检索的纹理,然后获取其尺寸
  2. 找出一个连续的内存区域来放入符合OpenGL要求的数据
  3. 最后使用glGetTexImage来获得像素

伪码:

GLint width,height,alignment;
glBindTexture(GL_TEXTURE_2D, textureID);
glGetIntegerv(GL_PACK_ALIGNMENT, &alignment);
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &width);
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &height);
// Fiddle with alignment to make sure you get properly aligned buffer/width.
byte* imagedata = new byte[width*height*3];
glGetTexImage(GL_TEXTURE_2D, 0, GL_RGB, GL_UNSIGNED_BYTE, imagedata);
// move data to cv::Mat or use cv::Mat to allocate to original image buffer (imagedata)
// but be mindful that the memory region in cv::Mat is contiguous and the right
// size and all.

https://www.opengl.org/sdk/docs/man2/xhtml/glGetTexImage.xml

https://www.opengl.org/sdk/docs/man2/xhtml/glGet.xml

https://www.opengl.org/sdk/docs/man2/xhtml/glGetTexLevelParameter.xml

相关内容

  • 没有找到相关文章

最新更新