【QT开发(8)】QT 中使用tensorrt

news2025/7/12 8:04:07

在之前的文章《【TensorRT(2)】研究美团tech的yolov6的TensorRT部署》说明了tensorRT 的使用流程。今天尝试将其并入QT 项目中。

文章目录

  • 项目地址
  • 参考资料:
  • 该分支主要做的工作
  • Task 1:读取视频文件,然后通过 dds 发送的事情
  • Task 2.1:将 yolov6 作为deeplib 库。
  • # Task 2.2:接收 dds 信息,用 deeplib 库推理图片。
  • 演示gif 动画

项目地址

库地址:https://gitee.com/hiyanyx/qt5.14-cpp_dds_-project/tree/dds_-tensorRT-yolov6/

参考资料:

1、代码参考:https://gitee.com/xiaoyuerCV/tensorrt-yolov6/,已经下载到了目录 ./reference/YOLOv6-Trt8

2、pytorch 权重下载:美团yolov6,已经下载到了目录 ./reference/YOLOv6-main-meituan/deployONNX

原理:下载 pytorch 的权重,yolov6s.pt,转换成 onnx。然后,把onnx 复制到 ./reference/YOLOv6-Trt8。然后trt 里面的c代码会自动把onnx 序列化为 yolov6s.engine 文件。

3、行人视频:reference/YOLOv6-Trt8/xingren.mp4

该分支主要做的工作

1、在 ./src/main/example.cpp 中实现了读取视频文件,然后通过 dds 发送的事情。

2、将 ./reference/YOLOv6-Trt8 作为 库 引入到 c++ 代码工程中,库名字为 deeplib,位置:./deps/deeplib。 具体工作为修改cmakelist文件,生成动态库 deeplib.so,增加deeplib.h 作为yolo检测器的接口(实现了Inferclass这个对象进行检测)。

Task 1:读取视频文件,然后通过 dds 发送的事情

1、在之前的文章【QT开发(6)】0926-QT 中加入 fastDDS 通信库的程序使用说明中说明了dds 的使用方法。

2、我们基于上次的项目,修改 examples.hpp, 在 class Example 增加一个对象成员 cv::VideoCapture video_capture;。 特别说明以下,关于对象成员的初始化可以查看我的博客【C++学习(8)】类对象作为成员变量 和 【C++学习(10)】将一个类作为另一个类的成员: 类对象和类指针; std::unique_ptr 智能管理类指针。成员对象的初始化还是有很多知识点,作为基础知识大家需要学习。

3、修改 examples.cpp对 video_capture 的一些属性进行修改。

video_capture.open("/var/files/yanyixiong/qt5.14-cpp_-empty_-project/deps/deeplib/xingren.mp4");
// 视频mp4解码
  int codec = cv::VideoWriter::fourcc('D', 'I', 'V', 'X');
//获得
  double fps = video_capture.get(cv::CAP_PROP_FPS);
// 宽度
  int width = video_capture.get(cv::CAP_PROP_FRAME_WIDTH);
//高度
  int height = video_capture.get(cv::CAP_PROP_FRAME_HEIGHT);

4、然后在50ms定时器中设置发送dds 信息。如果不明白我说的这个定时器是什么东西,请查看博文【QT开发(6)】0926-QT 中加入 fastDDS 通信库的程序使用说明

我把那篇的截图放一下:
在这里插入图片描述

void Example::timer_WorkingStatus_callback()
{
  // Test Env
  std::vector<unsigned char> vec_data;
  cv::Mat frame_pub;
  video_capture.read(frame_pub);

  if (!frame_pub.data ) {
              debug::log("fail to imread");
              return ;
      }
  else
      {
              //cv::imshow("source image", img1);
              //cv::waitKey(1);
              //cv::resize(frame_pub, frame_pub, cv::Size(),0.1, 0.1);
              debug::log("success to imread");
      }

  cv::imencode(".jpg", frame_pub, vec_data);
  auto_msg::msg::FrameData msg1;
  msg1.time_stamp() = get_time_ms();
  msg1.data() = vec_data;
  //msg1.data.insert(msg1.data.end(), vec_data.begin(), vec_data.end());
  simulation_raw_images_pub_->publish(msg1);
}

5、至此,dds 发送视频就完成了。接下来,我们需要接受dds 信息,并用 yolov6 推理。

Task 2.1:将 yolov6 作为deeplib 库。

将 ./reference/YOLOv6-Trt8 作为 库 引入到 c++ 代码工程中,库名字为 deeplib,位置:./deps/deeplib。 具体工作为修改cmakelist文件,生成动态库 deeplib.so,增加deeplib.h 作为yolo检测器的接口(实现了Inferclass这个对象进行检测)。

