带有自定义投影矩阵的OpenGL GL_DEPTH_TEST

时间:2015-09-08 07:54:45

标签: opencv opengl depth

我正在使用OpenCV和OpenGL为桌面开发增强现实应用程序,因为我正在使用具有相机校准参数的自定义投影矩阵来实现这一点。下一步是从场景中提取深度图。 现在的问题是当我做glEnable(GL_DEPTH_TEST)时,立方体消失了。请帮帮我。

这是我的代码:

#include "GeometryTypes.hpp"
#include "CameraCalibration.hpp"
#include "ARPipeline.hpp"

#include <GL/glew.h>
#include <GL/freeglut.h>

#include <opencv2/opencv.hpp>

#define GL_CHECK_ERRORS assert(glGetError()== GL_NO_ERROR);

class Renderer
{

public : 
Renderer(const CameraCalibration& c) : m_isTextureInitialized(false), m_calibration(c), x_direction(0.0f), y_direction(0.0f)
{

}

~Renderer()
{

}

bool isPatternPresent;
Transformation patternPose;

float x_direction, y_direction;

void updateBackground(const cv::Mat& frame)
{
    frame.copyTo(m_backgroundImage);
}

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

    drawCameraFrame();      
    drawAugmentedScene();

    int w = m_backgroundImage.cols;
    int h = m_backgroundImage.rows;

    cv::Mat mat(h, w, CV_32FC1);
    glReadPixels(0, 0, w, h, GL_DEPTH_COMPONENT, GL_FLOAT, mat.data);
    cv::flip(mat, mat, 0);
    cv::imshow("test", mat);

    glutSwapBuffers();
}

void drawCameraFrame()
{
    if (!m_isTextureInitialized)
    {
        glGenTextures(1, &m_backgroundTextureId);
        glBindTexture(GL_TEXTURE_2D, m_backgroundTextureId);

        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

        m_isTextureInitialized = true;
    }

    int w = m_backgroundImage.cols;
    int h = m_backgroundImage.rows;

    glPixelStorei(GL_PACK_ALIGNMENT, 1);
    glBindTexture(GL_TEXTURE_2D, m_backgroundTextureId);

    if (m_backgroundImage.channels() == 3)
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, w, h, 0, GL_BGR_EXT, GL_UNSIGNED_BYTE, m_backgroundImage.data);
    else if(m_backgroundImage.channels() == 4)
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, w, h, 0, GL_BGRA_EXT, GL_UNSIGNED_BYTE, m_backgroundImage.data);
    else if (m_backgroundImage.channels()==1)
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, w, h, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, m_backgroundImage.data);

    const GLfloat bgTextureVertices[] = { 0, 0, w, 0, 0, h, w, h };
    const GLfloat bgTextureCoords[]   = { 1, 0, 1, 1, 0, 0, 0, 1 };
    const GLfloat proj[]              = { 0, -2.f/w, 0, 0, -2.f/h, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1 };

    glMatrixMode(GL_PROJECTION);
    glLoadMatrixf(proj);
    //glLoadIdentity();

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

    glEnable(GL_TEXTURE_2D);
    glBindTexture(GL_TEXTURE_2D, m_backgroundTextureId);


    glEnableClientState(GL_VERTEX_ARRAY);
    glEnableClientState(GL_TEXTURE_COORD_ARRAY);

    glVertexPointer(2, GL_FLOAT, 0, bgTextureVertices);
    glTexCoordPointer(2, GL_FLOAT, 0, bgTextureCoords);

    glColor4f(1,1,1,1);
    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

    glDisableClientState(GL_VERTEX_ARRAY);
    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
    glDisable(GL_TEXTURE_2D);
}

void drawAugmentedScene()
{
    Matrix44 projectionMatrix;
    int w = m_backgroundImage.cols;
    int h = m_backgroundImage.rows;
    buildProjectionMatrix(m_calibration, w, h, projectionMatrix);

    glPushMatrix();

    glMatrixMode(GL_PROJECTION);
    glLoadMatrixf(projectionMatrix.data);
    //glLoadIdentity();
    //glFrustum(-1.0, 1.0, -1.0, 1.0, 1.5, 20.0);


    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

    if (isPatternPresent)
    {
        Matrix44 glMatrix = patternPose.getMat44();
        glLoadMatrixf(reinterpret_cast<const GLfloat*>(&glMatrix.data[0]));

        drawCoordinateAxis();

        drawCubeModel();
    }
}

