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 ...
随机推荐
- 一款开源、免费、跨平台的Redis可视化管理工具
前言 经常有小伙伴在技术群里问:有什么好用的Redis可视化管理工具推荐的吗?, 今天大姚给大家分享一款我一直在用的开源.免费(MIT License).跨平台的Redis可视化管理工具:Anothe ...
- java后端数据接收
restful风格 @RequestMapping("/getTeacherPage/{current}/{limit}") public List<WorkOrder> ...
- snippet n. 小片, 片断, 摘录 单词记忆
snippet 助记:snip[剪断] + -et小词后缀. 关键是 snip 怎么记忆 snip : 拟声词,模仿剪断东西的声音. 助记单词 slip 滑 根据字母 n是done的缩写,可以 想成 ...
- 阿里云Python UDP Server和client基础教程
壹: socket通信是常用的一种通信方式,熟练掌握,快速的入戏,是一个程序员必备的素质. 贰: 注意:udp和tcp的套接字: 服务端代码: #!/usr/bin/env python3 # -*- ...
- 基于BES2300芯片的开源DSP开发平台简述
一 什么是开源DSP平台 所谓的开源DSP平台,就是软硬件全部开发接口,开发者可以在上面做DSP算法验证和算法开发.基于目前科研机构缺少开源的微型数字信号处理的情况,我们把bes2300的代码做了优化 ...
- 模板函数中的const
所有讨论都是底层const指针或引用,顶层const不会传递进模板. 模板中有const,不管传进来是否是const,T都是非const类型. template<typename T> v ...
- [https://atcoder.jp/contests/abc234/tasks/abc234_d Prefix K-th Max] 最小堆实现
Problem Statement Given are a permutation P=(P_1,P_2,\ldots,P_N)P=(P1,P2,-,PN) of (1,2,\ldots,N)( ...
- drf(JWT认证)
一. jwt实现过程 1. 构建jwt过程 第一: 用户提交用户名和密码给服务端,如果登录成功,使用jwt创建一个token,并给用户返回 eyJ0eXAiOiJqd3QiLCJhbGciOiJIUz ...
- SpringBoot集成drools
目录 1.背景 2.需求 3.实现 3.1 引入jar包 3.2 编写drools配置类 3.3 编写Person对象 3.4 编写drl文件 3.5 编写kmodule.xml文件 3.6 编写Co ...
- C# Winform 图片 Base64 转换
//图片 转为 base64编码的文本 private void button1_Click(object sender, EventArgs e) { OpenFileDialog dlg = ne ...