1、 ./deps/deeplib 修改cmakelists,增加库

ADD_LIBRARY(deeplib SHARED ${SOURCES_FILES})
target_include_directories(deeplib PUBLIC ${SOURCES_PATH})
target_link_libraries(deeplib cuda tensorrt opencv)

2、写deeplib.h 接口程序
写一个对象 Inferclass,包含,构造函数,析构函数,推理接口inferIOmain,以及复制构造函数。
包含 私有成员类指针 Yolov6Detector,这个是在https://gitee.com/xiaoyuerCV/tensorrt-yolov6/里面已经实现的

class Inferclass {
public:
  Inferclass(std::string model_path = "/var/files/yanyixiong/qt5.14-cpp_-empty_-project/deps/deeplib/yolov6s.onnx");
	Inferclass(const Inferclass &S);
	void inferIOmain(cv::Mat input_image);
	~Inferclass();

private:
    std::string model_path ;
    std::unique_ptr<Yolov6Detector> yolov6_detector;

};

在 构造函数 中完成对 Yolov6Detector 对象的初始化。

Inferclass::Inferclass(std::string model_path):model_path(model_path)
{
    std::cout << "Start" << std::endl;
// 导入onnx 地址
  this->yolov6_detector.reset(new Yolov6Detector(model_path));
  if (!this->yolov6_detector->Init()) {
    std::cout << "Failed to initialize Yolov6 detector!";
  }

}

析构函数 ,因为我们使用的是std::unique_ptr 类指针,不需要手动new和delete 指针。需要注意的是,如果我们是使用普通指针,一定到在 析构函数里面把 这个类指针释放,否则是内存泄漏!

Inferclass::~Inferclass()
{
    std::cout << "End" << std::endl;
	//-----------------代码-------------------------------
	if(NULL != pA)//此处需要初始化时设置指针为空。
	{
	  delete pA;
	  pA = new A;
	}  else {
	  pA = new A;
	}
	//-----------------代码-------------------------------

}

推理接口 inferIOmain函数:

void Inferclass::inferIOmain(cv::Mat input_image) {
  //cv::Mat input_image;
// 建立目标列表
    std::vector<Object> objects;
// 检测图像 
   this->yolov6_detector->Detect(input_image, &objects);
    //画图
    DrawObjects(input_image, objects);
// 展示图片
    cv::imshow("YOLOv6 Object detection", input_image);
    cv::waitKey(1);
  }

3、我们有了 deeplib.h 和cmakelist文件,这就是一个库了,可以被其他项目使用。这是个基础的工作,如果你不懂怎么在主项目里面引入库,可以看之前的git仓库学习cmake practice。

# Task 2.2:接收 dds 信息,用 deeplib 库推理图片。

在之前的文章【QT开发(6)】0926-QT 中加入 fastDDS 通信库的程序使用说明中,引入deeplib 库。

1、修改 cmakelists,增加头文件

# ===== 设置 include 目录路径 =====
target_include_directories ( emptyApp PUBLIC
    # === 第三方库 ===
    # 在此处添加更多 第三方库
    # 具体写法,请查阅各个 库文档
    ${CMAKE_CURRENT_SOURCE_DIR}/deeplib/src
    )

2、修改 cmakelists,增加 cmaklist 子目录

#---------------------------------------------------#
#             子目录 CMakeLists.txt
#---------------------------------------------------#
#-- 子 CMakeLists.txt 执行的 中间产物,将分别放在 
#      build/src  build/libhello  目录中。
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/deps/deeplib EXCLUDE_FROM_ALL)

3、修改 cmakelists,增加一个 target_link_libraries

    target_link_libraries( emptyApp 
			    deeplib)

4、至此,修改完了 cmakelists。然后在 Examples.h 中增加成员类。

在博客【C++学习(10)】将一个类作为另一个类的成员: 类对象和类指针; std::unique_ptr 智能管理类指针,我们谈到,如果是在 一个 class 中增加另一个 类成员,首先,要将A类的对象作为B类的成员,你必须在B类声明前声明A类。其次,就是像声明一个成员变量一样,在B类中添加一个成员,如A m_a; 最后,初始化m_a。因为这个成员是一个类对象,因此需要调用构造函数才能初始化。因为这个对象m_a在B类中,m_a对象的构造必然是在B类对象构造之前进行,因此不能在B类构造函数中进行,又因为m_a不是全局对象,也不能在函数外部。如何解决这个问题呢?这就是C++提出的成员初始化列表,用来解决这类问题的。

因此,我们增加一个 类成员

class Example : public rclcpp::Node
{
 public:
  Example(std::string model_path);
  ~Example();
  int Init();
  int Start();
  int Stop();
  Inferclass InferPr;
...
...
}

然后在 Examples.cpp 中class Examples 成员初始化列表 初始化。

Example::Example(std::string model_path) : rclcpp::Node("example"),InferPr(model_path)
{
  running_ = false;
  workingStatus_timer_ = nullptr;
}

完成了初始化,就可以使用这个 InferPr 成员,在50ms 定时器中用它进行推理

void Example::timer_WorkingStatus_callback()
{
  auto_msg::msg::FrameData stitch_img = stitch_img_.Get();
    if ( running_ == true && stitch_img.time_stamp()>0) {
      cv::Mat frame = cv::imdecode(stitch_img.data(), CV_LOAD_IMAGE_COLOR);
      InferPr.inferIOmain(frame);
    }
    else
    {
        std::cout << "Timer trick 50ms, waiting" << std::endl;
    }
  }

4、至此,完成了工作

演示gif 动画

ScreenToGif 很好用呀,推荐。
在这里插入图片描述

正文结束

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1103218.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

2008-2017年上市公司海外收入数据

2008-2017年上市公司海外收入数据 1、时间&#xff1a;2008-2017年 2、指标&#xff1a;上市公司海外收入 3、范围&#xff1a;A股 4、来源&#xff1a;WIND 5、指标解释&#xff1a; 上市公司&#xff08;The listed company&#xff09;&#xff0c;根据《公司法》第四…

交通目标检测-行人车辆检测流量计数 - 计算机竞赛

文章目录 0 前言1\. 目标检测概况1.1 什么是目标检测&#xff1f;1.2 发展阶段 2\. 行人检测2.1 行人检测简介2.2 行人检测技术难点2.3 行人检测实现效果2.4 关键代码-训练过程 最后 0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; 毕业设计…

MySQL——七、MySQL备份恢复

MySQL 一、MySQL日志管理1、MySQL日志类型2、错误日志3、通用查询日志4、慢查询日志5、二进制日志5.1 开启日志5.2 二进制日志的管理5.3 日志查看5.4 二进制日志还原数据 二、MySQL备份1、备份类型逻辑备份优缺点 2、备份内容3、备份工具3.1 MySQL自带的备份工具3.2 文件系统备…

做接口测试的流程一般是怎么样的?UI功能6大流程、接口测试8大流程这些你真的全会了吗?

在讲接口流程测试之前&#xff0c;首先需要给大家申明下&#xff1a;接口测试对于测试人员而言&#xff0c;非常非常重要&#xff0c;懂功能测试接口测试&#xff0c;就能在企业中拿到一份非常不错的薪资。 这么重要的接口测试&#xff0c;一般也是面试笔试必问。为方便大家更…

k8s-20 hpa控制器

hpa可通过metrics-server所提供pod的cpu 或者内存的负载情况&#xff0c;从而动态拉伸控制器的副本数&#xff0c;从而达到后端的自动弹缩 官网&#xff1a;https://kubernetes.io/zh-cn/docs/tasks/run-application/horizontal-pod-autoscale-walkthrough/ 上传镜像 压测 po…

模型量化笔记--KL散度量化

KL散度量化 前面介绍的非对称量化中&#xff0c;是将数据中的min值和max值直接映射到[-128, 127]。 同样的&#xff0c;前面介绍的对称量化是将数据的最大绝对值 ∣ m a x ∣ |max| ∣max∣直接映射到127。 上面两种直接映射的方法比较粗暴&#xff0c;而TensorRT中的int8量化…

有没有好用的扫描爆破工具?来看这里

工具介绍 goon集合了fscan和kscan等优秀工具功能的扫描爆破工具。功能包含&#xff1a;ip探活、port扫描、web指纹扫描、title扫描、压缩文件扫描、fofa获取、ms17010、mssql、mysql、postgres、redis、ssh、smb、rdp、telnet、tomcat等爆破以及如netbios探测等功能。 参数说…

Linux高性能服务器编程 学习笔记 第十六章 服务器调制、调试和测试

Linux平台的一个优秀特性是内核微调&#xff0c;即我们可以通过修改文件的方式来调整内核参数。 服务器开发过程中&#xff0c;可能会碰到意想不到的错误&#xff0c;一种调试方法是用tcpdump抓包&#xff0c;但这种方法主要用于分析程序的输入和输出&#xff0c;对于服务器的…

