OpenCV + OpenGL + Qt

dal*_*tar 8 opengl qt opencv augmented-reality qglwidget

我正在设计自己的增强现实应用程序.我已经检测到我正在使用的模式的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 */
Run Code Online (Sandbox Code Playgroud)

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();
}
Run Code Online (Sandbox Code Playgroud)

好的,所以,作为我的MainWindow的构造函数中的附加注释,我有类似的东西:

windowGL = new GLWidget();
windowGL.setParent(this);
Run Code Online (Sandbox Code Playgroud)

为了将GL窗口放在MainWindow中.我还在GLViewer.h中创建了一个名为的新变量:

double modelViewMatrix[16] = {0.0};
Run Code Online (Sandbox Code Playgroud)

因此,为了显示3D对象,我在GLViewer中创建了一个方法,如下所示:

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

在那之后,我在使用glDrawPixels()绘制图像之后将这样的东西放入GLViewer :: paintGL()方法中,显然是在弹出矩阵之后:

    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();
Run Code Online (Sandbox Code Playgroud)

因此,对于modelViewMatrix,我考虑到我必须按顺序排列或排序,或转置,无论你想要什么...所以,当然,作为最后一步我调用创建函数GLWidget :: setModelView之后我将相机内在和外在转换为数组:

windowGL.setModelView(convertedFromIntrExtr);
Run Code Online (Sandbox Code Playgroud)

然而,我什么都没看到......我已经尝试了一个代码,我得到的工作绘制轴但没有投影矩阵...但是,当我使用glutPerspective()(显然在glMatrixMode(GL_PROJECTION)之后)我可以看不到任何东西......所以,我不知道是否有人在Qt中有一个使用增强现实而没有使用ARToolkit的工作代码,因为正如我所说,我得到了我自己的外在摄像头参数......所以,如果有人有一个工作代码,你可以在其中获得外部相机参数并将它们转换为openGL投影和模型视图矩阵......嗯,这将是非常有帮助的...这是因为我找到了这个例子:

http://old.uvr.gist.ac.kr/wlee/web/techReports/ar/Camera%20Models.html
Run Code Online (Sandbox Code Playgroud)

我按照所有步骤实现了两个相机型号之间的转换,但没有成功...如果有人有工作代码我真的很感激...谢谢!

dam*_*ian 2

我曾在The Artvertiser上使用 CV 进行自我姿势估计,这个东西可以让你头脑清醒。

首先,您需要弄清楚为什么看不到任何东西。这可能有多种原因,最有可能的是相机观看方向的反转(用手习惯混乱),因此几何图形实际上位于 OpenGL 空间中相机的“后面”。但我要尝试的第一个调试是:

  • 通过在 x 和 z 维度上以 0.1f 的步长从 -1 到 1 循环绘制地面网格,绘制 glLines 来定义 y 平面的一部分(假设 y=上/下的右手坐标系:x 是右,y 是向上,z 指向屏幕外的您)(这样您可以感受到世界的规模以及相机矩阵为您提供的方向)
  • 相机“后面”的几何图形(捕捉按键来前后移动相机,然后稍微移动一下,看看是否可以找到几何图形)
  • 几何比例太大/太小(设置相机后立即使用 glScalef 捕捉按键来调整全局比例)
  • 剪裁平面之外的几何体(调整剪裁平面)

另外:这看起来有点可疑:this->modelViewMatrix[i] = cameraMatrix[i];您首先尝试过反转cameraMatrix吗?