【发布时间】:2023-03-08 14:54:01
【问题描述】:
我正在设计自己的增强现实应用程序。 我已经检测到我正在使用的模式的 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();
}
好的,所以,作为 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();
}
在那之后,我在用 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();
所以,对于 modelViewMatrix,我考虑到我必须按列而不是行排序,或者转置,无论你想要什么...... 所以,很自然,作为最后一步,我在将相机内部和外部转换为数组后调用创建的函数 GLWidget::setModelView:
windowGL.setModelView(convertedFromIntrExtr);
但是我什么也没看到...我尝试了一个代码,并且可以绘制轴但没有投影矩阵...但是,当我使用 glutPerspective() 时(显然是在 glMatrixMode(GL_PROJECTION) 之后)我只是什么都看不到......所以,我不知道是否有人在不使用 ARToolkit 的情况下在 Qt 中具有增强现实的工作代码,因为正如我所说,我正在为我自己获取外部相机参数...所以,如果有人有一个工作代码,您可以在其中获取外部相机参数并将它们转换为 openGL 投影和模型视图矩阵......嗯,这将非常有帮助......这是因为我找到了这个例子:
http://old.uvr.gist.ac.kr/wlee/web/techReports/ar/Camera%20Models.html
我按照所有步骤在 2 个相机型号之间实现了转换,但没有成功... 如果有人有工作代码,我将不胜感激......谢谢!!!
【问题讨论】:
-
您不应该使用 glDrawPixels,因为它通常慢得令人尴尬。相反,您应该渲染一个带纹理的对象,您的图像是纹理。见opengl.org/resources/faq/technical/performance.htm。确保在绘制背景时禁用深度缓冲区(或之后清除)。
-
是的,我试过了,事实上我在纹理上也得到了很好的结果......但问题是:我有一个旋转矩阵(这很好)和一个平移向量(未缩放)因为openGL似乎只接受-1和1之间相机位置的GL_MODELVIEW值......我的意思是,openGL将X轴-1作为左侧,+1作为右侧...... . 对于 Y 轴,底部为 -1,顶部为 +1 ......所以问题是如果有人知道如何缩放它,因为我不知道
-
glMatrixMode(GL_TEXTURE);可能是一种途径,或者您声明纹理坐标的方式可能是另一种途径。也就是手动变换你的坐标,然后推变换后的坐标。
标签: qt opengl opencv augmented-reality qglwidget