分割一切模型 Fast SAM C++推理部署---TensorRT (有核心代码)

Fast SAM C++推理部署—TensorRT
核心源代码在结尾处有获取方式
晓理紫

0 XX开局一张图,剩下…

在这里插入图片描述

1 为什么需要trt部署

主要是在GPU上推理可以获得更高的推理速度。可与onnxruntim推理向比较一下

对比视频

2 TensorRt部署

2.1 环境与条件

  • 需要配置TensorRt相关环境

这个就需要有显卡,安装驱动,CUDA以及TensorRT

  • 需要把原始权重模型转为trt模型

2.2 trt模型转换

trt模型转换有多种方式,本文采用的是先把pt模型转成onnx模型(),再把onnx通过trtexec工具进行转换。这里假设已经有onxx模型,转换命令如下:

trtexec --onnx=fastsam.onnx --saveEngine=fasrsam.engine 

注意: trtexec -h查看帮助,转fp16或者int8等参数

2.3 部署核心代码

模型转换完成以后,剩下的就是部署推理。部署推理里面最为重要也是最难搞的是数据解析部分。其中模型加载是很标准的流程,当然我这里不一定是标准的。

  • 加载模型并初始化核心代码
  std::ifstream file(engine_file_path, std::ios::binary);assert(file.good());file.seekg(0, std::ios::end);auto size = file.tellg();std::ostringstream fmt;file.seekg(0, std::ios::beg);char *trtModelStream = new char[size];assert(trtModelStream);file.read(trtModelStream, size);file.close();initLibNvInferPlugins(&this->gLogger, "");this->runtime = nvinfer1::createInferRuntime(this->gLogger);assert(this->runtime != nullptr);this->engine = this->runtime->deserializeCudaEngine(trtModelStream, size);assert(this->engine != nullptr);this->context = this->engine->createExecutionContext();assert(this->context != nullptr);cudaStreamCreate(&this->stream);const nvinfer1::Dims input_dims =this->engine->getBindingDimensions(this->engine->getBindingIndex(INPUT));this->in_size = get_size_by_dims(input_dims);CHECK(cudaMalloc(&this->buffs[0], this->in_size * sizeof(float)));this->context->setBindingDimensions(0, input_dims);const int32_t output0_idx = this->engine->getBindingIndex(OUTPUT0);const nvinfer1::Dims output0_dims =this->context->getBindingDimensions(output0_idx);this->out_sizes[output0_idx - NUM_INPUT].first =get_size_by_dims(output0_dims);this->out_sizes[output0_idx - NUM_INPUT].second =DataTypeToSize(this->engine->getBindingDataType(output0_idx));const int32_t output1_idx = this->engine->getBindingIndex(OUTPUT1);const nvinfer1::Dims output1_dims =this->context->getBindingDimensions(output1_idx);this->out_sizes[output1_idx - NUM_INPUT].first =get_size_by_dims(output1_dims);this->out_sizes[output1_idx - NUM_INPUT].second =DataTypeToSize(this->engine->getBindingDataType(output1_idx));const int32_t Reshape_1252_idx = this->engine->getBindingIndex(Reshape_1252);const nvinfer1::Dims Reshape_1252_dims =this->context->getBindingDimensions(Reshape_1252_idx);this->out_sizes[Reshape_1252_idx - NUM_INPUT].first =get_size_by_dims(Reshape_1252_dims);this->out_sizes[Reshape_1252_idx - NUM_INPUT].second =DataTypeToSize(this->engine->getBindingDataType(Reshape_1252_idx));const int32_t Reshape_1271_idx = this->engine->getBindingIndex(Reshape_1271);const nvinfer1::Dims Reshape_1271_dims =this->context->getBindingDimensions(Reshape_1271_idx);this->out_sizes[Reshape_1271_idx - NUM_INPUT].first =get_size_by_dims(Reshape_1271_dims);this->out_sizes[Reshape_1271_idx - NUM_INPUT].second =DataTypeToSize(this->engine->getBindingDataType(Reshape_1271_idx));const int32_t Concat_1213_idx = this->engine->getBindingIndex(Concat_1213);const nvinfer1::Dims Concat_1213_dims =this->context->getBindingDimensions(Concat_1213_idx);this->out_sizes[Concat_1213_idx - NUM_INPUT].first =get_size_by_dims(Concat_1213_dims);this->out_sizes[Concat_1213_idx - NUM_INPUT].second =DataTypeToSize(this->engine->getBindingDataType(Concat_1213_idx));const int32_t OUTPUT1167_idx = this->engine->getBindingIndex(OUTPUT1167);const nvinfer1::Dims OUTPUT1167_dims =this->context->getBindingDimensions(OUTPUT1167_idx);this->out_sizes[OUTPUT1167_idx - NUM_INPUT].first =get_size_by_dims(OUTPUT1167_dims);this->out_sizes[OUTPUT1167_idx - NUM_INPUT].second =DataTypeToSize(this->engine->getBindingDataType(OUTPUT1167_idx));for (int i = 0; i < NUM_OUTPUT; i++) {const int osize = this->out_sizes[i].first * out_sizes[i].second;CHECK(cudaHostAlloc(&this->outputs[i], osize, 0));CHECK(cudaMalloc(&this->buffs[NUM_INPUT + i], osize));}if (warmup) {for (int i = 0; i < 10; i++) {size_t isize = this->in_size * sizeof(float);auto *tmp = new float[isize];CHECK(cudaMemcpyAsync(this->buffs[0], tmp, isize, cudaMemcpyHostToDevice,this->stream));this->xiaoliziinfer();}}

