2011-05-29 22 views
8

Estoy diseñando mi propia aplicación de realidad aumentada. Ya he detectado las 4 esquinas para los patrones con los que estoy trabajando. Después de detectar las 4 esquinas en el orden correcto, las paso a cvFindExtrinsicCameraParams2. Obtuve buenos resultados para la rotación y la traducción del objeto con respecto al marco de la cámara. Ahora tengo que poner esa información (Vector de rotación y Vector de traducción) en OpenGL para dibujar algo. Naturalmente, estoy usando cvRodrigues2 para obtener la matriz de rotación del vector de rotación. Además de esto estoy viendo la cámara con QGlWidget de esta manera:OpenCV + OpenGL + Qt

GLWidget.h

#ifndef _GLWIDGET_H 
#define _GLWIDGET_H 

#include <QtOpenGL/QGLWidget> 
#include <cv.h> 
#include <cxcore.h> 

class GLWidget : public QGLWidget { 

    Q_OBJECT // must include this if you use Qt signals/slots 

public: 
    GLWidget(QWidget *parent = NULL); 
    IplImage *img; 
    void setImage(IplImage *imagen); 
protected: 
    void initializeGL(); 
    void resizeGL(int w, int h); 
    void paintGL(); 
}; 

#endif /* _GLWIDGET_H */ 

GLWidget.cpp

#include <QtGui/QMouseEvent> 
#include "GLWidget.h" 

GLWidget::GLWidget(QWidget *parent) : QGLWidget(parent) { 
    this->img = 0; 
} 

void GLWidget::initializeGL() { 
    glDisable(GL_TEXTURE_2D); 
    glDisable(GL_DEPTH_TEST); 
    glDisable(GL_COLOR_MATERIAL); 
    glEnable(GL_BLEND); 
    glEnable(GL_POLYGON_SMOOTH); 
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 
    glClearColor(0, 0, 0, 0); 
} 

void GLWidget::resizeGL(int w, int h) { 
    glViewport(0, 0, w, h); 
    glMatrixMode(GL_PROJECTION); 
    glLoadIdentity(); 
    gluOrtho2D(0, w, 0, h); // set origin to bottom left corner 
// gluPerspective(52.0f, 1.3333f, 0.1f, 100.0f); 
    glMatrixMode(GL_MODELVIEW); 
    glLoadIdentity(); 

} 

void GLWidget::paintGL() { 

    if(this->img) 
    { 
     glClear (GL_COLOR_BUFFER_BIT); 
     glClearColor(0.0,0.0,0.0,1.0); 
     glMatrixMode(GL_PROJECTION); 
     glPushMatrix(); 
     glLoadIdentity(); 
     gluOrtho2D(0.0,img->width, 0.0, img->width); 
     glMatrixMode(GL_MODELVIEW); 
     glPushMatrix(); 
     glLoadIdentity(); 
     glDrawPixels(img->width,img->height,GL_RGB,GL_UNSIGNED_BYTE,img->imageData); 
     glMatrixMode(GL_PROJECTION); 
     glPopMatrix(); 
     glMatrixMode(GL_MODELVIEW); 
     glPopMatrix(); 
    } 
} 
void GLWidget::setImage(IplImage *imagen) 
{ 
    this->img = imagen; 
    this->updateGL(); 
} 

Ok, por lo que, como se una nota adicional en el constructor de mi MainWindow tengo algo así como:

windowGL = new GLWidget(); 
windowGL.setParent(this); 

Para colocar la ventana GL dentro de la ventana principal. También he creado una nueva variable dentro GLViewer.h llamada:

double modelViewMatrix[16] = {0.0}; 

Por lo tanto, con el fin de mostrar un objeto en 3D que he creado un método en el interior GLViewer así:

void GlViewer::setModelView(double cameraMatrix[]){ 
    for(int i=0;i<16;i++){ 
    this->modelViewMatrix[i] = cameraMatrix[i]; 
    } 
    this->updateGL(); 
} 

Después de eso, estoy puesta en GLViewer :: paintGL() de algo como esto después de dibujar la imagen con glDrawPixels() y, obviamente, después de matrices que hacen estallar:

glMatrixMode(GL_MODELVIEW); 
    glLoadMatrixd(this->modelViewMatrix); 
    glPushMatrix(); 
    glColor3f(1,0,0); 

    glPushAttrib(GL_COLOR_BUFFER_BIT | GL_POLYGON_BIT | GL_ENABLE_BIT) ; 
    glDisable(GL_LIGHTING) ; 
    glPolygonMode(GL_FRONT_AND_BACK, GL_LINE) ; 
    glLineWidth(3); 

    glBegin(GL_LINES) ; 
      glColor3f(1,0,0) ; 
      glVertex3f(0,0,0) ; 
      glVertex3f(100,0,0); 

      glColor3f(0,1,0) ; 
      glVertex3f(0,0,0) ; 
      glVertex3f(0,100,0); 

      glColor3f(0,0,1) ; 
      glVertex3f(0,0,0) ; 
      glVertex3f(0,0,100); 
    glEnd() ; 

    glLineWidth(1) ; 
    glPopAttrib() ; 
    glMatrixMode(GL_MODELVIEW); 
    glPopMatrix(); 

