2011-05-29 4 views
8

Je suis en train de concevoir ma propre application de réalité augmentée. J'ai déjà détecté les 4 coins pour les motifs avec lesquels je travaille. Après avoir détecté les 4 coins dans un ordre approprié, je les passe dans cvFindExtrinsicCameraParams2. J'obtiens de bons résultats pour la rotation et la translation de l'objet par rapport au cadre de la caméra. Maintenant, je dois mettre cette information (vecteur de rotation et vecteur de traduction) dans OpenGL pour dessiner quelque chose. Naturellement, j'utilise cvRodrigues2 pour obtenir la matrice de rotation à partir du vecteur de rotation. En plus de cela je regarde la caméra avec QGLWidget de cette façon: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, donc, comme une note supplémentaire dans le constructeur de ma MainWindow j'ai quelque chose comme:

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

Afin de mettre la fenêtre GL à l'intérieur de la MainWindow. Aussi j'ai créé une nouvelle variable à l'intérieur GLViewer.h appelé:

double modelViewMatrix[16] = {0.0}; 

Ainsi, afin d'afficher un objet 3D j'ai créé une méthode à l'intérieur GLViewer comme ceci:

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

Après cela, je suis la mise en GLViewer :: méthode paintGL() de quelque chose comme ça après avoir dessiné l'image avec glDrawPixels() et, évidemment, après matrices popping:

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(); 

Alors, pour modelViewMatrix je prends en compte que je J'ai donc besoin de commander en colonnes au lieu de lignes, ou de transposer, ce que vous voulez ... Donc, naturellement, comme dernière étape j'appelle la fonction créée GLWidget :: setModelView après avoir converti la caméra intrinsèque et extrinsèque en un tableau:

windowGL.setModelView(convertedFromIntrExtr); 

Cependant, je vois rien ... J'ai essayé un code et je reçois qui épure les axes, mais sans la matrice de projection ... Cependant, quand je l'utilise glutPerspective() (évidemment après glMatrixMode (GL_PROJECTION)) Je ne vois rien ... donc, je ne sais pas si quelqu'un a un code de travail en Qt avec la réalité augmentée sans utiliser ARToolkit parce que, comme je l'ai dit, je reçois la caméra extrinsèque paramètres pour mon propre ... Donc, si quelqu'un a un code de travail dans lequel vous obtenez les paramètres de la caméra extrins les nslate en projection et matrices openGL MODELVIEW ... hmm bien, serait très utile ... c'est parce que je trouve cet exemple:

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

J'ai suivi toutes les étapes pour réaliser la conversion entre les 2 modèles de caméra sans succès ... J'apprécierai vraiment si quelqu'un a un code de travail ... merci !!!

+0

Vous ne devriez pas utiliser glDrawPixels car il est généralement lent. Au lieu de cela, vous devriez rendre un objet texturé, avec votre image étant la texture. Voir http://www.opengl.org/resources/faq/technical/performance.htm. Assurez-vous de désactiver le tampon de profondeur (ou d'effacer après) lors du dessin de l'arrière-plan. – ypnos

+0

ouais, j'ai essayé ça, en fait j'obtiens de bons résultats avec la texture aussi ... mais la chose est: j'ai une matrice de rotation (qui est sympa) et un vecteur de traduction (qui est non scalable) car openGL semble accepter seulement pour les valeurs GL_MODELVIEW pour la position de la caméra entre -1 et 1 ... Je veux dire, openGL prend pour axe X -1 comme le côté gauche et +1 pour le côté droit ... pour l'axe Y prend - 1 pour le bas et +1 pour le haut ... Donc, le problème est de savoir si quelqu'un sait comment le mettre à l'échelle parce que je ne sais pas – daleotar

+0

'glMatrixMode (GL_TEXTURE);' pourrait être une avenue, ou comment vous déclarez vos coordonnées de texture pourraient être un autre. C'est-à-dire, transformez vos coordonnées à la main, puis appuyez sur le coord transformé. – EnabrenTane

Répondre

2

J'ai travaillé avec CV ego-estimation de la pose sur The Artvertiser, et ce genre de choses peut faire votre tête.

D'abord, vous devez comprendre pourquoi vous ne pouvez pas voir quoi que ce soit.Il pourrait s'agir d'un certain nombre de raisons, la plus probable étant une inversion de la direction de regard de la caméra (confusion de la rectitude), de sorte que la géométrie est en réalité «derrière» la caméra dans l'espace OpenGL. Mais les premières choses de débogage je voudrais essayer serait:

  • dessiner une grille au sol par une boucle de -1 à 1, aux étapes de 0.1f dans les dimensions x et z, le dessin glLines pour définir une partie du plan de y (en supposant que le système de coordonnées est à droite avec y = haut/bas: x est à droite, y est levé, z pointe vers vous hors de l'écran) (de cette façon vous pouvez avoir une idée de l'échelle du monde et de l'orientation de votre caméra matrice vous donne)
  • géométrie « derrière » la caméra (prises de pressions sur les touches pour déplacer la caméra vers l'arrière et vers l'avant, et de se déplacer un peu et voir si vous pouvez trouver la géométrie)
  • échelle de la géométrie trop grands/trop petits (pressions sur les touches de prises pour ajuster l'échelle mondiale en utilisant glScalef juste après la mise en place de l'appareil photo)
  • géométrie
  • en dehors du plan de coupe (régler le plan de coupe)

Aussi: cela semble un peu suspect: this->modelViewMatrix[i] = cameraMatrix[i]; Avez-vous essayé d'inverser cameraMatrix en premier?

+0

Non, je pense que je l'ai compris, c'est juste que je supposais que l'axe Z de la caméra était négatif mais positif ... – daleotar