模型加载以后,就可以送入数据进行推理

  • 送入数据并推理
  float height = (float)image.rows;float width = (float)image.cols;float r = std::min(INPUT_H / height, INPUT_W / width);int padw = (int)std::round(width * r);int padh = (int)std::round(height * r);if ((int)width != padw || (int)height != padh) {cv::resize(image, tmp, cv::Size(padw, padh));} else {tmp = image.clone();}float _dw = INPUT_W - padw;float _dh = INPUT_H - padh;_dw /= 2.0f;_dh /= 2.0f;int top = int(std::round(_dh - 0.1f));int bottom = int(std::round(_dh + 0.1f));int left = int(std::round(_dw - 0.1f));int right = int(std::round(_dw + 0.1f));cv::copyMakeBorder(tmp, tmp, top, bottom, left, right, cv::BORDER_CONSTANT,PAD_COLOR);cv::dnn::blobFromImage(tmp, tmp, 1 / 255.f, cv::Size(), cv::Scalar(0, 0, 0),true, false, CV_32F);CHECK(cudaMemcpyAsync(this->buffs[0], tmp.ptr<float>(),this->in_size * sizeof(float), cudaMemcpyHostToDevice,this->stream));this->context->enqueueV2(buffs.data(), this->stream, nullptr);for (int i = 0; i < NUM_OUTPUT; i++) {const int osize = this->out_sizes[i].first * out_sizes[i].second;CHECK(cudaMemcpyAsync(this->outputs[i], this->buffs[NUM_INPUT + i], osize,cudaMemcpyDeviceToHost, this->stream));}cudaStreamSynchronize(this->stream);

推理以后就可以获取数据并进行解析

  • 数据获取
cv::Mat matData(37, OUTPUT0w, CV_32F, pdata);matVec.push_back(matData);float *pdata1 = nullptr;pdata1 = static_cast<float *>(this->outputs[2]);if (pdata1 == nullptr) {return;}cv::Mat matData1(105, OUTPUT1w * OUTPUT1w, CV_32F, pdata1);matVec.push_back(matData1);float *pdata2 = nullptr;pdata2 = static_cast<float *>(this->outputs[3]);if (pdata2 == nullptr) {return;}cv::Mat matData2(105, Reshape_1252w * Reshape_1252w, CV_32F, pdata2);matVec.push_back(matData2);float *pdata3 = nullptr;pdata3 = static_cast<float *>(this->outputs[4]);if (pdata3 == nullptr) {return;}cv::Mat matData3(105, Reshape_1271w * Reshape_1271w, CV_32F, pdata3);matVec.push_back(matData3);float *pdata4 = nullptr;pdata4 = static_cast<float *>(this->outputs[1]);if (pdata4 == nullptr) {return;}cv::Mat matData4(Concat_1213w, 32, CV_32F, pdata4);matVec.push_back(matData4);float *pdata5 = nullptr;pdata5 = static_cast<float *>(this->outputs[0]);if (pdata5 == nullptr) {return;}cv::Mat matData5(32, OUTPUT1167w * OUTPUT1167w, CV_32F, pdata5);matVec.push_back(matData5);
  • 数据解析

