MMDeploy部署实战系列【第六章】:将编译好的MMdeploy导入到自己的项目中 (C++)
MMDeploy部署实战系列【第六章】:将编译好的MMdeploy导入到自己的项目中 (C++)
这个系列是一个随笔,是我走过的一些路,有些地方可能不太完善。如果有那个地方没看懂,评论区问就可以,我给补充。
版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。
目录:
0️⃣ mmdeploy源码安装 (转换faster rcnn r50/yolox为tensorrt,并进行推理)_gy77
内容:一文包含了在Linux系统下安装mmdeploy模型转换环境,模型转换为TensorRT,在Linux,Windows下模型推理,推理结果展示。
1️⃣ MMDeploy部署实战系列【第一章】:Docker,Nvidia-docker安装_gy77
内容:docker/nvidia-docker安装,docker/nvidia-docker国内源,docker/nvidia-docker常用命令。
2️⃣ MMDeploy部署实战系列【第二章】:mmdeploy安装及环境搭建_gy77
内容:mmdeploy环境安装三种方法:源码安装,官方docker安装,自定义Dockerfile安装。
3️⃣ MMDeploy部署实战系列【第三章】:MMdeploy pytorch模型转换onnx,tensorrt_gy77
内容:如何查找pytorch模型对应的部署配置文件,模型转换示例:mmcls:resnext50,mmdet:yolox-s,faster rcnn50。
4️⃣ MMDeploy部署实战系列【第四章】:onnx,tensorrt模型推理_gy77
内容:在linux,windows环境下推理,Windows下推理环境安装,推理速度对比,显存对比,可视化展示。
5️⃣ MMDeploy部署实战系列【第五章】:Windows下Release x64编译mmdeploy(C++),对TensorRT模型进行推理_gy77
内容:Windows下环境安装编译环境,编译c++ mmdeploy,编译c++ mmdeploy demo,运行实例。
6️⃣ MMDeploy部署实战系列【第六章】:将编译好的MMdeploy导入到自己的项目中 (C++)_gy77
内容:Windows下环境导入我们编译好的mmdeploy 静态/动态库。
下面是正文:
️ 注意:我用的是mmdeploy==0.5.0版本,在mmdeploy新版本中方法名都经过了修改。下面报红的内容要根据自己的 mmdeploy/detector.h 修改为正确的方法名。
官方文档: 操作概述 — mmdeploy 0.6.0 文档
项目环境配置:
1️⃣ 创建一个控制台应用,并起名inference_sdk(有自己项目的就在自己项目中直接修改即可,不用这一步)
2️⃣ 右下角属性管理器,右击Release |x64,因为我们编译mmdeploy时用的Release x64,这个要对应,新建一个项目属性表,起名mmlab。

