2011-05-29 106 views
8

我正在设计自己的增强现实应用程序。 我已经检测到我正在使用的模式的4个角。按照正确的顺序检测到四个角后,我将它们传递给cvFindExtrinsicCameraParams2。 我得到了很好的结果,旋转和对象相对于相机框架的平移。 现在我必须将这些信息(旋转矢量和转换矢量)放到OpenGL中来绘制一些东西。自然,我使用cvRodrigues2从旋转矢量中获取旋转矩阵。 除了这个我看使用QGLWidget来相机这样: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(); 
} 

好了,所以,如在我的MainWindow的构造函数中有一个额外的注释我有类似的东西:

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

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

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

我跟所有的步骤来实现,而不2种相机型号之间的转换成功... 如果有人有工作代码,我会很感激......谢谢!

+0

你不应该使用glDrawPixels,因为它通常是非常慢的。相反,你应该渲染一个纹理对象,你的图像就是纹理。请参阅http://www.opengl.org/resources/faq/technical/performance.htm。确保在绘制背景时禁用深度缓冲区(或之后清除)。 – ypnos 2011-05-29 18:17:29

+0

是的,我试过了,实际上我用纹理也得到了很好的结果...但是,事情是:我有一个旋转矩阵(这是很好的)和一个平移矢量(它是未缩放的),因为openGL似乎只接受GL_MODELVIEW值为-1和1之间的摄像头位置......我的意思是,openGL取X轴-1作为左侧,+1作为右侧...对于Y轴正在采取 - 1为底部,+1为顶部...所以问题是如果有人知道如何缩放,因为我不知道 – daleotar 2011-05-29 22:54:24

+0

'glMatrixMode(GL_TEXTURE);'可能是一条途径,或者你如何声明你的纹理坐标可能是另一个。也就是说,手动变换坐标,然后推动变换后的坐标。 – EnabrenTane 2011-06-01 06:17:53

回答

2

我和CV工作了自我姿态估计上The Artvertiser,这东西可以做你的头。

首先,你需要弄清楚为什么你看不到任何东西。这可能是由于很多原因,最可能的是相机观看方向的反转(手型混乱),所以在OpenGL空间中几何实际上是在相机后面。但第一调试事我会尝试将是:

  • 由从-1到1在x和z维度0.1F的步骤循环绘制一个接地网,拉丝glLines来定义y平面的一部分(假设右坐标系y =向上/向下:x是正确的,y是向上的,z指向你离开屏幕)(这样你就可以感觉到世界的规模和你的相机的方向矩阵是给你)
  • 几何“背后”相机(抓按键向后和向前移动相机,和周围有点动,看你是否能找到几何)
  • 几何尺度太大/太小剪辑平面之外
  • 几何(捕获按键来设置相机后右调整使用glScalef全球范围)(调整裁剪平面)

另外:这看起来有点怀疑:this->modelViewMatrix[i] = cameraMatrix[i];你有没有尝试颠倒cameraMatrix第一?

+0

不,我想我知道了,只是我假设相机的Z轴负面但是正面... – daleotar 2011-06-19 20:30:10