首先是对数据进行分割处理并进行NMS获取box、lab以及mask相关信息

cv::Mat box;
cv::Mat cls;
cv::Mat mask;
box = temData.colRange(0, 4).clone();
cls = temData.colRange(4, 5).clone();
mask = temData.colRange(5, temData.cols).clone();
cv::Mat j = cv::Mat::zeros(cls.size(), CV_32F);
cv::Mat dst;
cv::hconcat(box, cls, dst); // dst=[A  B]
cv::hconcat(dst, j, dst);
cv::hconcat(dst, mask, dst);
std::vector<float> scores;
std::vector<cv::Rect> boxes;
pxvec = dst.ptr<float>(0);
for (int i = 0; i < dst.rows; i++) {pxvec = dst.ptr<float>(i);boxes.push_back(cv::Rect(pxvec[0], pxvec[1], pxvec[2], pxvec[3]));scores.push_back(pxvec[4]);
}
std::vector<int> indices;
xiaoliziNMSBoxes(boxes, scores, conf_thres, iou_thres, indices);
cv::Mat reMat;
for (int i = 0; i < indices.size() && i < max_det; i++) {int index = indices[i];reMat.push_back(dst.rowRange(index, index + 1).clone());
}
box = reMat.colRange(0, 6).clone();
xiaolizixywh2xyxy(box);
mask = reMat.colRange(6, reMat.cols).clone();

其次是获取mask相关数据

  for (int i = 0; i < bboxes.rows; i++) {pxvec = bboxes.ptr<float>(i);cv::Mat dest, mask;cv::exp(-maskChannels[i], dest);dest = 1.0 / (1.0 + dest);dest = dest(roi);cv::resize(dest, mask, frmae.size(), cv::INTER_LINEAR);cv::Rect roi(pxvec[0], pxvec[1], pxvec[2] - pxvec[0], pxvec[3] - pxvec[1]);cv::Mat temmask = mask(roi);cv::Mat boxMask = cv::Mat(frmae.size(), mask.type(), cv::Scalar(0.0));float rx = std::max(pxvec[0], 0.0f);float ry = std::max(pxvec[1], 0.0f);for (int y = ry, my = 0; my < temmask.rows; y++, my++) {float *ptemmask = temmask.ptr<float>(my);float *pboxmask = boxMask.ptr<float>(y);for (int x = rx, mx = 0; mx < temmask.cols; x++, mx++) {pboxmask[x] = ptemmask[mx] > 0.5 ? 1.0 : 0.0;}}vremat.push_back(boxMask);}

最后是画出相关信息

cv::Mat bbox = vremat[0];float *pxvec = bbox.ptr<float>(0);for (int i = 0; i < bbox.rows; i++) {pxvec = bbox.ptr<float>(i);cv::rectangle(image, cv::Point(pxvec[0], pxvec[1]),cv::Point(int(pxvec[2]), int(pxvec[3])),cv::Scalar(0, 0, 255), 2);}for (int i = 1; i < vremat.size(); i++) {cv::Mat mask = vremat[i];int indx = (rand() % (80 - 0)) + 0;for (int y = 0; y < mask.rows; y++) {const float *mp = mask.ptr<float>(y);uchar *p = image.ptr<uchar>(y);for (int x = 0; x < mask.cols; x++) {if (mp[x] == 1.0) {p[0] = cv::saturate_cast<uchar>(p[0] * 0.5 + COLORS[indx][0] * 0.5);p[1] = cv::saturate_cast<uchar>(p[1] * 0.5 + COLORS[indx][1] * 0.5);p[2] = cv::saturate_cast<uchar>(p[2] * 0.5 + COLORS[indx][2] * 0.5);}p += 3;}}}