3️⃣ 双击打开mmlab属性表,
VC++ 目录 --> 包含目录 --> 添加
F:\gy77\mmdeploy\build\install\include
F:\env\opencv455\opencv\build\include\opencv2
F:\env\opencv455\opencv\build\include\opencv
F:\env\opencv455\opencv\build\include
链接器 --> 输入 --> 附加依赖项。根据自己的目录修改,第一个是opencv目录。(当然也可以通过在VC++里添加库目录,然后在链接器输入里加lib文件)
F:\env\opencv455\opencv\build\x64\vc15\lib\opencv_world455.lib
F:\gy77\mmdeploy\build\install\example\build\Release\object_detection_loader.lib
F:\gy77\mmdeploy\build\install\lib\mmdeploy_opencv_utils.lib
F:\gy77\mmdeploy\build\install\lib\mmdeploy_classifier.lib
F:\gy77\mmdeploy\build\install\lib\mmdeploy_detector.lib
F:\gy77\mmdeploy\build\install\lib\mmdeploy_segmentor.lib
F:\gy77\mmdeploy\build\install\lib\mmdeploy_text_detector.lib
F:\gy77\mmdeploy\build\install\lib\mmdeploy_text_recognizer.lib
F:\gy77\mmdeploy\build\install\lib\mmdeploy_restorer.lib
F:\gy77\mmdeploy\build\install\lib\mmdeploy_pose_detector.lib
F:\gy77\mmdeploy\build\install\lib\mmdeploy_rotated_detector.lib
F:\gy77\mmdeploy\build\install\lib\mmdeploy_pipeline.lib
F:\gy77\mmdeploy\build\install\lib\mmdeploy_model.lib
F:\gy77\mmdeploy\build\install\lib\mmdeploy_executor.lib
F:\gy77\mmdeploy\build\install\lib\mmdeploy_common.lib
F:\gy77\mmdeploy\build\install\lib\mmdeploy_core.lib
F:\gy77\mmdeploy\build\install\lib\spdlog.lib
链接器 --> 命令行 --> 其他选项:
%(AdditionalOptions) /machine:x64 /WHOLEARCHIVE:object_detection_loader
编写代码
在解决方案资源管理器,源文件中,修改inference_sdk.cpp,内容如下:
#include <iostream>
#include <fstream>
#include <opencv2/imgcodecs/imgcodecs.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <string>
#include "mmdeploy/detector.h"
using namespace std;
string coco_classes[80] = {"person", "bicycle", "car",
"motorcycle", "airplane", "bus",
"train", "truck", "boat",
"traffic light", "fire hydrant", "stop sign",
"parking meter", "bench", "bird",
"cat", "dog", "horse",
"sheep", "cow", "elephant",
"bear", "zebra", "giraffe",
"backpack", "umbrella", "handbag",
"tie", "suitcase", "frisbee",
"skis", "snowboard", "sports ball",
"kite", "baseball bat", "baseball glove",
"skateboard", "surfboard", "tennis racket",
"bottle", "wine glass", "cup",
"fork", "knife", "spoon",
"bowl", "banana", "apple",
"sandwich", "orange", "broccoli",
"carrot", "hot dog", "pizza",
"donut", "cake", "chair",
"couch", "potted plant", "bed",
"dining table", "toilet", "tv",
"laptop", "mouse", "remote",
"keyboard", "cell phone", "microwave",
"oven", "toaster", "sink",
"refrigerator", "book", "clock",
"vase", "scissors", "teddy bear",
"hair drier", "toothbrush"};
int main() {
// init
const char *device_name = "cuda";
const char *model_path = "F:\\gy77\\mmdeploy\\mmdeploy_models\\yolox_s";
const char *img_path = "F:\\imgs\\demo.jpg";
mmdeploy_detector_t detector{};
mmdeploy_detection_t *bboxes{};
int *res_count{};
int status{};
int max_res_count = 10;
status = mmdeploy_detector_create_by_path(model_path, device_name, 0, &detector);
if (status != MMDEPLOY_SUCCESS) {
fprintf(stderr, "failed to create detector, code: %d\n", (int) status);
return 1;
}
// load image
clock_t t0 = clock();
cv::Mat img = cv::imread(img_path);
mmdeploy_mat_t mat{
img.data, img.rows, img.cols, 3, MMDEPLOY_PIXEL_FORMAT_BGR, MMDEPLOY_DATA_TYPE_UINT8};
// inference
clock_t t1 = clock();
status = mmdeploy_detector_apply(detector, &mat, 1, &bboxes, &res_count);
clock_t t2 = clock();
for (int i = 0; i < max_res_count; ++i) {
const auto &box = bboxes[i].bbox;
const auto &mask = bboxes[i].mask;
// skip detections with invalid bbox size (bbox height or width < 1)
if ((box.right - box.left) < 1 || (box.bottom - box.top) < 1) {
continue;
}
// skip detections less than specified score threshold
if (bboxes[i].score < 0.3) {
continue;
}
cv::rectangle(img, cv::Point{(int) box.left, (int) box.top},
cv::Point{(int) box.right, (int) box.bottom}, cv::Scalar{0, 255, 0}, 2);
cv::putText(img, coco_classes[bboxes[i].label_id] + ":" + std::to_string(bboxes[i].score),
cv::Point{(int) box.left, (int) box.top}, cv::FONT_HERSHEY_SIMPLEX, 0.5,
cv::Scalar{0, 0, 255}, 2);
}
//show image
cv::imshow("img", img);
clock_t t3 = clock();
cout << "load image cost time: " << (t1 - t0) / (double) CLOCKS_PER_SEC << "s" << endl;
cout << "mmdeploy_detector_apply cost time" << (double) (t2 - t1) / CLOCKS_PER_SEC << "s" << endl;
cout << "cv::imshow cost time" << (double) (t3 - t2) / CLOCKS_PER_SEC << "s" << endl;
cv::waitKey(0);
cv::destroyAllWindows();
return 0;
}
结果展示:
log:
loading mmdeploy_execution ...
loading mmdeploy_cpu_device ...
loading mmdeploy_cuda_device ...
loading mmdeploy_graph ...
loading mmdeploy_directory_model ...
[2022-08-01 12:33:53.232] [mmdeploy] [info] [model.cpp:95] Register 'DirectoryModel'
loading mmdeploy_transform ...
loading mmdeploy_cpu_transform_impl ...
loading mmdeploy_cuda_transform_impl ...
loading mmdeploy_transform_module ...
loading mmdeploy_trt_net ...
loading mmdeploy_net_module ...
loading mmdeploy_mmcls ...
loading mmdeploy_mmdet ...
loading mmdeploy_mmseg ...
loading mmdeploy_mmocr ...
loading mmdeploy_mmedit ...
loading mmdeploy_mmpose ...
loading mmdeploy_mmrotate ...
[2022-08-01 12:33:53.293] [mmdeploy] [info] [model.cpp:38] DirectoryModel successfully load model F:\gy77\mmdeploy\mmdeploy_models\yolox_s
[2022-08-01 12:33:53.928] [mmdeploy] [warning] [trt_net.cpp:24] TRTNet: Using an engine plan file across different models of devices is not recommended and is likely to affect performance or even cause errors.
[2022-08-01 12:33:54.503] [mmdeploy] [warning] [trt_net.cpp:24] TRTNet: TensorRT was linked against cuBLAS/cuBLAS LT 11.6.3 but loaded cuBLAS/cuBLAS LT 11.2.1
[2022-08-01 12:33:55.109] [mmdeploy] [warning] [trt_net.cpp:24] TRTNet: TensorRT was linked against cuBLAS/cuBLAS LT 11.6.3 but loaded cuBLAS/cuBLAS LT 11.2.1
load image cost time: 0.018s
mmdeploy_detector_apply cost time0.019s
cv::imshow cost time0.029s
图片推理结果:
![]() |
![]() |
|---|
MMDeploy部署实战系列【第六章】:将编译好的MMdeploy导入到自己的项目中 (C++)的更多相关文章
- 基于 abp vNext 和 .NET Core 开发博客项目 - Blazor 实战系列(六)
系列文章 基于 abp vNext 和 .NET Core 开发博客项目 - 使用 abp cli 搭建项目 基于 abp vNext 和 .NET Core 开发博客项目 - 给项目瘦身,让它跑起来 ...
- 【无私分享:ASP.NET CORE 项目实战(第六章)】读取配置文件(一) appsettings.json
目录索引 [无私分享:ASP.NET CORE 项目实战]目录索引 简介 在我们之前的Asp.net mvc 开发中,一提到配置文件,我们不由的想到 web.config 和 app.config,在 ...
- jQuery系列 第六章 jQuery框架事件处理
第六章 jQuery框架事件处理 JavaScript以事件驱动来实现页面的交互,其核心是以消息为基础,以事件来驱动.虽然利用传统的JavaScript事件处理方式也能够完成页面交互,但jQuery框 ...
- Sass与Compress实战:第六章
概要:介绍Compass如何让你从本地开发原型轻松转移到正产环境的网址或Web应用中. 本章内容: ● CSS精灵的历史和基本原则 ● Compass混合器让精灵自动化 ● 自定义精灵图片和CSS输出 ...
- 微服务从代码到k8s部署应有尽有系列(六、订单服务)
我们用一个系列来讲解从需求到上线.从代码到k8s部署.从日志到监控等各个方面的微服务完整实践. 整个项目使用了go-zero开发的微服务,基本包含了go-zero以及相关go-zero作者开发的一些中 ...
- 《GPU高性能编程CUDA实战》第六章 常量内存
▶ 本章介绍了常量内存的使用,并给光线追踪的一个例子.介绍了结构cudaEvent_t及其在计时方面的使用. ● 章节代码,大意是有SPHERES个球分布在原点附近,其球心坐标在每个坐标轴方向上分量绝 ...
- java并发编程实战:第六章----任务执行
任务:通常是一些抽象的且离散的工作单元.大多数并发应用程序都是围绕"任务执行"来构造的,把程序的工作分给多个任务,可以简化程序的组织结构便于维护 一.在线程中执行任务 任务的独立性 ...
- Python学习系列----第六章 数据结构
本章主要讲的是python中重要的四种数据结构,分别是列表.元组.字典和集合. 6.1 列表 list 是处理一组有序项目的数据结构,即你可以在一个列表中存储一个序列的项目.列表中的项目应该包括在方括 ...
- 《Spring Boot实战》笔记 (六章)
6.1 基本配置 ........................................................................................... ...
- GAN实战笔记——第六章渐进式增长生成对抗网络(PGGAN)
渐进式增长生成对抗网络(PGGAN) 使用 TensorFlow和 TensorFlow Hub( TFHUB)构建渐进式增长生成对抗网络( Progressive GAN, PGGAN或 PROGA ...
随机推荐
- mybaits 笔记2022年8月学习笔记
mybatis整理 前期准备 安装必要依赖: idea开发mybatis,如果学习测试,可以在一个直接建一个空白项目,如果是用spring boot,则建议用用boot的安装捆绑方式 核 心依赖 or ...
- ContextMenuManager右键z 右键菜单
常用软件 下载 https://files.cnblogs.com/files/pengchenggang/ContextMenuManager右键z-右键菜单.rar?t=1664158084
- hesitation 单词学习 犹豫 hes 就是 her 粘 助记单词 here
hesitation 单词学习 犹豫 hes 就是 her 粘 助记单词 here hes + itation(ite + ate + ion) hesitation 美: [ˌhezɪˈteɪʃ(ə ...
- git svn 提交代码日志填写规范 BUG NEW DEL CHG TRP gitz 日志z
git svn 提交代码日志填写规范 BUG NEW DEL CHG TRP gitz 日志z
- Dreamweaver基础教程:学习HTML
目录 HTML简介 HTML实例 HTML 标签 HTML元素 HTML 属性 HTML网页结构 <!DOCTYPE> 声明 HTML 基础 HTML 标题 HTML 段落 HTML 链接 ...
- Asp .Net Core 系列:Asp .Net Core 集成 Hangfire+MySQL
简介 https://www.hangfire.io/ 在 .NET 和 .NET Core 应用程序中执行后台处理的简单方法,无需 Windows 服务或单独的进程. Hangfire 是一个开源的 ...
- TTS 擂台: 文本转语音模型的自由搏击场
对文本转语音 (text-to-speech, TTS) 模型的质量进行自动度量非常困难.虽然评估声音的自然度和语调变化对人类来说是一项微不足道的任务,但对人工智能来说要困难得多.为了推进这一领域的发 ...
- 云VR的未来发展方向
随着元宇宙元年的到来,VR正呈现出蓬勃的发展势头.然而,更好的用户体验大多依赖于高性能PC或主机进行本地渲染,这使得用户的VR消费成本更高,在一定程度上影响了产业发展,成为业界亟待解决的问题. 的确, ...
- JS(循环)
一 for循环 在程序中,一组被重复执行的语句被称之为循环体,能否继续重复执行,取决于循环的终止条件.由循环体及循环的终止条件组成的语句,被 称之为循环语句 1 语法结构 for循环主要用于把某些代码 ...
- PyQt5 GUI编程
一.PyQt5简介 PyQt5是一个用于创建图形用户界面(GUI)应用程序的跨平台工具集,它将Qt库(广泛用于C++编程语言中创建丰富的GUI应用程序)的功能包装给Python使用者.PyQt5是由R ...

