yolov8-seg分割模型TensorRt部署,去掉torch

已完成的yolov8-seg分割模型TensorRt部署

  • 准备
  • 下载yolov8-seg模型
  • 转化为onnx和trt
  • 推理
    • 写好的推理接口

准备

https://github.com/songjiahao-wq/yolov8_seg_trtinference.git下载代码
安装TensorRt=8.6版本,以及pip install -r requirements.txt

下载yolov8-seg模型

转化为onnx和trt

转化方法如下:

# tensorRT==8.6
## yolov8-seg CLI指令
### 转化ONNX模型
`python export-seg.py --weights yolov8m-seg.pt --opset 14 --sim --input-shape 1 3 640 640 --device cuda:0``python export-seg.py --weights yolov8m-seg.pt --opset 14 --sim --input-shape 1 3 448 512 --device cuda:0`
### 导出trt模型
`python build.py --weights yolov8m-seg.onnx --fp16  --device cuda:0 --seg`
### 采用trtexec导出trt模型
`E:\Download\TensorRT-10.0.1.6\bin/trtexec --onnx=yolov8m-seg.onnx --saveEngine=yolov8s-seg.engine --fp16`
### 不需要torch环境推理
`python infer-seg-without-torch.py --engine yolov8m-seg.engine --imgs data --show --out-dir outputs --method cudart`
### 需要torch环境推理
`python infer-seg.py`- [x] infer-seg-without-torch-port.py 调用接口,每次只保存mask.txt
- [x] infer-seg-without-torch.py 不需要torch调用,有cuda和pycuda
  1. 首先转化为onnx模型
python export-seg.py --weights yolov8m-seg.pt --opset 14 --sim --input-shape 1 3 640 640 --device cuda:0
  1. 然后转化为trt模型
    有两种转化方式:
    代码转化:python build.py --weights yolov8m-seg.onnx --fp16 --device cuda:0 --seg
    trtexec转化:trtexec --onnx=yolov8m-seg.onnx --saveEngine=yolov8s-seg.engine --fp16

推理