void buildProjectionMatrix(const CameraCalibration& calibration, int w, int h, Matrix44& projectionMatrix)
{
    float nearPlane = 0.01f;  
    float farPlane  = 1000.0f;  

    float f_x = calibration.fx();
    float f_y = calibration.fy(); 
    float c_x = calibration.cx(); 
    float c_y = calibration.cy(); 


    projectionMatrix.data[0] = -2.0f * f_x / w;
    projectionMatrix.data[1] = 0.0f;
    projectionMatrix.data[2] = 0.0f;
    projectionMatrix.data[3] = 0.0f;

    projectionMatrix.data[4] = 0.0f;
    projectionMatrix.data[5] = 2.0f * f_y / h;
    projectionMatrix.data[6] = 0.0f;
    projectionMatrix.data[7] = 0.0f;

    projectionMatrix.data[8] = 2.0f * c_x / w - 1.0f;
    projectionMatrix.data[9] = 2.0f * c_y / h - 1.0f;    
    projectionMatrix.data[10] = -( farPlane + nearPlane) / ( farPlane - nearPlane );
    projectionMatrix.data[11] = -1.0f;

    projectionMatrix.data[12] = 0.0f;
    projectionMatrix.data[13] = 0.0f;
    projectionMatrix.data[14] = -2.0f * farPlane * nearPlane / ( farPlane - nearPlane );        
    projectionMatrix.data[15] = 0.0f;

}

void drawCoordinateAxis()
{
    static float lineX[] = {0,0,0,1,0,0};
    static float lineY[] = {0,0,0,0,1,0};
    static float lineZ[] = {0,0,0,0,0,1};

    glLineWidth(2);

    glBegin(GL_LINES);

    glColor3f(1.0f, 0.0f, 0.0f);
    glVertex3fv(lineX);
    glVertex3fv(lineX + 3);

    glColor3f(0.0f, 1.0f, 0.0f);
    glVertex3fv(lineY);
    glVertex3fv(lineY + 3);

    glColor3f(0.0f, 0.0f, 1.0f);
    glVertex3fv(lineZ);
    glVertex3fv(lineZ + 3);

    glEnd();
}

