QT集成IntelRealSense双目摄像头2,集成OpenGL

上一篇文章写了如何把IntelRealSense摄像头的SDK集成到QT项目,并成功采集数据,在没有用OpenCV的情况下完成色彩数据,以及深度数据的显示。

具体地址:https://blog.csdn.net/qujia121qu/article/details/144734163

本次主要写如何把深度数据和色彩数据,融合显示为3D数据。既然要显示为3D数据,那么肯定是要用OpenGL。所以第一步,就是要项目引入opengl。

第一步:引入OpenGL。

引入OpenGL需要QT+=opengl,然后加载opengl的lib和glu的lib文件。代码如下。引入成功以后,#include <GL/gl.h>不会报错。

复制代码
win32:LIBS += -lOpengl32\
-lglu32
unix:LIBS += -lglut -lGLU

第二步:创建一个用于显示3D图像的Widget

因为要显示3D,所以这个Widget要继承自QGLWidget或者QOpenGLWidget。这两个差不多。头文件和CPP见下面代码,这个是最基本的一个QGLWidget框架,适合绘制平面图形,建议收藏。

cpp 复制代码
#include <QObject>
#include <QGLWidget>
#include <GL/gl.h>
#include <GL/glu.h>
class GLWidget : public QGLWidget
{
    Q_OBJECT
public:
    GLWidget();
    static GLWidget* getInstance();          //单例模式
protected:
    void resizeGL(int w, int h) override;   //窗口大小改变的时候,gl重新初始化
    void initializeGL() override;           //初始化gl
    void paintGL() override;                //核心绘制
};

#endif // GLWIGET_H
cpp 复制代码
#include "glwidget.h"

GLWidget::GLWidget()
{

}

/**
 * @brief GLWidget::getInstance 单例模式
 * @return
 */
GLWidget* GLWidget::getInstance(){
    GLWidget* ins=NULL;
    if(ins==NULL)ins=new GLWidget();
    return ins;
}
/**
 * @brief GLWidget::initializeGL 初始化opengl。可以步写
 */
void GLWidget::initializeGL(){

}
/**
 * @brief GLWidget::resizeGL 窗口大小改变
 * @param w
 * @param h
 */
void GLWidget::resizeGL(int w, int h){
    glViewport(0,0,w,h);            //重新适应窗口大小

}
/**
 * @brief GLWidget::paintGL 绘制核心方法
 */
void GLWidget::paintGL(){
    glClearColor(0,0,0,0);                       //背景色
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);//清除上一次的缓存
    glLoadIdentity();  //加载单位矩阵
    glColor3f (1, 0, 1.0); //画笔颜色
    glRectf(-0.5, -0.5, 0.5, 0.5); // 绘制一个边长为1的矩形
}

以上代码绘制出来一个矩形,如下图。opengl窗口的宽高都是1,所以0.5,就是宽高的一半。

目前只是加载了opengl,但是绘制是依然是平面图形。要绘制3D图像,就需要设置投影矩阵,以及相机。大致的意思,就是设置相机焦距,远距离,近距离,视角,相机位置等。主要是两个函数

复制代码
gluPerspective(视角角度,长宽比,近距离,远距离)
gluLookAt(相机x,相机y,相机z,        目标x,目标y,目标z,   相机方向x,相机方向y,相机方向z)

第三步:设置相机和投影矩阵

如下,就是在resizeGL里面增加了几行代码,这个设置完,就不用改了。在paintGL里面增加了一个gluLookAt,通过调整参数,可以改变相机位置。

cpp 复制代码
/**
 * @brief GLWidget::resizeGL 窗口大小改变
 * @param w
 * @param h
 */
void GLWidget::resizeGL(int w, int h){
    glViewport(0,0,w,h);            //重新适应窗口大小
    glMatrixMode (GL_PROJECTION);
    glLoadIdentity ();
    gluPerspective(60.0, (GLfloat) w/(GLfloat) h, 1, 2000.0);           //设置相机投影参数
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

}
/**
 * @brief GLWidget::paintGL 绘制核心方法
 */
void GLWidget::paintGL(){
    glClearColor(0,0,0,0);                       //背景色
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);//清除上一次的缓存
    glLoadIdentity();  //加载单位矩阵
    gluLookAt(0,0,100, 0,0,0,   0.0,1.0,0);                             //设置相机

    glColor3f (1, 0, 1.0); //画笔颜色
    glRectf(-0.5, -0.5, 0.5, 0.5); // 绘制一个边长为1的矩形
}

第四步:鼠标跟随

实际上就是控制相机位置,通过改变相机位置,达到鼠标控制3D画面的效果。为了实现效果,定义一个水平面的角度degZ,一个垂直面角度degY,一个相机距离中心点的半径R,实际上就是定义极坐标,通过极坐标转换为三维坐标。鼠标滚轮改变半径R,坐标左右移动改变水平面角度degZ,鼠标上下移动Y,改变垂直面角度。

以下是一个具备基本功能的GLWidget类代码,强烈建议收藏

cpp 复制代码
#ifndef GLWIGET_H
#define GLWIGET_H

