OpenCV + OpenGL + Qt
我正在设计自己的增强现实应用程序。 我已经检测到我正在使用的图案的 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();
}
之后,我在绘制后将其放入 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
我按照所有步骤实现了 2 个相机模型之间的转换,但没有成功... 如果有人有有效的代码,我将非常感激...谢谢!!!
I'm designing my own augmented reality application.
I have already detected the 4 corners for the patterns I'm working with. After detecting the 4 corners in a proper order I'm passing them into cvFindExtrinsicCameraParams2.
I'm getting nice results for the rotation and translation of the object respect to the camera frame.
Now I have to put that information (Rotation Vector and Translation Vector) into OpenGL to draw something. Naturally, I'm using cvRodrigues2 to get the rotation matrix from rotation vector.
In addition to this I'm watching the camera with QGlWidget in this way:
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, so, as an additional note in the constructor of my MainWindow I have something like:
windowGL = new GLWidget();
windowGL.setParent(this);
In order to put the GL window inside the MainWindow. Also I created a new variable inside GLViewer.h called :
double modelViewMatrix[16] = {0.0};
So, in order to display a 3D object I created a method inside GLViewer like this:
void GlViewer::setModelView(double cameraMatrix[]){
for(int i=0;i<16;i++){
this->modelViewMatrix[i] = cameraMatrix[i];
}
this->updateGL();
}
After that, I'm putting into GLViewer::paintGL() method something like this after drawing the image with glDrawPixels() and obviously after popping matrices:
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();
So, for modelViewMatrix I'm taking into account that I have to order into columns instead of rows, or transpose, whatever you want...
So, naturally, as the last step I'm calling the created function GLWidget::setModelView after I converted the camera intrinsic and extrinsic into an array:
windowGL.setModelView(convertedFromIntrExtr);
However I'm seeing nothing... I've tried a code and I get that working drawing the axes but without the projection matrix... However, when I use glutPerspective() (obviously after glMatrixMode(GL_PROJECTION)) I just can't see anything... so, I don't know if someone out there has a working code in Qt with augmented reality without using ARToolkit because, as I said, I'm getting the extrinsic camera parameters for my own... So, If anyone has a working code in which you get the extrinsic camera parameters and translate them into openGL projection and modelview matrices... hmm well, would be very helpful... this is because I found this example:
http://old.uvr.gist.ac.kr/wlee/web/techReports/ar/Camera%20Models.html
I followed all steps to achieve that conversion between the 2 camera models without success...
I'll really appreciate if someone has a working code... thanks!!!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我曾在 The Artvertiser 上使用 CV 进行自我姿势估计,这个东西可以让你头脑清醒。
首先,你需要弄清楚为什么你看不到任何东西。这可能有多种原因,最有可能的是相机观看方向的反转(用手习惯混乱),因此几何图形实际上位于 OpenGL 空间中相机的“后面”。但我要尝试的第一个调试方法是:
另外:这看起来有点可疑:
this->modelViewMatrix[i] =cameraMatrix[i];
您是否先尝试过反转cameraMatrix?I've worked with CV for ego-pose estimation on The Artvertiser, and this stuff can do your head in.
First, you need to figure out why you can't see anything. It could be for a number of reasons, the most likely being an inversion of the camera look-at direction (handedness confusion), so the geometry is actually 'behind' the camera in OpenGL space. But the first debugging things I would try would be:
Also: this looks a bit suspect:
this->modelViewMatrix[i] = cameraMatrix[i];
Have you tried inverting cameraMatrix first?