void drawCubeModel()
{
    static const GLfloat LightAmbient[]=  { 0.25f, 0.25f, 0.25f, 1.0f };   
    static const GLfloat LightDiffuse[]=  { 0.1f, 0.1f, 0.1f, 1.0f };    
    static const GLfloat LightPosition[]= { 0.0f, 0.0f, 2.0f, 1.0f };    

    glPushAttrib(GL_COLOR_BUFFER_BIT | GL_CURRENT_BIT | GL_ENABLE_BIT | GL_LIGHTING_BIT | GL_POLYGON_BIT | GL_DEPTH_BUFFER_BIT);

    glColor4f(0.2f,0.35f,0.3f,0.75f);        
    glBlendFunc(GL_ONE,GL_ONE_MINUS_SRC_ALPHA);       
    glEnable(GL_BLEND); 

    glShadeModel(GL_SMOOTH);

    glEnable(GL_LIGHTING);
    glDisable(GL_LIGHT0);
    glEnable(GL_LIGHT1);
    glLightfv(GL_LIGHT1, GL_AMBIENT, LightAmbient);
    glLightfv(GL_LIGHT1, GL_DIFFUSE, LightDiffuse);
    glLightfv(GL_LIGHT1, GL_POSITION, LightPosition);
    glEnable(GL_COLOR_MATERIAL);

    glScalef(0.25,0.25, 0.25);
    glTranslatef(0,0, 1);

    glPushMatrix();

    glTranslatef(x_direction, y_direction, 0);

    glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
    glBegin(GL_QUADS); 

    glNormal3f( 0.0f, 0.0f, 1.0f);    
    glVertex3f(-1.0f, -1.0f,  1.0f);  
    glVertex3f( 1.0f, -1.0f,  1.0f);  
    glVertex3f( 1.0f,  1.0f,  1.0f);  
    glVertex3f(-1.0f,  1.0f,  1.0f);  

    glNormal3f( 0.0f, 0.0f,-1.0f);    
    glVertex3f(-1.0f, -1.0f, -1.0f);  
    glVertex3f(-1.0f,  1.0f, -1.0f);  
    glVertex3f( 1.0f,  1.0f, -1.0f);  
    glVertex3f( 1.0f, -1.0f, -1.0f);  

    glNormal3f( 0.0f, 1.0f, 0.0f);    
    glVertex3f(-1.0f,  1.0f, -1.0f); 
    glVertex3f(-1.0f,  1.0f,  1.0f);  
    glVertex3f( 1.0f,  1.0f,  1.0f);  
    glVertex3f( 1.0f,  1.0f, -1.0f);  

    glNormal3f( 0.0f,-1.0f, 0.0f);    
    glVertex3f(-1.0f, -1.0f, -1.0f);  
    glVertex3f( 1.0f, -1.0f, -1.0f);  
    glVertex3f( 1.0f, -1.0f,  1.0f);  
    glVertex3f(-1.0f, -1.0f,  1.0f);  

    glNormal3f( 1.0f, 0.0f, 0.0f);    
    glVertex3f( 1.0f, -1.0f, -1.0f);  
    glVertex3f( 1.0f,  1.0f, -1.0f);  
    glVertex3f( 1.0f,  1.0f,  1.0f);  
    glVertex3f( 1.0f, -1.0f,  1.0f);  

    glNormal3f(-1.0f, 0.0f, 0.0f);    
    glVertex3f(-1.0f, -1.0f, -1.0f);  
    glVertex3f(-1.0f, -1.0f,  1.0f);  
    glVertex3f(-1.0f,  1.0f,  1.0f); 
    glVertex3f(-1.0f,  1.0f, -1.0f);  
    glEnd();

    glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
    glColor4f(0.2f,0.65f,0.3f,0.35f); 
    glBegin(GL_QUADS); 

    glNormal3f( 0.0f, 0.0f, 1.0f);    
    glVertex3f(-1.0f, -1.0f,  1.0f);  
    glVertex3f( 1.0f, -1.0f,  1.0f);  
    glVertex3f( 1.0f,  1.0f,  1.0f);  
    glVertex3f(-1.0f,  1.0f,  1.0f);  

    glNormal3f( 0.0f, 0.0f,-1.0f);   
    glVertex3f(-1.0f, -1.0f, -1.0f);  
    glVertex3f(-1.0f,  1.0f, -1.0f);  
    glVertex3f( 1.0f,  1.0f, -1.0f);  
    glVertex3f( 1.0f, -1.0f, -1.0f);  

    glNormal3f( 0.0f, 1.0f, 0.0f);    
    glVertex3f(-1.0f,  1.0f, -1.0f);  
    glVertex3f(-1.0f,  1.0f,  1.0f);  
    glVertex3f( 1.0f,  1.0f,  1.0f);  
    glVertex3f( 1.0f,  1.0f, -1.0f); 

    glNormal3f( 0.0f,-1.0f, 0.0f);    
    glVertex3f(-1.0f, -1.0f, -1.0f);  
    glVertex3f( 1.0f, -1.0f, -1.0f);  
    glVertex3f( 1.0f, -1.0f,  1.0f);  
    glVertex3f(-1.0f, -1.0f,  1.0f);  

    glNormal3f( 1.0f, 0.0f, 0.0f);    
    glVertex3f( 1.0f, -1.0f, -1.0f);  
    glVertex3f( 1.0f,  1.0f, -1.0f);  
    glVertex3f( 1.0f,  1.0f,  1.0f);  
    glVertex3f( 1.0f, -1.0f,  1.0f);  

    glNormal3f(-1.0f, 0.0f, 0.0f);   
    glVertex3f(-1.0f, -1.0f, -1.0f);  
    glVertex3f(-1.0f, -1.0f,  1.0f);  
    glVertex3f(-1.0f,  1.0f,  1.0f);  
    glVertex3f(-1.0f,  1.0f, -1.0f);  
    glEnd();

    //glPopMatrix();




    glPopAttrib();
}