推理方法有两种:
cudart推理,不包含torch

  1. python infer-seg-without-torch.py --engine yolov8m-seg.engine --imgs data --show --out-dir outputs --method cudart
    pycuda推理,不包含torch
  2. `python infer-seg-without-torch.py --engine yolov8m-seg.engine --imgs data --show --out-dir outputs --method pycuda
    带torch的推理
  3. python infer-seg.py

写好的推理接口

import argparse
import time
from pathlib import Pathimport cv2
import numpy as npfrom config import ALPHA, CLASSES, COLORS, MASK_COLORS
from models.utils import blob, letterbox, path_to_list, seg_postprocess
import torchdef clip_segments(segments, shape):"""Clips segment coordinates (xy1, xy2, ...) to an image's boundaries given its shape (height, width)."""if isinstance(segments, torch.Tensor):  # faster individuallysegments[:, 0].clamp_(0, shape[1])  # xsegments[:, 1].clamp_(0, shape[0])  # yelse:  # np.array (faster grouped)segments[:, 0] = segments[:, 0].clip(0, shape[1])  # xsegments[:, 1] = segments[:, 1].clip(0, shape[0])  # ydef scale_segments(img1_shape, segments, img0_shape, ratio_pad=None, normalize=False):"""Rescales segment coordinates from img1_shape to img0_shape, optionally normalizing them with custom padding."""if ratio_pad is None:  # calculate from img0_shapegain = min(img1_shape[0] / img0_shape[0], img1_shape[1] / img0_shape[1])  # gain  = old / newpad = (img1_shape[1] - img0_shape[1] * gain) / 2, (img1_shape[0] - img0_shape[0] * gain) / 2  # wh paddingelse:gain = ratio_pad[0][0]pad = ratio_pad[1]segments[:, 0] -= pad[0]  # x paddingsegments[:, 1] -= pad[1]  # y paddingsegments /= gainclip_segments(segments, img0_shape)if normalize:segments[:, 0] /= img0_shape[1]  # widthsegments[:, 1] /= img0_shape[0]  # heightreturn segmentsdef masks2segments(masks, strategy="largest"):"""Converts binary (n,160,160) masks to polygon segments with options for concatenation or selecting the largestsegment."""segments = []for x in masks.int().cpu().numpy().astype("uint8"):c = cv2.findContours(x, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)[0]if c:if strategy == "concat":  # concatenate all segmentsc = np.concatenate([x.reshape(-1, 2) for x in c])elif strategy == "largest":  # select largest segmentc = np.array(c[np.array([len(x) for x in c]).argmax()]).reshape(-1, 2)else:c = np.zeros((0, 2))  # no segments foundsegments.append(c.astype("float32"))return segmentsdef keep_highest_conf_per_class(bboxes, scores, labels, segments, classes=0):# 组合成新的检测结果数组det = np.hstack((bboxes, scores[:, np.newaxis], labels[:, np.newaxis], np.array(segments)[:, np.newaxis]))if det.shape[0] == 0:return det  # 如果没有检测到任何对象,直接返回unique_classes = np.unique(det[:, 5])  # 获取所有独特的类标签max_conf_indices = []# 对每一个类别找到最高置信度的检测框cls_mask = det[:, 5] == classes  # 找到所有该类别的检测框cls_detections = det[cls_mask]  # 提取该类别的所有检测框# 计算每个检测框的面积areas = (cls_detections[:, 2] - cls_detections[:, 0]) * (cls_detections[:, 3] - cls_detections[:, 1])# 合并置信度和面积为一个复合评分,这里用置信度 + 面积的小部分作为评分scores_combined = cls_detections[:, 4] * 0.1 + 1.0 * areas# 找到评分最高的检测框max_score_index = np.argmax(scores_combined)# 找到原始的索引original_max_conf_index = np.where(cls_mask)[0][max_score_index]max_conf_indices.append(original_max_conf_index)# 选取评分最高的检测框return det[max_conf_indices][:, :4], det[max_conf_indices][:, 4], det[max_conf_indices][:, 5], det[max_conf_indices][:,6], max_conf_indicesclass YOLOv8_seg_main:def __init__(self, args: argparse.Namespace):if args.method == 'cudart':from models.cudart_api import TRTEngineelif args.method == 'pycuda':from models.pycuda_api import TRTEngineelse:raise NotImplementedErrorself.Engine = TRTEngine(args.engine)self.H, self.W = self.Engine.inp_info[0].shape[-2:]self.args = argsdef main(self, bgr, imagename, outtxtdir) -> None:outtxtdir = Path(outtxtdir)save_path = Path(args.out_dir)if not self.args.show and not save_path.exists():save_path.mkdir(parents=True, exist_ok=True)draw = bgr.copy()bgr, ratio, dwdh = letterbox(bgr, (self.W, self.H))dw, dh = int(dwdh[0]), int(dwdh[1])rgb = cv2.cvtColor(bgr, cv2.COLOR_BGR2RGB)tensor, seg_img = blob(rgb, return_seg=True)dwdh = np.array(dwdh * 2, dtype=np.float32)tensor = np.ascontiguousarray(tensor)# inferencedata = self.Engine(tensor)seg_img = seg_img[dh:self.H - dh, dw:self.W - dw, [2, 1, 0]]bboxes, scores, labels, masks = seg_postprocess(data, bgr.shape[:2], self.args.conf_thres, self.args.iou_thres)if bboxes.size == 0:# if no bounding boxassert print(f'image: no object!')masks = masks[:, dh:self.H - dh, dw:self.W - dw, :]segments = [scale_segments(tensor.shape[2:], x, rgb.shape, normalize=True)for x in reversed(masks2segments(torch.from_numpy(masks)))]bboxes -= dwdhbboxes /= ratio# 应用 keep_highest_conf_per_class 函数bboxes, scores, labels, segments, max_conf_indices = keep_highest_conf_per_class(bboxes, scores, labels, segments, classes=0)if args.show:masks = masks[max_conf_indices]mask_colors = MASK_COLORS[0]mask_colors = mask_colors.reshape(-1, 1, 1, 3) * ALPHAmask_colors = masks @ mask_colorsinv_alph_masks = (1 - masks * 0.5).cumprod(0)mcs = (mask_colors * inv_alph_masks).sum(0) * 2seg_img = (seg_img * inv_alph_masks[-1] + mcs) * 255draw = cv2.resize(seg_img.astype(np.uint8), draw.shape[:2][::-1])if args.save_txt:seg = segments[0].reshape(-1)  # (n,2) to (n*2)line = (int(labels[0]), *seg)  # label formatwith open(outtxtdir / f"{Path(imagename).stem}.txt", "w") as f:f.write(("%g " * len(line)).rstrip() % line + "\n")if args.show:save_image = save_path / Path(imagename).namecv2.imwrite(str(save_image), draw)def parse_args():parser = argparse.ArgumentParser()parser.add_argument('--engine', type=str, default="../yolov8l-seg.engine", help='Engine file')parser.add_argument('--imgs', type=str, default="data", help='Images file')parser.add_argument('--show',action='store_true',default=False,help='Show the detection results')parser.add_argument('--save_txt',action='store_true',default=True,help='save_txt the detection results')parser.add_argument('--out-dir',type=str,default='./output',help='Path to output file')parser.add_argument('--conf-thres',type=float,default=0.25,help='Confidence threshold')parser.add_argument('--iou-thres',type=float,default=0.25,help='Confidence threshold')parser.add_argument('--method',type=str,default='cudart',help='CUDART pipeline')args = parser.parse_args()return argsif __name__ == '__main__':args = parse_args()YOLOv8_seg_main = YOLOv8_seg_main(args)imgpath = './data/1.jpg'outtxtdir = './output'bgr_img = cv2.imread(imgpath)t1 = time.time()for i in range(100):YOLOv8_seg_main.main(bgr_img, imgpath, outtxtdir)print(time.time() - t1)

输入为brg图像,图像的路径和输出路径,最后会保存masktxt

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

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

相关文章

FastAPI本身是一个高性能的Web框架

FastAPI本身是一个高性能的Web框架,它并不直接支持数据库操作,但可以通过集成各种数据库库来与各种数据库进行交互。FastAPI支持几乎所有的关系型数据库和非关系型数据库,这主要取决于你选择的数据库库(如ORM库)以及相…

【web APIs】快速上手Day05(Bom操作)

目录 Web APIs - 第5天笔记js组成window对象BOM定时器-延迟函数案例-5秒钟之后消失的广告 JS执行机制location对象案例-5秒钟之后跳转的页面 navigator对象histroy对象 本地存储(今日重点)localStorage(重点)sessionStorage&#…

三、mysql-万字长文读懂mysql

mysql 三、 Mysql3.1 基础3.1.1 mysql执行流程-组成架构3.2 索引3.2.1 索引底层的数据结构与算法分类在创建表时,InnoDB 存储引擎会根据不同的场景选择不同的列作为索引B+树结构3.2.2 为什么 MySQL InnoDB 选择 B+tree 作为索引的数据结构3.2.2.1. 从磁盘角度出发3.2.2.2. 数据…

深度解析移动硬盘“函数不正确”错误及高效恢复策略

在数据密集型的社会中,移动硬盘作为移动存储的重要载体,承载着无数用户的个人信息、工作资料及珍贵回忆。然而,当遭遇“函数不正确”的错误时,这些宝贵的数据仿佛被一层无形的屏障所阻隔,让人束手无策。本文将深入探讨…

如何选择高性价比的土壤检测仪器?

在现代农业与环保领域,土壤检测仪器的选择显得尤为关键。它不仅关系到土壤养分管理、作物健康生长,还涉及到环境保护和可持续发展。那么,面对市场上琳琅满目的土壤检测仪器,我们该如何选择一款实用的设备呢? 首先&…

(1)滑动窗口算法介绍与练习:长度最小的子数组

滑动窗口算法介绍 所谓滑动窗口,即为同向双指针移动过程中形成的间隔区域,并且这两个指针在移动的过程中不会回退 对于滑动窗口的题目可以抽象为三个步骤: 定义窗口两端指针left和right进入窗口判断离开窗口循环2、3和4步 滑动窗口练习 长度最…

昇思训练营打卡第十七天(基于MindNLP+MusicGen生成自己的个性化音乐)

MindNLP是一个基于MindSpore的自然语言处理(NLP)开源库。它提供了一系列常用的NLP方法,并支持解决各种自然语言处理任务的平台。MindNLP的设计目标是帮助研究人员和开发者更高效地构建和训练模型。 MindNLP的主要特点包括: 全面…

git要忽略对文件的本地修改

要忽略对文件的本地修改(即,使Git忽略对该文件的任何未提交更改),可以使用以下命令将该文件标记为假设未更改(assume-unchanged): sh git update-index --assume-unchanged runtime/x64/skin/s…

短视频电商源码的优势及软件架构解析

短视频电商源码是目前电商行业中非常火热的一个新兴领域,它通过短视频内容和电商商品的结合,为用户提供了一种新的购物体验。下面将介绍短视频电商源码的优势以及软件架构。 首先,短视频电商源码具有以下几个优势: 1、创新的购物体…

C#中的函数

函数是越单一越好 函数的命名规范 驼峰命名法&#xff1a;即首字母大写 多单词拼接时&#xff0c;所有单词首字母大写 internal class Program {static void Main(string[] args){int a 2;int b 3;int sum add(a, b);Console.WriteLine(sum); ​}/// <summary>///…

惠海 H6118 DCDC降压恒流芯片IC 30V36v40V降12V 9V LED景观灯舞台灯方案

H6118是一款连续电感电流导通模式的降压型LED恒流驱动器&#xff0c;用于驱动一个或多个LED 灯串。H6118工作电压从4V到30V&#xff0c;提供可调的输出电流&#xff0c;最大输出电流可达到1.2A。 H6118内置功率开关管&#xff0c;采用高端电流检测电路&#xff0c;支持PWM模式…

云联壹云 FinOps:赋能某车企公有云成本管理与精细化运营

背景 某车企&#xff0c;世界 500 强企业&#xff0c;使用了大量的公有云资源&#xff0c;分布于多家公有云&#xff0c;月消费在千万级别。 业务线多且分散&#xff0c;相关的云消耗由一个核心团队进行管理&#xff0c;本次案例的内容将围绕这些云成本的管理展开的。 需求 …

用例导图CMind

突然有一些觉悟&#xff0c;程序猿不能只会吭哧吭哧的低头做事&#xff0c;应该学会怎么去展示自己&#xff0c;怎么去宣传自己&#xff0c;怎么把自己想做的事表述清楚。 于是&#xff0c;这两天一直在整理自己的作品&#xff0c;也为接下来的找工作多做点准备。接下来…

超详细kkFileView打包部署Windows或Liunx

目录 前言 下载源码编辑打包 Windows下的部署 Liunx下的部署 前言 本文章主要以下载源码 自己编译打包的方式进行部署。 因为4.0.0之后官方不在初始jar包,所以自己拉代码吧,别偷懒,顺便看看代码怎么写的。 码云: kkFileView 下载源代码为4.4.0-beta版本,亲测可用 下载源…

C++的map / multimap容器

一、介绍 在C的map / multimap容器中&#xff0c;所有的元素均是pair类型&#xff08;有关pair类型可以参考我之前写的 《C的set / multiset容器》的3.2中有介绍到&#xff09;。 每对pair的第一个元素被称为关键字key&#xff0c;第二个元素被称为值value。因此&#xff0c;ma…

Linux 复现Docker NAT网络

Linux 复现Docker NAT网络 docker 网络的构成分为宿主机docker0网桥和为容器创建的veth 对构成。这个默认网络命名空间就是我们登陆后日常使用的命名空间 使用ifconfig命令查看到的就是默认网络命名空间&#xff0c;docker0就是网桥&#xff0c;容器会把docker0当成路由&…

43、nginx的优化、防盗链、重定向、代理

nginx的优化、防盗链、重定向、代理 一、nginx的优化 1.1、隐藏版本号 server_tokens off;隐藏版本号 [roottest1 conf]# vim nginx.confserver_tokens off;[roottest1 conf]# nginx -t nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok ngin…

卫星IoT产品发展前景

卫星IoT产品发展前景 一、概述 卫星IoT产品是指利用卫星通信技术实现物联网设备互联互通的解决方案。随着卫星互联网技术的快速发展&#xff0c;卫星IoT产品正逐渐成为解决偏远地区、海洋、航空等场景下物联网连接问题的重要手段。 二、性能特点 广泛覆盖&#xff1a; 卫星…

【CW32F030CxTx StartKit开发板】利用超声波传感器实现智能灯控

目录 1、超声波传感器 2、硬件连线 3. 程序开发 3.1 超声波测距 3.2 LED控制 4. 演示视频 本文首发于21ic。 感谢21ic和武汉芯源提供的测试机会。 在上一篇帖子中介绍了CW32F030CxTxStartKit 评估板的环境构建。本次介绍如何利用超声波传感器实现人来灯亮&#xff0c;人…

Ubuntu 22.04上/etc/init.d/softIOC脚本解析

如何在Linux上设立一个软IOC框架 以下说明是基于我们的Debian Linux机器。其它发行版(或其他Unixes)会有不同命令和对于东西有不同位置。这对我添加到本页的Debian /etc/init.d尤其如此。如果你为一个不同发行版创建一个不同的脚本&#xff0c;请添加它到本页。其它人将能够使…