为什么GLUT加载图像倾斜,并像一个循环缓冲区一样倒置在窗口上?

时间:2015-10-18 23:28:02

标签: c++ opencv opengl

我使用glut函数和opencv的IplImage数据结构组合了一个过量初始化器和图像视图,但出于某些不幸的原因,结果并不那么简单。

这是真实的形象 enter image description here

这是实际结果 enter image description here

首先我运行以下功能:

void initGlutTools(int argc, char **argv)
{
    /* Get Image */
    IplImage *image = cvLoadImage(imagePath.c_str(), CV_LOAD_IMAGE_COLOR);
    if(image == NULL) cout << "Cannot open image " << endl;
    cout << "width: " << image->width << "height: " << image->height << endl;
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
    glutInitWindowSize(image->width, image->height);
    glutInitWindowPosition(100, 100);
    glutCreateWindow("Iancovici's 2D Particle Filter");

    gluOrtho2D(0.0, 1.0, 0.0, 1.0);

    glEnable( GL_POINT_SMOOTH );
    glEnable( GL_BLEND );
    glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
    glPointSize( 1.0 );

    glClearColor ( 0, 0, 0, 0 );
    glShadeModel( GL_SMOOTH );
    glDisable( GL_LIGHTING );
    glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
    glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
    glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
    glTexImage2D( GL_TEXTURE_2D, 0, 3, image->width, image->height, 0, GL_RGB, GL_UNSIGNED_BYTE, image->imageData);
    glEnable( GL_TEXTURE_2D );

    glutDisplayFunc(&gl_display);
    glutIdleFunc(&gl_idle);

}

,gl_display函数如下

void gl_display(void)
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    // Draw background.
    glEnable( GL_TEXTURE_2D );
    glColor3f(0.5f, 0.5f, 0.5f);
    glBegin(GL_QUADS);

    glTexCoord2f(0, 1);
    glVertex2f(0, 1);
    glTexCoord2f(0, 0);
    glVertex2f(0, 0);
    glTexCoord2f(1, 0);
    glVertex2f(1, 0);
    glTexCoord2f(1, 1);
    glVertex2f(1, 1);
    glEnd();

    // Draw objects.
    glDisable( GL_TEXTURE_2D );
    glColor3f(0.0, 1.0, 0.0);
    glPointSize(1.0);

    // Draw poses
    glPointSize(5.0f);
    glBegin(GL_POINTS);
    glColor3f(1.0f, 0.0f, 0.0f);
    glVertex2f(real_pose.x / MAP_WIDTH, real_pose.y / MAP_HEIGHT);
    glColor3f(0.0f, 0.3f, 1.0f);
    glVertex2f(best_pose.x / MAP_WIDTH, best_pose.y / MAP_HEIGHT);
    glEnd();

    glutSwapBuffers();
}

gl_idle函数只是

void gl_idle(void)
{    
    glutPostRedisplay();
    sleep(0.05);
}

最后,在并发线程上我运行了glutMainLoop

但我不确定是什么原因导致这种变形。我认为它可能与glBegin(GL_QUADS)有关,你可以在glEnd中定义顶点和纹理坐标,但是没有去这里。

1 个答案:

答案 0 :(得分:4)

OpenCV&#39; IlpImage不会将图像存储为紧密排列的数组,正如您的GL代码目前所建议的那样。相反,每条线可能是对齐的。描述它的相关字段是widthStep,它定义了两个连续行之间的字节偏移量。不幸的是,这并没有直接映射到GL,它只接受像素中的GL_UNPACK_ROW_LENGHT。对于额外的对齐,您必须手动将其分为GL_UNPACK_ROW_LENGTHGL_UNPACK_ALIGNMENT

如果您的输入格式为RGB,每个通道有1个字节,则应该可以使用:

glPixelStorei(GL_UNPACK_ROW_LENGTH, image->widthStep/3);
int align=1;
for (int s=image->widthStep; (align<8) && !(s&1); s>>=1)
    align<<=1;
glPixelStorei(GL_UNPACK_ALIGNMENT, align);

这当然假设图像行以1,2,4或8字节边界对齐,否则无论如何都无法将数据直接输入GL。