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

Fast SAM C++推理部署—onnxruntime
核心源代码在结尾处
晓理紫

0 XX开局一张图,剩下…

在这里插入图片描述
本文记录只为日后更好学习

1 Fast SAM 简介

Fast SAM是仅使用SAM作者发布的SA-1B数据集的2%进行训练的CNN任意分割模型。FastSAM的性能与SAM方法相当,运行速度提高了50倍。
在这里插入图片描述

在这里插入图片描述

2 onnxruntime部署

2.1 环境与条件

  • 需要配置onnxruntime相关环境

这个就网上自行解决

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

2.2 onnx模型转换

本文参考进行转换,在转换过程中需要把dynamic_axes设置为None,采用静态维度进行,在核心源码中我们提供了640以及1024大小的onnx模型。相关核心代码如下:

torch.onnx.export(model, img,  output_model_path,export_params=True,       opset_version=11,        do_constant_folding=True,  input_names = ['images'],  output_names = output_names,dynamic_axes=None)

注意:dynamic_axes=None这个最为关键,当然你也可以试试设置为dynamic

2.3 部署核心代码

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

  • 加载模型核心代码
  sessionOptions.SetExecutionMode(ORT_SEQUENTIAL);sessionOptions.EnableCpuMemArena();sessionOptions.SetIntraOpNumThreads(1);sessionOptions.SetGraphOptimizationLevel(ORT_ENABLE_BASIC);ort_session = new Session(env, model_path.data(), sessionOptions);size_t numInputNodes = ort_session->GetInputCount();size_t numOutputNodes = ort_session->GetOutputCount();Ort::AllocatorWithDefaultOptions allocator;for (int i = 0; i < numInputNodes; i++) {this->input_names.emplace(ort_session->GetInputNameAllocated(i, allocator));Ort::TypeInfo input_type_info = ort_session->GetInputTypeInfo(i);auto input_tensor_info = input_type_info.GetTensorTypeAndShapeInfo();auto input_dims = input_tensor_info.GetShape();input_node_dims.push_back(input_dims);}for (int i = 0; i < numOutputNodes; i++) {this->output_names.emplace(ort_session->GetOutputNameAllocated(i, allocator));Ort::TypeInfo output_type_info = ort_session->GetOutputTypeInfo(i);auto output_tensor_info = output_type_info.GetTensorTypeAndShapeInfo();auto output_dims = output_tensor_info.GetShape();output_node_dims.push_back(output_dims);}this->inpHeight = input_node_dims[0][2];this->inpWidth = input_node_dims[0][3];input_names__[0] = input_names->get();

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

  • 推理
  xiaoliziprocessImage(frame, tmp);this->xiaoliziNormalize_(tmp);array<int64_t, 4> input_shape_{1, 3, this->inpHeight, this->inpWidth};auto allocator_info =MemoryInfo::CreateCpu(OrtDeviceAllocator, OrtMemTypeCPU);Value input_tensor_ = Value::CreateTensor<float>(allocator_info, input_image_.data(), input_image_.size(),input_shape_.data(), input_shape_.size());vector<Value> ort_outputs = ort_session->Run(RunOptions{nullptr}, input_names__, &input_tensor_, 1, output_names__,sizeof(output_names__) / sizeof(char *)); // 开始推理

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

  • 数据获取
  std::vector<cv::Mat> matVec;float *pdata = nullptr;pdata = ort_outputs[0].GetTensorMutableData<float>();if (pdata == nullptr) {std::cout << "pdata is nullptr" << std::endl;return;}cv::Mat matData(37, OUTPUT0w, CV_32F, pdata);matVec.push_back(matData);float *pdata5 = nullptr;pdata5 = ort_outputs[5].GetTensorMutableData<float>();if (pdata5 == nullptr) {std::cout << "pdata or pdata5 is nullptr" << std::endl;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 核心代码

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

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

支付宝五福53张自动领取程序 v2021

简介&#xff1a; 临近过年&#xff0c;身边的朋友们都开始参加支付宝一年一度的集五福活动了&#xff01;今天小编带来的这款支付宝五福53张自动领取程序能够帮助集福的朋友们更加轻松地完成任务&#xff0c;让用户一键完成53个任务并自动获取福卡&#xff0c;非常方便&#…

2920集五福_2020年支付宝集五福攻略

支付宝2020扫福活动在今天也就是1月13日开始啦&#xff0c;听说&#xff0c;居然有2.4万人集齐了吗&#xff0c;也太快了吧&#xff01;有人好奇&#xff0c;2020年支付宝集五福活动规则&#xff0c;有什么新玩法。不过不少小伙伴们比较关心的是2020每天可以扫几张福&#xff1…

2020 春节集五福最详细收集攻略

本文由葡萄城技术团队于博客原创并首发 转载请注明出处&#xff1a;葡萄城官网&#xff0c;葡萄城为开发者提供专业的开发工具、解决方案和服务&#xff0c;赋能开发者。 一年一度的支付宝集五福活动已经开始了&#xff0c;不知从什么时候开始&#xff0c;集五福已经成为了惯例…

已有一万名快手用户集齐好运卡获得六六六早鸟红包,还可再分一亿

“谁要来沾幸运的吗&#xff01;我已经集齐了&#xff01;“ “天呐&#xff0c;马上就要到一万人&#xff01;谁能让我沾一沾幸运&#xff01;“ 伴随着超话里网友们热火朝天的讨论&#xff0c;快手「集好运中国福」活动也终于迎来了第1万个集齐五张好运卡的幸运用户。 据了…

支付宝集五福可以开“外挂”? 70万人秒集齐!

点击上方[全栈开发者社区]→右上角[...]→[设为星标⭐] 2月1日零点&#xff0c;2021年支付宝集五福活动正式开始&#xff0c;打响“年味”第一枪&#xff01; 我稍微看了看&#xff0c;今年的集福难度更低&#xff0c;生怕你集不全似的给各种“外挂”&#xff0c;开始13小时&am…

2021支付宝集五福最新最全攻略:万能福沾沾福敬业福

五福背后的 Web 3D 引擎 Oasis Engine 正式开源 五福还是一如既往&#xff0c;独乐乐不如众乐乐 分享一波攻略顺便晒晒我的会不会被打 骚套路 1. 敬业福套路 可以5个小朋友建个小群&#xff0c;分享套卡互相领取 2. 万能福套路 3. 沾沾福套路 分享福卡也有机会得沾沾 …

《Linux从练气到飞升》No.12 Linux进程概念

&#x1f57a;作者&#xff1a; 主页 我的专栏C语言从0到1探秘C数据结构从0到1探秘Linux菜鸟刷题集 &#x1f618;欢迎关注&#xff1a;&#x1f44d;点赞&#x1f64c;收藏✍️留言 &#x1f3c7;码字不易&#xff0c;你的&#x1f44d;点赞&#x1f64c;收藏❤️关注对我真的…

RT-Thread智能音箱音频应用实践

国内智能音箱的问世早于国外&#xff0c;但由于国内对智能化概念普及程度较低&#xff0c;初期智能音箱并没有受到很多关注。但近几年国内智能音箱行业经历了从百花齐放到三足鼎立的发展阶段&#xff0c;来自RT-Thread的黄天翔将从占据主流市场的三个厂商脱颖而出的秘诀开始&am…

智能音箱技术概览

目前的智能音箱多基于语音控制&#xff0c;其基本交互流程可以用图1 概括&#xff1a; 1&#xff09;用户通过自然语言向音箱提出服务请求或问题 2&#xff09;音箱拾取用户声音&#xff08;音箱本地完成&#xff09;并分析&#xff08;一般在服务器端完成&#xff09; 3&#…

揭秘智能音箱里那些神秘的声学技术

音箱行业有着悠久的历史&#xff0c;但是在过去十多年里&#xff0c;传统的音箱行业面临着极大的市场困境&#xff0c;例如蓝牙音箱刚出现各个厂商便直接杀成了一片红海。而2015年随着智能音箱的涌现&#xff0c;特别是亚马逊的Echo、京东的叮咚、阿里的小飞&#xff0c;不仅对…

智能家居控制系统MECOOL KA1智能音响

MECOOL KA1是智能音箱和4K安卓电视流媒体设备的结合。该设备采用Amlogic S905Y4 SoC四核ARM Cortex -A35处理器&#xff0c;支持远场语音和免提电视控制。 MECOOL KA1通过ART&#xff08;谷歌智能语音测试&#xff09; ART 旨在验证集成了 Google 助理的设备的助理功能。要被…

AI智能音箱五大功能中应用的数字功放芯片

AI智能音箱多基于语音控制&#xff0c;其基本交互流程可以用下图概括&#xff1a;1&#xff09;用户通过自然语言向音箱提出服务请求或问题 2&#xff09;音箱拾取用户声音&#xff08;音箱本地完成&#xff09;并分析&#xff08;一般在服务器端完成&#xff09;3&#xff09;…

Talk | ICCV‘23清华大学刘世隆:From Detection to Grounding-迈向更强的开集目标检测

本期为TechBeat人工智能社区第521期线上Talk&#xff01; 北京时间8月10日(周四)20:00&#xff0c;清华大学博士生—刘世隆的Talk已准时在TechBeat人工智能社区开播&#xff01; 他与大家分享的主题是: “From Detection to Grounding-迈向更强的开集目标检测”&#xff0c;他分…

5个PPT素材、模板网站,建议收藏~

做PPT绝对不能错过这5个网站&#xff0c;建议收藏~ 1、菜鸟图库 https://www.sucai999.com/search/ppt/0_0_0_1.html?vNTYxMjky 菜鸟图库素材非常齐全&#xff0c;设计、办公、图片、视频等素材这里都能找到&#xff0c;PPT模板数量很可观&#xff0c;模板样式多&#xff0c…

数据结构和算法——散列表的性能分析(开放地址法的查找性能、期望探测次数与装填因子的关系、分离链接法的查找性能)

目录 开放地址法的查找性能 线性探测法 平方探测法和双散列探测法 期望探测次数与装填因子的关系 分离链接法的查找性能 总结 散列表的性能分析 平均查找长度&#xff08;ASL&#xff09;用来度量散列表查找效率&#xff1a;成功、不成功关键词的比较次数&#xff0c;取…

Dataloader数据集的制作

数据集Dataloader制作 如何自定义数据集&#xff1a; 1.数据和标签的目录结构先搞定(得知道到哪读数据)2.写好读取数据和标签路径的函数(根据自己数据集情况来写)3.完成单个数据与标签读取函数(给dataloader举一个例子) 咱们以花朵数据集为例&#xff1a; 原来数据集都是以…

RabbitMQ 消息队列(Spring boot AMQP)

文章目录 &#x1f370;有几个原因可以解释为什么要选择 RabbitMQ&#xff1a;&#x1f969;mq之间的对比&#x1f33d;RabbitMQ vs Apache Kafka&#x1f33d;RabbitMQ vs ActiveMQ&#x1f33d;RabbitMQ vs RocketMQ&#x1f33d;RabbitMQ vs Redis &#x1f969;linux docke…

Android App消息推送 实现原理

https://www.jianshu.com/p/b61a49e0279f 1.消息推送的实质 实际上&#xff0c;是当服务器有新消息需推送给用户时&#xff0c;先发送给应用App&#xff0c;应用App再发送给用户 2. 作用产品角度&#xff1a;功能需要&#xff0c;如&#xff1a;资讯类产品的新闻推送、工具类…

App消息推送 实现原理

1.消息推送的实质 实际上&#xff0c;是当服务器有新消息需推送给用户时&#xff0c;先发送给应用App&#xff0c;应用App再发送给用户 2. 作用 产品角度&#xff1a;功能需要&#xff0c;如&#xff1a;资讯类产品的新闻推送、工具类产品的公告推送等等 运营角度&#xff1a;活…

浏览器及app消息推送

消息推送 什么是消息推送PC端的实现方法1:Notification方法2&#xff1a;pushjs APP端实现打包设置 什么是消息推送 消息推送可以存在于浏览器端&#xff0c;也存在APP端。浏览器的推送&#xff0c;会在电脑通知中显示&#xff0c;app中显示在通知栏 PC端的实现 方法1:Notif…