#include <QObject>
#include <QGLWidget>
#include <GL/gl.h>
#include <GL/glu.h>
#include <QMouseEvent>
#include <QWheelEvent>
class GLWidget : public QGLWidget
{
    Q_OBJECT
public:
    GLWidget();
    static GLWidget* getInstance();          //单例模式
protected:
    void resizeGL(int w, int h) override;   //窗口大小改变的时候,gl重新初始化
    void initializeGL() override;           //初始化gl
    void paintGL() override;                //核心绘制
    void mousePressEvent(QMouseEvent *event) override;
    void mouseMoveEvent(QMouseEvent *event) override;
    void mouseReleaseEvent(QMouseEvent *event) override;
    void wheelEvent(QWheelEvent *event) override;
private:
    double r;//相机距离中心的的半径
    double degZ;//在水平面的角度
    double degY;//在垂直面的角度
    double camx,camy,camz;//相机位置
    void refresh();//重新绘制
    QPoint old;//鼠标原始位置
    bool isPressed;//是否按下
};

#endif // GLWIGET_H
cpp 复制代码
#include "glwidget.h"
#include <qmath.h>
#include <QDebug>
GLWidget::GLWidget()
{
    r=100;//默认距离
    degY=degZ=0;
    camz=r*qCos(degZ);
    camx=r*qSin(degZ);
    camy=r*qSin(degY);
}

/**
 * @brief GLWidget::getInstance 单例模式
 * @return
 */
GLWidget* GLWidget::getInstance(){
    GLWidget* ins=NULL;
    if(ins==NULL)ins=new GLWidget();
    return ins;
}
/**
 * @brief GLWidget::initializeGL 初始化opengl。可以步写
 */
void GLWidget::initializeGL(){

}
/**
 * @brief GLWidget::resizeGL 窗口大小改变
 * @param w
 * @param h
 */
void GLWidget::resizeGL(int w, int h){
    glViewport(0,0,w,h);            //重新适应窗口大小
    glMatrixMode (GL_PROJECTION);
    glLoadIdentity ();
    gluPerspective(60.0, (GLfloat) w/(GLfloat) h, 1, 2000.0);           //设置相机投影参数
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

}
/**
 * @brief GLWidget::paintGL 绘制核心方法
 */
void GLWidget::paintGL(){
    glClearColor(0,0,0,0);                       //背景色
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);//清除上一次的缓存
    glLoadIdentity();  //加载单位矩阵
    gluLookAt(camx,camy,camz, 0,0,0,   0.0,1.0,0);                             //设置相机

    glColor3f (1, 0, 1.0); //画笔颜色
    glRectf(-50, -50, 50, 50); // 绘制一个边长为50的矩形
}
/**
 * @brief GLWidget::refresh 重新计算相机位置
 */
void GLWidget::refresh(){
    camz=r*qCos(degZ);
    camx=r*qSin(degZ);
    camy=r*qSin(degY);

    this->update();
}


void GLWidget::wheelEvent(QWheelEvent *event){
    qDebug()<<r<<event->delta();
    r+=event->delta()/20;
    if(r<20)r=20;
    if(r>1800)r=1800;
    refresh();
}
void GLWidget::mouseMoveEvent(QMouseEvent *event){
    if(isPressed){
        QPoint p=event->pos();
        degZ+=(p.x()-old.x())/5.0;
        degY+=(p.y()-old.y())/5.0;
        old=p;
        refresh();
    }
}

void GLWidget::mousePressEvent(QMouseEvent *event){

    if(event->button()==Qt::LeftButton){
        isPressed=true;
        old=event->pos();
    }
}
void GLWidget::mouseReleaseEvent(QMouseEvent *event){
    if(event->button()==Qt::LeftButton){
        isPressed=false;
    }
}

运行效果,可以通过鼠标来控制相机,达到3D效果

时间关系,就一篇就水到这里。周一再来一篇,写双面相机数据,如何显示到GLWidget。

相关推荐
zhooyu39 分钟前
利用叉乘判断OpenGL中的左右关系
c++·3d·opengl
m0_497214152 小时前
Qt事件系统
开发语言·qt
秋月的私语2 小时前
遥感影像拼接线优化工具:基于Qt+GDAL+OpenCV的从零到一实践
开发语言·qt·opencv
姓刘的哦3 小时前
Qt自定义控件
开发语言·qt
AlanW3 小时前
Qt Model/View 框架完全指南:从入门到性能优化
qt
艾莉丝努力练剑6 小时前
【QT】Qt常用控件与布局管理深度解析:从原理到实践的架构思考
linux·运维·服务器·开发语言·网络·qt·架构
Z文的博客6 小时前
嵌入式 ARM 设备交叉编译 mosquitto 2.0.20 (完整 TLS 支持) 详细教程 TRAE全程辅助,没敲一行代码
qt·mqtt·嵌入式·ai编程·mosquitto·嵌入式linux·trae
特立独行的猫a6 小时前
HarmonyOS 鸿蒙PC端 Qt 应用开发:第三方 Qt 开源软件移植指南
qt·harmonyos·鸿蒙·鸿蒙pc
C++ 老炮儿的技术栈16 小时前
GCC编译时无法向/tmp 目录写入临时汇编文件,因为设备空间不足,解决
linux·运维·开发语言·汇编·c++·git·qt
米优20 小时前
qt+vlc实现国标客户端测试工具
qt·gb28181·vlc