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

在之前的文章《【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 Envstd::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.rhkb.cn/news/160527.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

银河麒麟你服务x86访问ftp服务器上的文件

打开我的电脑 地址栏输入 ftp地址 可以选择需要的文件复制出来了

pytorch 入门(二)

本文为&#x1f517;小白入门Pytorch内部限免文章 &#x1f368; 本文为&#x1f517;小白入门Pytorch中的学习记录博客&#x1f366; 参考文章&#xff1a;【小白入门Pytorch】教案二&#x1f356; 原作者&#xff1a;K同学啊 目录 一、神经网络的组成部分1. 神经元2. 神经网络…

PyQt界面里如何加载本地视频以及调用摄像头实时检测(小白入门必看)

目录 1.PyQt介绍 2.代码实现 2.1实时调用摄像头 2.2 使用YOLOv5推理 2.3 代码中用到的主要函数 1.PyQt介绍 PyQt是一个用于创建桌面应用程序的Python绑定库&#xff0c;它基于Qt框架。Qt是一个跨平台的C应用程序开发框架&#xff0c;提供了丰富的图形界面、网络通信、数据…

阶段性总结

uart协议&#xff1a; 通用异步收发器 UART&#xff08;Universal Asynchronous Receiver/Transmitter)&#xff0c;是一种串行、异步、全双工的通信协议&#xff0c;将所需传输的数据一位接一位地传输&#xff0c;在UART通讯协议中信号线上的状态位高电平代表’1’&#xff0…

竞品价格怎么监测

品牌在做产品营销、产品定价时&#xff0c;除了要做好自身产品的研发设计外&#xff0c;需要非常了解市场&#xff0c;了解消费者偏好、了解竞品数据&#xff0c;通过对比分析&#xff0c;从而知道哪些价位的产品更受消费者喜爱&#xff0c;怎样设计产品更符合市场要求等&#…

黑马JVM总结(三十六)

&#xff08;1&#xff09;CAS-概述 cas是配合volatile使用的技术 &#xff0c;对共享变量的安全性要使用synachonized加锁&#xff0c;但是CAS不加锁&#xff0c;它是使用where&#xff08;true&#xff09;的死循环&#xff0c;里面compareAndSwap尝试把结果赋值给共享变量&…

linux下的rsync(文件同步) 用法教程

一、简介 rsync 是一个常用的 Linux 应用程序&#xff0c;用于文件同步。 它可以在本地计算机与远程计算机之间&#xff0c;或者两个本地目录之间同步文件&#xff08;但不支持两台远程计算机之间的同步&#xff09;。它也可以当作文件复制工具&#xff0c;替代cp和mv命令。 …

RAII与智能指针

RAII与智能指针 1.RAII1.1RAII理解1.2RAII的原理1.2.1简单的例子说明局部对象的自动销毁的特性 1.2.2 RAII 过程 2.智能指针2.1 auto_ptr2.1.1auto_ptr的使用构造函数与析构函数拷贝构造函数与赋值提领操作auto ptr其它函数 2.1.2autoptr使用的注意事项 2.2 unique_ptr2.2.1uni…

ros学习笔记(1)Mac本地安装虚拟机,安装Ros2环境

Ros与Linux的关系 Ros环境基于Linux系统内核 我们平时用的是Linux发行版&#xff0c;centos&#xff0c;ubuntu等等&#xff0c;机器人就用了ubunut 有时候我们经常会听到ubunue的版本&#xff0c;众多版本中&#xff0c;有一些是长期维护版TLS&#xff0c;有一些是短期维护…

微信小程序个人账号申请和配置详细教程

一、注册小程序管理账号 1、注册方法 在微信公众平台官网首页&#xff08;mp.weixin.qq.com&#xff09;&#xff0c;点击右上角的“立即注册”按钮。 2、选择注册的账号类型 选择“小程序”&#xff0c;点击“查看类型区别”可查看不同类型账号的区别和优势。 3、填写邮箱和…

探秘网页打开的完整过程:DNS解析、CDN加速和Nginx负载均衡的协同驱动