void resize(int w, int h) 
{
    changeViewport(w, h);
}   

private :

void changeViewport(int w, int h) 
{
    glViewport(0, 0, w, h);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective (60.0, (float)w/(float)h, 0.1, 100.0);
}

bool m_isTextureInitialized;
unsigned int m_backgroundTextureId;
CameraCalibration m_calibration;
cv::Mat m_backgroundImage;

};

 static Renderer *renderer;

 static void glutResize(int w, int h) 
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
renderer->resize(w,h);
}

static void glutDisplay() 
{
renderer->draw();

}

GLboolean upPressed = false;
GLboolean downPressed = false;
GLboolean rightPressed = false;
GLboolean leftPressed = false;


void handleSpecialKeypress(int key, int x, int y) {

    if (GLUT_KEY_LEFT == key)
        leftPressed = true;

    if (GLUT_KEY_RIGHT == key)
        rightPressed = true;

    if (GLUT_KEY_UP == key)
        upPressed = true;

    if (GLUT_KEY_DOWN == key)
        downPressed = true;


}

void SpecialKeysUp(int key, int x, int y)
{

   if (GLUT_KEY_UP == key)
      upPressed = false;

   if (GLUT_KEY_DOWN == key)
      downPressed = false;

   if (GLUT_KEY_RIGHT == key)
      rightPressed = false;

   if (GLUT_KEY_LEFT == key)
      leftPressed = false;

}

static void idle()
{
    if(upPressed)
        renderer->y_direction += 0.05f;
    else if(downPressed)
        renderer->y_direction -= 0.05f;
    else if(rightPressed)
        renderer->x_direction -= 0.05f;
    else if(leftPressed)
        renderer->x_direction += 0.05f;
    else if(upPressed && rightPressed)
    {
        renderer->y_direction += 0.05f;
        renderer->x_direction -= 0.05f;
    }
    else if(upPressed && leftPressed)
    {
        renderer->y_direction += 0.05f;
        renderer->x_direction += 0.05f;
    }
    else if(downPressed && rightPressed)
    {
        renderer->y_direction -= 0.05f;
        renderer->x_direction -= 0.05f;
    }
    else if(downPressed && leftPressed)
    {
        renderer->y_direction -= 0.05f;
        renderer->x_direction += 0.05f;
    }

    glutPostRedisplay();
}



int main(int argc, char **argv)
{
    CameraCalibration calibration(526.58037684199849f, 524.65577209994706f, 318.41744018680112f, 202.96659047014398f);

if (argc < 3)
{
    std::cout << "Input image not specified" << std::endl;
    return 1;
}

cv::Mat patternImage = cv::imread(argv[1]);
if (patternImage.empty())
{
    std::cout << "Input image cannot be read" << std::endl;
    return 2;
}

std::string input = argv[2];
cv::Mat testImage = cv::imread(input);

glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGB);
glutInitWindowSize(testImage.cols, testImage.rows);

glutCreateWindow("Markerless AR");
GLenum err = glewInit();
if (GLEW_OK != err) {
    fprintf(stderr, "Glew error: %s\n", glewGetErrorString(err));
}

glutIgnoreKeyRepeat(1);
glutIdleFunc(idle);
glutReshapeFunc(glutResize);
glutDisplayFunc(glutDisplay);
glutSpecialFunc(handleSpecialKeypress);
glutSpecialUpFunc(SpecialKeysUp);
glEnable(GL_DEPTH_TEST);

renderer = new Renderer(calibration);

ARPipeline pipeline(patternImage, calibration);

cv::Mat img = testImage.clone();
renderer->updateBackground(img);
renderer->isPatternPresent = pipeline.processFrame(testImage);
renderer->patternPose = pipeline.getPatternLocation();

glutMainLoop();
}

1 个答案:

答案 0 :(得分:-1)

我在那里看不到任何深度功能。 glDepthFunc(GL_LESS);