3 核心代码

扫一扫,关注并回复fastsamtrt获取核心代码

在这里插入图片描述

晓理紫爱学习爱记录爱分享!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/33842.shtml

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

相关文章

【数字化处理】仿生假体控制中肌电信号的数字化处理研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

FileZilla Server安装配置使用说明

作者&#xff1a;John 链接&#xff1a;https://www.zhihu.com/question/20577011/answer/2360828234 来源&#xff1a;知乎 第一步&#xff1a;右键点击”立即下载“ 第二步&#xff1a;服务器端点击&#xff0c;“windows平台”版本 第三步&#xff1a;这个安装最新的“Fi…

探究使用HTTP代理ip后无法访问网站的原因与解决方案

目录 访问网站的原理是什么 1. DNS解析 2. 建立TCP连接 3. 发送HTTP请求&#xff1a; 4. 服务器响应&#xff1a; 5. 浏览器渲染&#xff1a; 6. 页面展示&#xff1a; 使用代理IP后访问不了网站&#xff0c;有哪些方面的原因 1. 代理IP的可用性&#xff1a; 2. 代理…

【ARM64 常见汇编指令学习 15 -- ARM 标志位的学习】

文章目录 ARM 标志位介绍Zero Condition flag(零标志位)零标志位判断实例 上篇文章&#xff1a;ARM64 常见汇编指令学习 14 – ARM 汇编 .balign,.balignw,.balign 伪指令学习 下篇文章&#xff1a;ARM64 常见汇编指令学习 16 – ARM64 SMC 指令 ARM 标志位介绍 在ARM架构中&am…

PLL 的 verilog 实现

锁相环&#xff08;PLL&#xff09;是一种常用的频率、相位追踪算法&#xff0c;在信号解调、交流并网等领域有着广泛的应用。本文对全数字锁相环的原理进行介绍&#xff0c;随后给出 verilog 实现及仿真。 PLL 锁相原理 锁相环结构如下图所示&#xff0c;主要由鉴相器、环路滤…

设计模式之简单工厂模式

一、概述 定义一个用于创建对象的接口&#xff0c;让子类决定实例化哪一个类。FactoryMethod使一个类的实例化延迟到其子类。 简单工厂模式&#xff1a;又叫做静态工厂方法模式&#xff0c;是由一个工厂对象决定创建出哪一种产品类的实例。 二、适用性 1.当一个类不知道它所…

CSS 中的优先级规则是怎样的?

聚沙成塔每天进步一点点 ⭐ 专栏简介⭐内联样式&#xff08;Inline Styles&#xff09;⭐ID 选择器&#xff08;ID Selectors&#xff09;⭐类选择器、属性选择器和伪类选择器&#xff08;Class, Attribute, and Pseudo-class Selectors&#xff09;⭐元素选择器和伪元素选择器…

Kafka 概述

Kafka 为什么需要消息队列&#xff08;MQ&#xff09;使用消息队列的好处&#xff08;1&#xff09;解耦&#xff08;2&#xff09;可恢复性&#xff08;3&#xff09;缓冲&#xff08;4&#xff09;灵活性 & 峰值处理能力&#xff08;5&#xff09;异步通信 消息队列的两…

掌握Python的X篇_30_使用python解析网页HTML

本篇将会介绍beutifulsoup4模块&#xff0c;可以用于网络爬虫、解析HTML和XML&#xff0c;对于没有接触过前端&#xff0c;不了解HTML是如何工作的&#xff0c;需要先解释一下什么事HTML。 1. HTML 网页中的各种布局等的背后都是非常简单的纯文本格式&#xff0c;那种格式称为…

【杨辉三角的两种解法——(超级详细)】

杨辉三角 1.杨辉三角简介&#x1f575;️ 杨辉三角&#xff0c;是二项式系数在三角形中的一种几何排列。在欧洲&#xff0c;这个表叫做帕斯卡三角形。帕斯卡&#xff08;1623----1662&#xff09;是在1654年发现这一规律的&#xff0c;比杨辉要迟393年&#xff0c;比贾宪迟600…

