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 ...
随机推荐
- vmware虚拟机 CentOS出现连接被拒--ssh:connect to host localzly port 22: Connection refused
一.问题现象: 错误提示如下:CentOS出现连接被拒--ssh:connect to host localzly (自己的主机名)port 22: Connection refused 二.问题原因 ...
- 【架构师视角系列】QConfig配置中心系列之Server端(三)
声明 原创文章,转载请标注.https://www.cnblogs.com/boycelee/p/17993697 <码头工人的一千零一夜>是一位专注于技术干货分享的博主,追随博主的文章, ...
- 文心一言 VS 讯飞星火 VS chatgpt (210)-- 算法导论16.1 1题
一.根据递归式(16.2)为活动选择问题设计一个动态规划算法.算法应该按前文定义计算最大兼容活动集的大小 c[i,j]并生成最大集本身.假定输入的活动已按公式(16.1)排好序.比较你的算法和GREE ...
- RIPEMD算法:多功能哈希算法的瑰宝
一.RIPEMD算法的起源与历程 RIPEMD(RACE Integrity Primitives Evaluation Message Digest)算法是由欧洲研究项目RACE发起,由Hans D ...
- 软件架构(四)单体架构(Monolithic Architecture)
系列目录 软件架构(一)概览 软件架构(二)编程语言的历史 软件架构(三)名词解释:架构.设计.风格.模式 软件架构(四)单体架构(Monolithic Architecture) 软件架构(五)分层 ...
- 2023山东省“技能兴鲁”职业技能大赛-学生组初赛wp
PWN pwn1 c++ pwn,cin 直接相当于 gets 了,程序有后门,保护基本没开,在 change 的最后一个输入点改掉返回地址为后门地址即可 from pwn import * cont ...
- 关于debian11无法安装星火商店的解决方法
#!/bin/bash if [ "$(id -u)" != "0" ] then echo "请确保你使用root权限启动此脚本" exi ...
- Linux IPC(进程间通信)摘要(信号灯,共享内存,消息队列,管道)(一)
PS:要转载请注明出处,本人版权所有. PS: 这个只是基于<我自己>的理解, 如果和你的原则及想法相冲突,请谅解,勿喷. 前置说明 本文作为本人csdn blog的主站的备份.(Bl ...
- 快速排序——Java
快排的思想想必大家都懂,前后两个指针,向中间靠拢.我这个partition函数能保证所有相同的数都被比较一次,靠拢在一起. 代码: public class Main { public static ...
- webpack 项目接入Vite的通用方案介绍(下)
愿景 希望通过此系列文章,能给读者提供一个存/增量项目接入Vite的点子,起抛砖引玉的作用,减少这方面能力的建设成本 在阐述过程中同时也会逐渐完善webpack-vite-serve这个工具 读者可直 ...

