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

ops/2024/12/29 5:42:00/

上一篇文章写了如何把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框架,适合绘制平面图形,建议收藏。

#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;           //初始化glvoid paintGL() override;                //核心绘制
};#endif // GLWIGET_H
#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,通过调整参数,可以改变相机位置。

/*** @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类代码,强烈建议收藏

#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;           //初始化glvoid 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
#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。


http://www.ppmy.cn/ops/145840.html

相关文章

Yocto 项目 - 共享状态缓存 (Shared State Cache) 机制

引言 在嵌入式开发中&#xff0c;构建效率直接影响项目的开发进度和质量。Yocto 项目通过其核心工具 BitBake 提供了灵活而强大的构建能力。然而&#xff0c;OpenEmbedded 构建系统的传统设计是从头开始构建所有内容&#xff08;Build from Scratch&#xff09;&#xff0c;这…

利用 deepin-IDE 的 AI 能力,我实现了文件加密扩展

经过多轮迭代&#xff0c;deepin 文件管理器&#xff08;dde-file-manager&#xff09;的扩展功能已经趋于稳定&#xff0c;看到越来越丰富的文管新功能&#xff0c;作为一名技术爱好者&#xff0c;也想自己动手写个插件扩展一下文管的功能。 我选择的开发工具是 deepin-IDE&a…

【Rust自学】7.1. Package、Crate和定义Module

喜欢的话别忘了点赞、收藏加关注哦&#xff0c;对接下来的教程有兴趣的可以关注专栏。谢谢喵&#xff01;(&#xff65;ω&#xff65;) 7.1.1. Rust的代码组织 代码组织主要包括&#xff1a; 那些细节可以对外暴露&#xff0c;而哪些细节是私有的在作用域内哪些名称有效… …

重装荣耀X14笔记本电脑踩坑记

这几天趁着有国补搞了台荣耀 X14笔记本电脑。到手后第一件事情对我来说当然是要重装成Windows 11 LTSC版。所以按以往的经验做了个USB启动安装盘&#xff0c;但发现上电后按F12能进入启动设备选择&#xff0c;可是USB分类下没有任何设备。重启按F2进入设置界面&#xff0c;关闭…

StableAnimator模型的部署:复旦微软提出可实现高质量和高保真的ID一致性人类视频生成

文章目录 一、项目介绍二、项目部署模型的权重下载提取目标图像的关节点图像&#xff08;这个可以先不看先用官方提供的数据集进行生成&#xff09;提取人脸&#xff08;这个也可以先不看&#xff09;进行图片的生成 三、模型部署报错 一、项目介绍 由复旦、微软、虎牙、CMU的…

IDE 强大功能背后的 Language Server Protocol 详解

目录 LSP 中的核心概念 LSP 的主要功能 LSP 的工作原理 LSP 的设计理念 小结 IDE&#xff08;Integrated Development Environment&#xff0c;集成开发环境&#xff09;在软件开发过程中发挥着至关重要的作用&#xff0c;不仅提供了代码编辑的基本功能&#xff0c;还集成…

论文略读: TransTab: Learning Transferable Tabular Transformers Across Tables

2022 neurips motivation&#xff1a;有若干个有标签的表格&#xff0c;但是每个表格的列名&#xff08;代表的属性&#xff09;都不大一样 怎样把这些表格都利用起来&#xff0c;学习一个普适的embedding——>利用列名

梳理你的思路(从OOP到架构设计)_设计模式Template Method模式

目录 1、Template Method模式 2、范例&#xff1a; Android TM模式 3、基于TM模式的扩充&#xff1a;以游戏的绘图循环(Game Loop)为例 4、Android中处处可见TM模型的应用 1、Template Method模式 在前面各节里&#xff0c;我们介绍过&#xff0c;控制反转(IoC:Inversion…