Atlassian Confluence OGNL表达式注入RCE CVE-2021-26084

影响版本 All 4.x.x versions All 5.x.x versions All 6.0.x versions All 6.1.x versions All 6.2.x versions All 6.3.x versions All 6.4.x versions All 6.5.x versions All 6.6.x versions All 6.7.x versions All 6.8.x versions All 6.9.x versions All 6.1…

uniapp使用uQRCode绘制二维码,下载到本地,调起微信扫一扫二维码核销

1.效果 2.在utils文件夹下创建uqrcode.js // uqrcode.js //--------------------------------------------------------------------- // github https://github.com/Sansnn/uQRCode //---------------------------------------------------------------------let uQRCode {…

小学数学题AI自动出题系统源码,支持在线打印及导出PDF!

今天给大家开发了个好东西&#xff0c;小学数学作业练习册AI自动出题网站源码&#xff0c;全面支持打印机打印机转成PDF文件&#xff0c;快给你家娃娃整一套吧&#xff0c;AI自动出题&#xff0c;让娃练习算数&#xff0c;解放双手&#xff0c;让您的孩子成绩蒸蒸日上&#xff…

【微服务 SpringCloudAlibaba】实用篇 · Nacos注册中心

微服务&#xff08;5&#xff09; 文章目录 微服务&#xff08;5&#xff09;1. 认识和安装Nacos2. 服务注册到nacos和拉取服务1&#xff09;引入依赖2&#xff09;配置nacos地址3&#xff09;重启 3. 服务分级存储模型3.1 给user-service配置集群3.2 同集群优先的负载均衡 4. …

高程DEM-等高线生成-AutoCAD等高线

高程DEM-等高线生成-AutoCAD等高线 发布时间&#xff1a;2018-01-17 版权&#xff1a; 同步视频教程&#xff1a;卫星地图_高清卫星地图_卫星地图视频_下载高程等高线使用视频教程 专题地图制作视频教程&#xff1a;卫星地图_高清卫星地图_卫星地图视频_地图数据应用&#xf…

【C++】--遇到抛异常没有及时释放的空间该怎么办??---智能指针来帮你解决(以及定制删除器)

&#x1f496;作者&#xff1a;小树苗渴望变成参天大树&#x1f388; &#x1f389;作者宣言&#xff1a;认真写好每一篇博客&#x1f4a4; &#x1f38a;作者gitee:gitee✨ &#x1f49e;作者专栏&#xff1a;C语言,数据结构初阶,Linux,C 动态规划算法&#x1f384; 如 果 你 …

04、RocketMQ -- 核心基础使用

目录 核心基础使用1、入门案例生产者消费者 2、消息发送方式方式1&#xff1a;同步消息方式2&#xff1a;异步消息方式3&#xff1a;一次性消息管控台使用过程中可能出现的问题 3、消息消费方式集群模式&#xff08;默认&#xff09;广播模式 4、顺序消息分析图&#xff1a;代码…

[uni-app] canvas绘制圆环进度条

文章目录 需求参考链接基本问题的处理1:画布旋转的问题2:注意arc()的起始位置是3点钟方向3: 如果绘制1.9*Matn.PI的圆环, 要保证其实位置在0点方向?4:小线段怎么画, 角度怎么处理? 源码 需求 要绘制一个如此的进度条 参考链接 uni-app使用canvas绘制时间刻度以及不显示问…

线段树【java实现】

一、解决问题 区间最值和区间求和问题 力扣相关题目&#xff1a; ​​​​​​303. 区域和检索 - 数组不可变 729. 我的日程安排表 I 二、线段树定义 平衡二叉树&#xff0c;数组中的元素都存储在叶子结点中&#xff0c;如图是一个求区间最大值的线段树。 已知数组arr[11…

电源特性测试之电源模块负载调整率测试方法及测试条件

负载调整率是衡量电源好坏的重要指标&#xff0c;它反映的是当负载电流变化时&#xff0c;稳压电源输出电压相应的变化情况。好的电源负载变化时引起的输出变化较小&#xff0c;通常是在3%-5%。负载调整率是电源模块测试的一个重要步骤&#xff0c;今天纳米软件将为大家介绍负载…

Yakit工具篇:综合目录扫描与爆破的使用

简介&#xff08;来自官方文档&#xff09; 目录扫描是一种常用的Web应用程序安全测试技术&#xff0c;用于发现Web应用程序中存在的可能存在的漏洞和弱点。其原理是通过对Web应用程序中的目录和文件进行遍历&#xff0c;来发现可能存在的安全漏洞和风险。 具体来说&#xff…