簡體   English   中英

OpenCV IplImage *圖像到OpenGL GLuint紋理

[英]OpenCV IplImage *Image to OpenGL GLuint texture

我試圖使用OpenGL / GLFW和OpenCV同時在兩個屏幕上顯示視頻。 當我在我的筆記本電腦上測試我的代碼(2010年中期13“Macbook Pro)和外部屏幕時,程序工作得很好(減去視頻以非常快的FPS播放的事實 - 任何能夠解決這個問題的人都會非常有幫助。它也是顛倒的,但OpenCV可以輕松翻轉。)但是當我將代碼移到2008年初的Mac Pro並運行代碼時,圖像似乎沒有正確的紋理。圖片如下:

三個顏色通道占據不同的列

由於某種原因,三個顏色記錄被分成不同的列,並且框架不正確。 它應該是這樣的:

更好的形象

圖像的放置並不重要,這僅僅是因為屏幕尺寸的差異。 我想知道是否有人之前已經看過這個問題,如果它只是一個問題我如何調用glTexImage2D? 下面發布的是我正在使用的代碼。

#include <stdio.h>
#include <string.h>

#include <opencv/cv.h>
#include <opencv/highgui.h>
#include <opencv2/imgproc/imgproc.hpp>

#include <GLFW/glfw3.h>
#include <GLUT/glut.h>

#define VIEWPORT_WIDTH              1280
#define VIEWPORT_HEIGHT             800
#define KEY_ESCAPE                  27

CvCapture* capture;
GLFWwindow* window1;
GLFWwindow* window2;
IplImage *image;
static GLuint texName;

void initTexture(IplImage* Image);
void applyTexture(int img_width, int img_height);
void loadImage(IplImage*, GLFWwindow* window);

int main(int argc, char* argv[])
{

    if (!glfwInit())
        exit(EXIT_FAILURE);

    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
    glutInitWindowSize(VIEWPORT_WIDTH, VIEWPORT_HEIGHT);

    int count;
    GLFWmonitor** monitors = glfwGetMonitors(&count);
    window1 = glfwCreateWindow(VIEWPORT_WIDTH, VIEWPORT_HEIGHT, "Simple example1", monitors[0], NULL);
    window2 = glfwCreateWindow(VIEWPORT_WIDTH, VIEWPORT_HEIGHT, "Simple example2", monitors[1], NULL);

    capture = cvCaptureFromAVI("../VideoTexture/movie.mov");
    assert(capture);
    // Initialize OpenGL
    glfwMakeContextCurrent(window1);


    while (!glfwWindowShouldClose(window1))
    {
            image = cvQueryFrame(capture);
    if(!cvGrabFrame(capture)){              // capture a frame 
        printf("Could not grab a frame\n\7");
        exit(0);
    }


        glfwMakeContextCurrent(window1);
        loadImage(image, window1);
        glfwMakeContextCurrent(window2);
        loadImage(image, window2);

    }


    return 0;


}

void initTexture(IplImage *Image)
{
    glClearColor(0.0, 0.0, 0.0, 0.0);
    glShadeModel(GL_FLAT);
    glEnable(GL_DEPTH_TEST);

    glGenTextures(1, &texName);
    glBindTexture(GL_TEXTURE_2D, texName);

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);

    glTexImage2D(GL_TEXTURE_2D, 0, 3, Image->width, Image->height, 0, GL_BGR, GL_UNSIGNED_BYTE, Image->imageData);
}

void applyTexture(int img_width, int img_height)
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glEnable(GL_TEXTURE_2D);
    glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
    glBindTexture(GL_TEXTURE_2D, texName);
    glBegin(GL_QUADS);
    glTexCoord2f(0, 0); glVertex3f(VIEWPORT_WIDTH /2, VIEWPORT_HEIGHT/2, 0);
    glTexCoord2f(0, 1); glVertex3f(VIEWPORT_WIDTH /2, VIEWPORT_HEIGHT/2+img_height, 0);
    glTexCoord2f(1, 1); glVertex3f(VIEWPORT_WIDTH /2+img_width, VIEWPORT_HEIGHT/2+img_height, 0);
    glTexCoord2f(1, 0); glVertex3f(VIEWPORT_WIDTH /2+img_width, VIEWPORT_HEIGHT/2, 0);
    glEnd();
    glFlush();
    glDisable(GL_TEXTURE_2D);
}

void loadImage(IplImage *Image, GLFWwindow* window)
{
    initTexture(Image);
    glViewport(0, 0, VIEWPORT_WIDTH , VIEWPORT_HEIGHT);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(0, VIEWPORT_WIDTH , 0, VIEWPORT_HEIGHT, -1, 1);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    applyTexture(Image->width,Image->height);
    glfwSwapBuffers(window);
    glfwPollEvents();
}

解決了:

添加以下兩行解決了這個問題。

glPixelStorei (GL_UNPACK_ALIGNMENT,  Image->align);
glPixelStorei (GL_UNPACK_ROW_LENGTH, Image->widthStep / Image->nChannels);

向GL發送/讀取RGB圖像時,需要將像素解包/包對齊設置為1 默認情況下,GL將讀取您的圖像數據,就好像每一行都與4字節邊界對齊一樣,並且顯然是緊湊的(8位)RGB,而不是這種情況。

這應該至少解決部分問題:

glPixelStorei (GL_UNPACK_ALIGNMENT, 1);
glTexImage2D  (GL_TEXTURE_2D, 0, 3, Image->width, Image->height, 0, GL_BGR, GL_UNSIGNED_BYTE, Image->imageData);


更新:

IplImage數據結構提供了所需的所有字段,以便可移植地執行此操作:

glPixelStorei (GL_UNPACK_ALIGNMENT,  Image->align);
glPixelStorei (GL_UNPACK_ROW_LENGTH, Image->widthStep / Image->nChannels);
glTexImage2D  (GL_TEXTURE_2D, 0, 3,  Image->width, Image->height, 0, GL_BGR, GL_UNSIGNED_BYTE, Image->imageData);

然而,根本問題是一樣的。 它歸結為兩台機器之間圖像數據對齊的差異。

至於您的圖像是顛倒的,請查看IplImage結構的origin字段。 你需要自己補償。 不幸的是,GL不具備在像素傳輸期間翻轉圖像的能力。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM