OpenCV + OpenGL + Qt - PullRequest
       44

OpenCV + OpenGL + Qt

8 голосов
/ 29 мая 2011

Я создаю свое собственное приложение с дополненной реальностью. Я уже обнаружил 4 угла для шаблонов, с которыми я работаю. После определения 4 углов в правильном порядке я передаю их в cvFindExtrinsicCameraParams2. Я получаю хорошие результаты для поворота и перемещения объекта относительно кадра камеры. Теперь я должен поместить эту информацию (Вектор вращения и Вектор перевода) в OpenGL, чтобы что-то нарисовать. Естественно, я использую cvRodrigues2, чтобы получить матрицу вращения из вектора вращения. В дополнение к этому я наблюдаю камеру с QGlWidget таким образом:

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

Итак, в качестве дополнительной заметки в конструкторе моего главного окна у меня есть что-то вроде:

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

Чтобы поместить окно GL внутри MainWindow. Также я создал новую переменную внутри GLViewer.h с именем:

double modelViewMatrix[16] = {0.0};

Итак, для отображения 3D-объекта я создал метод внутри GLViewer, например:

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

После этого я помещаю в метод GLViewer :: paintGL () что-то вроде этого после рисования изображения с помощью glDrawPixels () и, очевидно, после выталкивания матриц:

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

Итак, для modelViewMatrix я учитываю, что мне нужно упорядочивать столбцы вместо строк или транспонировать все, что вы хотите ... Итак, естественно, в качестве последнего шага я вызываю созданную функцию GLWidget :: setModelView после того, как преобразовал внутреннюю и внешнюю камеры в массив:

windowGL.setModelView(convertedFromIntrExtr);

Однако я ничего не вижу ... Я попробовал код, и я получаю этот рабочий рисование осей, но без матрицы проекции ... Однако, когда я использую glutPerspective () (очевидно, после glMatrixMode (GL_PROJECTION)) Я просто ничего не вижу ... так что, я не знаю, есть ли у кого-то работающий код в Qt с дополненной реальностью без использования ARToolkit, потому что, как я уже сказал, я получаю внешние параметры камеры для себя ... Итак, если у кого-то есть рабочий код, в котором вы получаете внешние параметры камеры и переводите их в матрицы проекции openGL и матрицы просмотра модели ... хм, хорошо, было бы очень полезно ... это потому, что я нашел этот пример:

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

Я выполнил все шаги, чтобы добиться этого преобразования между двумя моделями камер без успеха ... Буду очень признателен, если у кого-то есть рабочий код ... спасибо !!!

1 Ответ

2 голосов
/ 10 июня 2011

Я работал с CV для оценки позы эго на Artvertiser , и этот материал может вам помочь.

Сначала вам нужно выяснить, почему вы можете 'ничего не вижу.Это может быть по ряду причин, наиболее вероятной из которых является инверсия направления взгляда камеры (путаница в руках), поэтому геометрия фактически находится «позади» камеры в пространстве OpenGL.Но первой попыткой отладки было бы следующее:

  • нарисовать сетку заземления, выполнив цикл от -1 до 1 с шагом 0,1f в измерениях x и z, нарисовав glLines для определения частиплоскость y (при условии, что правая система координат с y = вверх / вниз: x вправо, y вверх, z указывает на вас вне экрана) (таким образом вы можете почувствовать масштаб мира иориентация, которую задает матрица вашей камеры)
  • геометрия "позади" камеры (ловите нажатия клавиш, чтобы перемещать камеру назад и вперед, немного перемещайтесь и посмотрите, сможете ли вы найтигеометрия)
  • геометрический масштаб слишком большой / слишком маленький (ловить нажатия клавиш для настройки глобального масштаба с помощью glScalef сразу после настройки камеры)
  • геометрия внеплоскость отсечения (отрегулируйте плоскость отсечения)

Также: это выглядит немного подозрительно: this->modelViewMatrix[i] = cameraMatrix[i]; Вы пытались сначала инвертировать cameraMatrix?

...