QT集成intel RealSense 双目摄像头

ops/2024/12/29 1:47:23/

最近一个小项目,用到了双目相机,选用了Intel的RealSense双目相机。功能很简单,就是识别某一个物体,然后对对这个物体进行操作。具体功能随后再说,这里只介绍QT如何集成IntelRealSense相机,就是下面这个。

首先还是下载SDK,https://www.intelrealsense.com/developers/。这个页面有下载地址。不过下载地址是在github上,然后就比较尴尬,很难下载。下载安装完成以后,会得到一个官方提供的查看软件Intel RealSense Viewer。打开可以看图像,见下图。

相机获取了两个图像,上面颜色表示的是深度图。下面是常规照片。还可以用两个图像,合成一个3D的模型。见下图。

除查看软件外,还有用于开发的SDK和样例代码,文件夹结构如下图:

 大致看了一下官方提供的样例代码,都可以跑起来,但是都用了第三方的显示库,和opencv。并且都是用的VS。由于这个项目前期用的QT做的设备控制功能,再换VS可能性不大,所以需要在QT里面集成一下。网上搜了一下,资料很少,也不完全能用,还是自己弄把,正文开始:

第一步,给SDK相关文件拷贝到项目路径,lib,include,以及bin,就是dll。include是头文件,写代码的时候用的,只有头文件,没有具体实现,所以还需要lib文件,有了lib才能编译。编译完以后,再运行,就需要用dll文件。

第二步:在pro文件包含include文件夹,和lib文件。lib文件用的是x64。-L是lib文件所在路径,$$PWD是当前路径。-l是lib文件名称,后面是lib文件不带后缀。-L和-l两个后面都是没有空格,直接写。

第三步:创建一个Camera类,继承自QThread,在子线程获取图像,不卡主界面。