7.3 详解NiN模型--首次使用多层感知机(1x1卷积核)替换掉全连接层的模型

一.前提知识 多层感知机&#xff1a;由一个输入层&#xff0c;一个或多个隐藏层和一个输出层组成。&#xff08;至少有一个隐藏层&#xff0c;即至少3层&#xff09; 全连接层&#xff1a;是MLP的一种特殊情况&#xff0c;每个节点都与前一层的所有节点连接&#xff0c;全连接…

设计模式(6)原型模式

一、介绍 Java中自带的原型模式是clone()方法。该方法是Object的方法&#xff0c;native类型。他的作用就是将对象的在内存的那一块内存数据一字不差地再复制一个。我们写简单类的时候只需要实现Cloneable接口&#xff0c;然后调用Object::clone方法就可实现克隆功能。这样实现…

emqx-5.1.4开源版使用记录

emqx-5.1.4开源版使用记录 windows系统安装eqmx 去官网下载 emqx-5.1.4-windows-amd64.zip&#xff0c;然后找个目录解压 进入bin目录,执行命令启动emqx 执行命令 emqx.cmd start使用emqx 访问内置的web管理页面 浏览器访问地址 http://localhost:18083/#/dashboard/overv…

猿人学刷题系列(第一届比赛)——第二题( js 混淆 - 动态cookie 1)

题目&#xff1a;提取全部5页发布日热度的值&#xff0c;计算所有值的加和 地址&#xff1a;https://match.yuanrenxue.cn/match/2 思路分析 本题我们会简单说一下两种不同的方式去处理&#xff0c;一种是不还原混淆代码直接从源代码硬扣生成逻辑&#xff0c;另一种则是还原…

数据通信——VRRP

引言 之前把实验做了&#xff0c;结果发现我好像没有写过VRRP的文章&#xff0c;连笔记都没记过。可能是因为对STP的记忆&#xff0c;导致现在都没忘太多。 一&#xff0c;什么是VRRP VRRP全名是虚拟路由冗余协议&#xff0c;虚拟路由&#xff0c;看名字就知道这是运行在三层接…

C语言三子棋小游戏--数组的应用

注&#xff1a;在最后面&#xff0c;完整源码会以两种形式展现。在讲解时&#xff0c;以三个源文件的形式。 前言&#xff1a;三子棋&#xff0c;顾名思义&#xff0c;就是三个子连在一起就可以胜出。在本节我们要介绍的三子棋模式是这样子的&#xff1a;在键盘输入坐标&#x…

HTML详解连载(3)

HTML详解连载&#xff08;3&#xff09; 专栏链接 [link](http://t.csdn.cn/xF0H3)下面进行专栏介绍 开始喽表单作用使用场景 input标签基本使用示例type属性值以及说明 input标签占位文本示例注意 单选框 radio代码示例 多选框-checkbox注意代码示例 文本域作用标签&#xff1…

【前端 | CSS】flex布局

基本概念 Flexible模型&#xff0c;通常被称为 flexbox&#xff0c;是一种一维的布局模型。它给 flexbox 的子元素之间提供了强大的空间分布和对齐能力 我们说 flexbox 是一种一维的布局&#xff0c;是因为一个 flexbox 一次只能处理一个维度上的元素布局&#xff0c;一行或者…

R语言4_安装BayesSpace

环境Ubuntu22/20, R4.1 你可能会报错说你的R语言版本没有这个库&#xff0c;但其实不然。这是一个在Bioconductor上的库。 同时我也碰到了这个问题&#xff0c;ERROR: configuration failed for package systemfonts’等诸多类似问题&#xff0c;下面的方法可以一并解决。 第…

Mr. Cappuccino的第61杯咖啡——Spring之BeanPostProcessor

Spring之BeanPostProcessor 概述基本使用项目结构项目代码运行结果源代码 常用处理器项目结构项目代码执行结果 概述 BeanPostProcessor&#xff1a;Bean对象的后置处理器&#xff0c;负责对已创建好的bean对象进行加工处理&#xff1b; BeanPostProcessor中的两个核心方法&am…