Así, por modelViewMatrix que estoy teniendo en cuenta que yo tiene que ordenar en columnas en lugar de filas, o transponer, lo que quiera ... Así que, como último paso, llamo a la función creada GLWidget :: setModelView después de convertir la cámara intrínseca y extrínseca en una matriz:

windowGL.setModelView(convertedFromIntrExtr); 

sin embargo estoy viendo nada ... he intentado un código y me sale que el trabajo de los ejes de dibujo pero sin la matriz de proyección ... sin embargo, cuando uso glutPerspective() (obviamente después glMatrixMode (GL_PROJECTION)) Simplemente no puedo ver nada ... así que no sé si alguien tiene un código de trabajo en Qt con realidad aumentada sin usar ARToolkit porque, como dije, estoy recibiendo la cámara extrínseca parámetros para mí ... Entonces, si alguien tiene un código de trabajo en el que se obtienen los parámetros de la cámara extrínseca y tra nslate ellos en OpenGL de proyección y matrices modelview ... hmm así, sería muy útil ... esto es porque me encontré con este ejemplo:

http://old.uvr.gist.ac.kr/wlee/web/techReports/ar/Camera%20Models.html 

He seguido todos los pasos para lograr que la conversión entre los modelos de cámara 2 sin éxito ... Realmente agradeceré si alguien tiene un código de trabajo ... ¡¡¡gracias !!!

+0

No debe usar glDrawPixels ya que normalmente es torpemente lento. En su lugar, debe representar un objeto texturizado, con su imagen como la textura. Ver http://www.opengl.org/resources/faq/technical/performance.htm. Asegúrese de desactivar el búfer de profundidad (o borrar después) al dibujar el fondo. – ypnos

+0

Sí, lo he intentado, de hecho estoy obteniendo buenos resultados con la textura también ... sin embargo, el problema es que tengo una matriz de rotación (lo cual es bueno) y un vector de traducción (sin escala) porque openGL parece aceptar solo valores de GL_MODELVIEW para la posición de la cámara entre -1 y 1 ... Quiero decir, OpenGL está tomando para el eje X -1 como el lado izquierdo y +1 para el lado derecho ... para el eje Y está tomando - 1 para abajo y +1 para arriba ... Así que el asunto es si alguien sabe cómo escalar eso porque no sé – daleotar

+0

'glMatrixMode (GL_TEXTURE);' podría ser una avenida, o cómo se declaran las coordenadas de su textura. otro. Es decir, transforma tus coordenadas a mano, luego empuja las coordenadas transformadas. – EnabrenTane

Respuesta

2

He trabajado con CV para el ego-pose estimación de The Artvertiser, y esto puede hacer que su cabeza.

En primer lugar, es necesario averiguar por qué no se puede ver nada.Podría ser por una serie de razones, la más probable es una inversión de la dirección de observación de la cámara (confusión de destreza), por lo que la geometría está realmente "detrás" de la cámara en el espacio OpenGL. Pero las primeras cosas depuración me gustaría probar serían:

  • dibujar una rejilla de tierra por bucle de -1 a 1 en los pasos de 0.1f en X y Z dimensiones, dibujo glLines para definir una parte de la Y plano (asumiendo el sistema de coordenadas a la derecha con y = arriba/abajo: x está a la derecha, y está arriba, z apunta hacia fuera de la pantalla) (de esta manera puede hacerse una idea de la escala del mundo y la orientación de su cámara matriz de usted) está dando
  • geometría 'detrás' de la cámara (pulsaciones de teclas de captura para mover la cámara hacia atrás y adelante, y moverse un poco y ver si puede encontrar la geometría)
  • escala de la geometría demasiado grande/demasiado pequeñas (pulsaciones de teclas de captura para ajustar a escala mundial utilizando glScalef justo después de la creación de la cámara)
  • geometría fuera del plano de delimitación (ajustar el plano de delimitación)

Además: esto parece un poco sospechoso: this->modelViewMatrix[i] = cameraMatrix[i]; ¿Has intentado invertir primero la cámaraMatriz?

+0

No, creo que lo tengo, es solo que estaba suponiendo que el eje Z de la cámara es negativo pero positivo ... – daleotar

Cuestiones relacionadas