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 ...
随机推荐
- 数据安全刻不容缓,国产智能化厂商首获SOC 2鉴证报告有何意义?
数据安全刻不容缓,国产智能化厂商首获SOC 2鉴证报告有何意义? 了解SOC 2与ISO 27001的区别,你就知道SOC 2对智能自动化厂商的意义了 文/王吉伟 要问当前组织对于数字化转型的最大顾虑 ...
- Android APP 渗透测试---总结
1.apk反编译得到源代码 使用编译软件 dex2gar 和 jdgui.jar 对Android APP软件进行反编译.具体步骤如下: (1)首先将APK文件后缀改为zip并解压,得到其中的clas ...
- Dreamweaver基础教程:学习HTML
目录 HTML简介 HTML实例 HTML 标签 HTML元素 HTML 属性 HTML网页结构 <!DOCTYPE> 声明 HTML 基础 HTML 标题 HTML 段落 HTML 链接 ...
- 基于stm32H730的解决方案开发之SD卡的读写调试
一 概述 在嵌入式小系统领域,SD卡存储是一个非常重要的功能.可从难度上,它又是非常难的.因为它涉及到两个大的功能点,一个是文件系统,这个难度非一般.另外一个是sd卡的底层驱动.涉及到的接口多,所以也 ...
- git clone error: RPC failed; curl 18 transfer closed with outstanding read data remaining
备忘 git clone比较大的工程时,出现这种错误:error: RPC failed; curl 18 transfer closed with outstanding read data rem ...
- 逆向通达信Level-2 续九 (无帐号打开itrend研究版)
此itrend研究版的版本比较旧. 本篇演示三图,用例进程同为0x4970. 1. itrend不支持脱机,游客登陆.没有帐号不能打开.现在以无帐号打开. 2. itrend支持高清,当打开主界面就会 ...
- 简洁版docker跑mongo
参考,欢迎点击原文:https://www.runoob.com/docker/docker-install-mongodb.html(菜鸟) 以下是拉取docker镜像并运行起来 docker pu ...
- PAT 甲级【1013 Battle Over Cities】
本题就是dfs.连通图个数-2: 但是java慢,最后一个case 超时 import java.io.*; import java.util.HashSet; import java.util.Se ...
- App磁盘沙盒工具实践
目录介绍 01.磁盘沙盒的概述 1.1 项目背景说明 1.2 沙盒作用 1.3 设计目标 02.Android存储概念 2.1 存储划分介绍 2.2 机身内部存储 2.3 机身外部存储 2.4 SD卡 ...
- 记录-Vue.js模板编译过程揭秘:从模板字符串到渲染函数
这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助 Vue.js是一个基于组件化和响应式数据流的前端框架.当我们在Vue中编写模板代码时,它会被Vue编译器处理并转换为可被浏览器解析的Jav ...