浅谈一个网页打开的全过程&#xff08;涉及DNS、CDN、Nginx负载均衡等&#xff09; 1、概要 从用户在浏览器输入域名开始&#xff0c;到web页面加载完毕&#xff0c;这是一个说复杂不复杂&#xff0c;说简单不简单的过程&#xff0c;下文暂且把这个过程称作网页加载过程。下面…

2652. 倍数求和

2652. 倍数求和 题目方法-【枚举】 & 题目特征-【求计算在给定范围内满足某种条件的整数之和】方法-【容斥原理】 & 题目特征-【计算满足多个条件的元素之和&#xff0c;并且需要避免重复计数】 题目 题目链接&#xff1a;https://leetcode.cn/problems/sum-multiples…

Idea集成Docker

1、前言 上一节中&#xff0c;我们介绍了Dockerfile的方式构建自己的镜像。但是在实际开发过程中&#xff0c;一般都会和开发工具直接集成&#xff0c;如Idea。今天就介绍下idea和Docker如何集成。 2、开启docker远程 要集成之前&#xff0c;需要我们本机能够访问docker服务…

每日一题 2652. 倍数求和(简单)

最简单的做法&#xff0c;遍历求和&#xff0c;时间O(n) class Solution:def sumOfMultiples(self, n: int) -> int:return sum([i if (i % 3 0) or (i % 5 0) or (i % 7 0) else 0 for i in range(n 1)])如果只求在 [1,n] 内能被m整除的数之和&#xff0c;那么 ans (…

[MQ]Win平台RocketMQ安装启动

1、下载 官网下载地址&#xff1a;https://rocketmq.apache.org/zh/download 2、解压ZIP包 解压rocketmq-all-x.x.x-bin-release.zip到目录。 比如我解压到了E:\Env\MQ_rocket\rocketmq-all-5.1.4-bin-release 3、配置环境变量 ROCKETMQ_HOME 4、RocketMQ JVM内存配置 这个需要…

3dmax中的 (Corona 9)cr渲染器怎么渲染?cr渲染器使用教程

Corona 9渲染器在3ds Max和Cinema 4D中应用广泛&#xff0c;是一款高效且功能强大的渲染器&#xff0c;得到了许多用户的好评。 Corona 9有以下几个主要的特点&#xff1a; 出色的渲染速度&#xff1a;Corona 9被证明是一个快速且高效的渲染引擎&#xff0c;它能够在保证高质…

虹科 | 解决方案 | 虹科Pico振动异响(NVH)诊断方案

车辆行驶过程中的偶发性异响&#xff08;比如经过颠簸路面时的吱嘎声&#xff09;和某一特定车速/转速下持续/周期性出现的异响&#xff0c;要将故障重现并定位故障点&#xff0c;对维持技师来讲是个重大的挑战。传统的测试方法是使用底盘听诊器&#xff0c;车辆一边在路上跑&a…

一文带你认识高速低侧栅极驱动器 FAN3111ESX 带你深入了解其特点及应用

FAN3111ESX一款低端驱动器产品&#xff0c;是外部 DC 2 至 5 V 参考输入、单通道同相输出、1.4 A 峰值灌电流、1.4 A 源电流低端栅极驱动器。 FAN3111ESX 1A栅极驱动器为驱动一个在低侧开关应用中的 N沟道增强型 MOSFET 而设计。 对于使用低压控制器和其它和驱动器相比使用更…

云计算是什么?学习云计算能做什么工作?

很多人经常会问云计算是什么&#xff1f;云计算能干什么&#xff1f;学习云计算能做什么工作&#xff1f;其实我们有很多人并不知道云计算是什么&#xff0c;小知今天来给大家讲讲学习云计算能做什么。 中国的云计算行业目前正处于快速发展阶段&#xff0c;随着互联网和数字化…

JMeter连接数据库

一. 下载数据库驱动jar包 https://jdbc.postgresql.org/download/ 二. 将数据库驱动放到jmeter的lib目录下 三. 在jmeter中引用这个jar包 四. 添加一个jdbc数据库连接配置 五. 添加一个jdbc request来查询sql并将查询结果赋值给一个变量 六. 将查询结果用于其他请求