2011-05-29 12 views
8

Projektuję własną aplikację rozszerzonej rzeczywistości. Już wykryłem 4 rogi dla wzorów, z którymi pracuję. Po wykryciu 4 rogów we właściwej kolejności przekazuję je do cvFindExtrinsicCameraParams2. Otrzymuję dobre wyniki dla obrotu i translacji obiektu w odniesieniu do ramy kamery. Teraz muszę umieścić te informacje (wektor obrotu i wektor translacji) w OpenGL, aby narysować coś. Naturalnie używam cvRodrigues2, aby uzyskać macierz obrotu z wektora obrotu. Poza tym patrzę aparat z QGlWidget w ten sposób: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, tak, jak dodatkowa uwaga w konstruktorze mojego MainWindow Mam coś takiego:

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

Aby umieścić okno GL w MainWindow. Także stworzyłem nową zmienną wewnątrz GLViewer.h nazwie:

double modelViewMatrix[16] = {0.0}; 

Tak więc, w celu wyświetlenia obiektu 3D I stworzył metodę wewnątrz GLViewer tak:

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

po tym, jestem oddanie do GLViewer :: paintGL() metoda czymś takim po pobraniu obrazu z glDrawPixels() i oczywiście po popping matryc:

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

Więc dla modelViewMatrix biorę pod uwagę, że trzeba zamawiać w kolumnach zamiast wierszy lub transponować, cokolwiek chcesz ... Tak więc, oczywiście, jako ostatni krok wywołuję utworzoną funkcję GLWidget :: setModelView po przekonwertowaniu kamery wewnętrznej i zewnętrznej do tablicy:

windowGL.setModelView(convertedFromIntrExtr); 

jednak widzę nic ... próbowałem kod i otrzymuję, że praca rysunek osie ale bez macierzy projekcji ... jednak kiedy używam glutPerspective() (oczywiście po glMatrixMode (GL_PROJECTION)) Po prostu nic nie widzę ... więc nie wiem, czy ktoś ma działający kod w Qt z rozszerzoną rzeczywistością bez użycia ARToolkita, ponieważ, jak powiedziałem, dostaję zewnętrzną kamerę parametry dla mojej własnej ... Tak więc, jeśli ktoś ma działający kod, w którym otrzymujesz zewnętrzne parametry kamery i tra nslate je w OpenGL projekcyjnych i ModelView matryc ... hmm dobrze, byłoby bardzo pomocne ... to dlatego, że uważam, że ten przykład:

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

Śledziłem wszelkie kroki w celu osiągnięcia tego konwersję między modelami 2 aparatu bez sukces ... Naprawdę doceniam, jeśli ktoś ma działający kod ... dzięki !!!

+0

Nie należy używać glDrawPixels, ponieważ zazwyczaj jest niezgrabnie wolny. Zamiast tego powinieneś renderować teksturowany obiekt, z obrazem będącym teksturą. Zobacz http://www.opengl.org/resources/faq/technical/performance.htm. Upewnij się, aby wyłączyć bufor głębi (lub wyczyścić później) podczas rysowania tła. – ypnos

+0

Tak, próbowałem tego, w rzeczywistości dostaję dobre wyniki z teksturą też ... jednak rzecz jest: mam macierz obrotu (która jest ładna) i wektor translacji (który jest nieskalowany), ponieważ openGL wydaje się akceptować tylko wartości GL_MODELVIEW dla pozycji kamery między -1 a 1 ... Mam na myśli, że openGL bierze dla osi X -1 jako lewa strona i +1 dla prawej strony ... dla osi Y pobiera - 1 dla dołu i +1 dla góry ... Tak więc, jeśli ktoś wie, jak to skalować, ponieważ nie wiem, – daleotar

+0

'glMatrixMode (GL_TEXTURE);' może być jedną z dróg, lub jak deklarujesz swoje współrzędne tekstury mogą być inne. To znaczy, przekształć swoje współrzędne ręcznie, a następnie popchnij przekształcone współrzędne. – EnabrenTane

Odpowiedz

2

Pracowałem z CV na ego-pose oszacowanie na The Artvertiser, a to rzeczy można zrobić swoją głowę.

Po pierwsze, trzeba dowiedzieć się, dlaczego nie widać nic.Może to wynikać z wielu powodów, najprawdopodobniej będących odwróceniem kierunku patrzenia kamery (zamieszanie z handedness), więc geometria jest rzeczywiście "za" kamerą w przestrzeni OpenGL. Jednak pierwsze debugowania rzeczy ja próbują to:

  • zwrócić siatkę ziemi za pomocą pętli od -1 do 1 w etapach 0.1f w wymiarach x i z, rysunek glLines zdefiniować części płaszczyzny y (zakładając prawostronny układ współrzędnych z y = góra/dół: x ma rację, y jest w górę, z wskazuje na ciebie z ekranu) (w ten sposób można wyczuć skalę świata i orientację kamery matryca daje ci)
  • geometrii „za” z aparatem (znakom połowów, aby przesunąć kamerę w tył iw przód, i poruszać się trochę i zobaczyć, czy można znaleźć geometrię)
  • skala geometria zbyt duże/za małe (naciśnięcie klawisza połowowe dostosować globalną skalę przy użyciu glScalef tuż po skonfigurowaniu aparatu)
  • geometrii poza płaszczyzną obcinania (ustawić płaszczyznę obcinania)

Ponadto: wygląda to trochę podejrzanie: this->modelViewMatrix[i] = cameraMatrix[i]; Czy próbowałeś najpierw odwrócić kameręMatrix?

+0

Nie, myślę, że mam to, po prostu zakładam, że oś Z kamery jest negatywna, ale pozytywna ... – daleotar