#include <QObject>
#include <QThread>
#include <librealsense2/rsutil.h>//包含sdk文件
#include <librealsense2/rs.hpp>//包含sdk文件
#include <QImage>
class Camera :public QThread
{Q_OBJECT
public:Camera();static Camera* getInstance();//单例模式void startCapture();        //开始采集void stopCapture();         //结束采集void run() override;        //线程函数
private slots:void doCam(int code,QString msg);   //用于接收线程信息,并弹出消息框
signals:void onCameraEvent(int code,QString msg);   //线程内部发送消息void onImage(QImage img);                   //线程内部发送图像采集成功信号private:bool isCapture;             //是否采集中rs2::pipeline pipe;         //采集采集对象};#endif // CAMERA_H

第三步:开始采集,按照官方SDK说法,只需要一个rs2::pipelie对象,start()开始采集,然后pipe.wait_for_frames()就ok了。

/*** @brief Camera::run 线程函数,用于打开相机和采集图像*/
void Camera::run(){try {pipe.start();       //尝试打开相机}catch (const std::exception& e){emit onCameraEvent(1, e.what() ); //如果没有成功,发送给主线程一个消息return;//返回,不继续了}emit onCameraEvent(0,"相机打开成功"); //如果打开成功,也发送一个rs2::colorizer color_map;//用于将深度数据,转换为图像数据色彩数据的map,isCapture=true;//循环控制变量while(isCapture){try {rs2::frameset data= pipe.wait_for_frames(); //获取一帧数据          rs2::frame color=data.get_color_frame();                    //获取彩色图像           const int w = color.as<rs2::video_frame>().get_width();     //获取图像宽度const int h = color.as<rs2::video_frame>().get_height();    //获取图像高度qDebug()<<"get frame"<<"width "<<w<<"height"<<h;}catch (const std::exception& e) {emit onCameraEvent(2,e.what());}}
}

代码运行,输出下面的结果,表示图像采集到了。这是获取的彩色图像的数据。

第四步:显示图像,官方提供的SDK是用openCV显示的,奈何只提供了VC编译的库,没有minGW版本的opencv库。无法使用。所以放弃opencv。 官方使用opencv代码如下:

// Create OpenCV matrix of size (w,h) from the colorized depth dataMat image(Size(w, h), CV_8UC3, (void*)depth.get_data(), Mat::AUTO_STEP);// Update the window with new dataimshow(window_name, image);

不难发现,这个图像的数据,实际上就是24位的RGB数据,也就是说,是标准的图像数据。有了这个结果,就简单了。不能用opencv,那就用QImage。反正是一样的用法,代码如下:

       rs2::frameset data= pipe.wait_for_frames(); //获取一帧数据          rs2::frame color=data.get_color_frame();                    //获取彩色图像           const int w = color.as<rs2::video_frame>().get_width();     //获取图像宽度const int h = color.as<rs2::video_frame>().get_height();    //获取图像高度qDebug()<<"get frame"<<"width "<<w<<"height"<<h;QImage img((uchar*)color.get_data(),w,h,QImage::Format_RGB888); //创建一个图片emit onImage(img);                                          //图片发送给主线程,mainwindow接收,并显示一下。

成功打开彩色图片

第五步:获取深度图像。咱们的目标是获取深度图。按官方说法,使用data.get_depth_frame();就可以。见下面代码:

    rs2::frame depth=data.get_depth_frame();                  //获取深度数据const int w = depth.as<rs2::video_frame>().get_width();     //获取图像宽度const int h = depth.as<rs2::video_frame>().get_height();    //获取图像高度qDebug()<<"get frame"<<"width "<<w<<"height"<<h;QImage img((uchar*)depth.get_data(),w,h,QImage::Format_RGB888); //创建一个图片emit onImage(img);                                          //图片发送给主线程,mainwindow接收,并显示一下。

运行,可以获取宽高,但是程序崩溃了。一般情况下,深度图像是单通道的,也就是说是一个8位灰度图或者是16位的灰度图。通过查看源码,确实是16位灰度图。

 创建QImage的时候,换成Grayscale16,见下图:

QImage img((uchar*)depth.get_data(),w,h,QImage::Format_Grayscale16); //创建一个图片

依稀能看出来是有数据的,但是直接显示不太好看,官方提供了一个深度转色彩的功能.apply_filter(color_map);可以转换为便于观看的色彩图片。

 完整Camera类代码:

#include "camera.h"
#include <QDebug>
#include <QException>
#include <common.h>Camera::Camera()
{connect(this,&Camera::onCameraEvent,this,&Camera::doCam);//链接线程内部的信号
}
/*** @brief Camera::getInstance 单例模式* @return*/
Camera* Camera::getInstance(){static Camera* ins=NULL;//static代码,唯一对象if(ins==NULL)ins=new Camera();//创建一个实力return ins;
}void Camera::startCapture(){loading("打开摄像头",0);//显示打开摄像头弹窗,一直显示,直到成功或是失败this->start();//开始子线程
}
/*** @brief Camera::stopCapture 停止采集*/
void Camera::stopCapture(){isCapture=false;//退出子线程pipe.stop();//停止相机
}
/*** @brief Camera::doCam 接收线程的消息,并弹窗显示* @param code 消息编码,0表示成功* @param msg 消息内容*/
void Camera::doCam(int code,QString msg){if(code==0)success(msg);else error(msg);
}
/*** @brief Camera::run 线程函数,用于打开相机和采集图像*/
void Camera::run(){try {pipe.start();       //尝试打开相机}catch (const std::exception& e){emit onCameraEvent(1, e.what() ); //如果没有成功,发送给主线程一个消息return;//返回,不继续了}emit onCameraEvent(0,"相机打开成功"); //如果打开成功,也发送一个rs2::colorizer color_map;//用于将深度数据,转换为图像数据色彩数据的map,isCapture=true;//循环控制变量while(isCapture){try {rs2::frameset data= pipe.wait_for_frames(); //获取一帧数据          rs2::frame color=data.get_color_frame();                    //获取彩色图像rs2::frame depth=data.get_depth_frame().apply_filter(color_map);  //获取深度数据,并转换为可见图const int w = depth.as<rs2::video_frame>().get_width();     //获取图像宽度const int h = depth.as<rs2::video_frame>().get_height();    //获取图像高度qDebug()<<"get frame"<<"width "<<w<<"height"<<h;QImage img((uchar*)depth.get_data(),w,h,QImage::Format_RGB888); //创建一个图片emit onImage(img);                                          //图片发送给主线程,mainwindow接收,并显示一下。}catch (const std::exception& e) {emit onCameraEvent(2,e.what());}}
}

后续准备同时显示深度和彩色图片,并在QT显示3D模型。


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

相关文章

linux、mysql日常工作备忘录

Mysql ==mysql8远程授权访问========================================== use mysql; mysql8不再允许直接对root用户授权远程访问,需要新建一个用户。 CREATE USER root@% IDENTIFIED BY password; GRANT ALL PRIVILEGES ON *.* TO root@% WITH GRANT OPTION;mysql8数据备份=…

亚马逊云科技 | Amazon Nova:智能技术新势力

在2024年亚马逊云科技re:invent大会上&#xff0c;Amazon Nova 系列自研生成式 AI 多模态模型重磅登场&#xff0c;新一代的AI产品-Amazon Nova&#xff0c;隶属于 Amazon Bedrock&#xff0c;一共发布6款大模型&#xff0c;精准切入不同领域&#xff0c;解锁多元业务可能&…

IOS safari 播放 mp4 遇到的坎儿

起因 事情的起因是调试 IOS 手机下播放服务器接口返回的 mp4 文件流失败。对于没调试过移动端和 Safari 的我来说着实费了些功夫&#xff0c;网上和AI也没有讲明白。好在最终大概理清楚了&#xff0c;在这里整理出来供有缘人参考。 问题 因为直接用 IOS 手机的浏览器打开页面…

国标GB28181设备管理软件EasyGBS:P2P远程访问故障排查指南(设备端)

在现代安防监控系统中&#xff0c;国标GB28181协议已成为连接和管理视频监控设备的重要标准。EasyGBS作为一款遵循该协议的设备管理软件&#xff0c;为用户提供了强大的视频监控和设备管理功能。然而&#xff0c;在实际应用中&#xff0c;用户可能会遇到P2P远程访问故障的问题&…

AI Agent案例全解析:百度营销智能体(8/30)

引言&#xff1a;在当今这个科技飞速发展的时代&#xff0c;AI技术呈现出爆发式的增长&#xff0c;正以前所未有的态势改变着众多行业的发展轨迹&#xff0c;营销领域也不例外。随着市场竞争的日益激烈&#xff0c;传统营销模式逐渐显露出疲态&#xff0c;对于变革的需求愈发迫…

MinIO服务器文件复制(Windows环境Linux环境)

一、下载 Windows环境&#xff1a;https://dl.min.io/server/minio/release/windows-amd64/minio.exe Linux环境&#xff1a; > curl https://dl.min.io/client/mc/release/linux-amd64/mc \ --create-dirs \ -o $HOME/minio/mc > chmod x $HOME/minio/mc > expo…

14: curl#6 - “Could not resolve host: mirrorlist.centos.org; 未知的错误“

出现这个错误是因为使用的 CentOS 7 仓库已经被归档&#xff0c;当前的镜像地址无法找到所需的文件。CentOS 7 的官方支持已经结束&#xff0c;部分仓库已被移至归档库。这导致了你的 yum 命令无法找到所需的元数据文件。CentOS 7 的官方仓库在 2024 年 6 月 30 日之后已经停止…

跨域问题解决

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言原理介绍&#xff1a;1.CrossOrigin注解2.实现WebMvcConfigurer接口3.使用过滤器4.vue代理服务器总结 前言 跨域问题由浏览器的同源策略引起&#xff0c;浏览器…