yolov8-seg 分割推理流程

目录

一、分割+检测

二、图像预处理

二、推理

三、后处理与可视化

3.1、后处理

3.2、mask可视化

四、完整pytorch代码


一、分割+检测

注:本篇只是阐述推理流程,tensorrt实现后续跟进。

yolov8-pose的tensorrt部署代码稍后更新,还是在仓库:GitHub - FeiYull/TensorRT-Alpha: 🔥🔥🔥TensorRT-Alpha supports YOLOv8、YOLOv7、YOLOv6、YOLOv5、YOLOv4、v3、YOLOX、YOLOR...🚀🚀🚀CUDA IS ALL YOU NEED.🍎🍎🍎It also supports end2end CUDA C acceleration and multi-batch inference.

也可以关注:TensorRT系列教程-CSDN博客

以下是官方预测代码:

from ultralytics import YOLO
model = YOLO(model='yolov8n-pose.pt')
model.predict(source="d:/Data/1.jpg", save=True)

推理过程无非是:图像预处理 -> 推理 -> 后处理 + 可视化,这三个关键步骤在文件大概247行:D:\CodePython\ultralytics\ultralytics\engine\predictor.py,代码如下:

# Preprocess
with profilers[0]:im = self.preprocess(im0s) # 图像预处理# Inference
with profilers[1]:preds = self.inference(im, *args, **kwargs) # 推理# Postprocess
with profilers[2]:self.results = self.postprocess(preds, im, im0s) # 后处理

二、图像预处理

通过debug,进入上述self.preprocess函数,看到代码实现如下。处理流程大概是:padding(满足矩形推理),图像通道转换,即:BGR装RGB,检查图像数据是否连续,存储顺序有HWC转为CHW,然后归一化。需要注意,原始pytorch框架图像预处理的时候,会将图像缩放+padding为HxW的图像,其中H、W为32倍数,而导出tensorrt的时候,为了高效推理,H、W 固定为640x640。

def preprocess(self, im):"""Prepares input image before inference.Args:im (torch.Tensor | List(np.ndarray)): BCHW for tensor, [(HWC) x B] for list."""not_tensor = not isinstance(im, torch.Tensor)if not_tensor:im = np.stack(self.pre_transform(im))im = im[..., ::-1].transpose((0, 3, 1, 2))  # BGR to RGB, BHWC to BCHW, (n, 3, h, w)im = np.ascontiguousarray(im)  # contiguousim = torch.from_numpy(im)img = im.to(self.device)img = img.half() if self.model.fp16 else img.float()  # uint8 to fp16/32if not_tensor:img /= 255  # 0 - 255 to 0.0 - 1.0return img

二、推理

图像预处理之后,直接推理就行了,这里是基于pytorch推理。

def inference(self, im, *args, **kwargs):visualize = increment_path(self.save_dir / Path(self.batch[0][0]).stem,mkdir=True) if self.args.visualize and (not self.source_type.tensor) else Falsereturn self.model(im, augment=self.args.augment, visualize=visualize)

三、后处理与可视化

3.1、后处理

640x640输入之后,有两个输出,其中

  • output1:尺寸为:116X8400,其中116=4+80+32,32为seg部分特征,经过NMS之后,输出为:N*38,其中38=4 + 2 + 32
  • output2:尺寸为32x160x160,拿上面NMS后的特征图后面,即:N*38矩阵后面部分N*32的特征图和output2作矩阵乘法,得到N*160*160的矩阵,接着执行sigmiod,然后拉平得到N*160*160 的mask。

然后将bbox缩放160*160的坐标系,如下代码,用于截断越界的mask,就是如下函数。最后,将所有mask上采样到640*640,然后用阀值0.5过一下。最后mask中只有0和1了,结束。

有关def crop_mask(masks, boxes):的理解:

def crop_mask(masks, boxes):"""It takes a mask and a bounding box, and returns a mask that is cropped to the bounding boxArgs:masks (torch.Tensor): [n, h, w] tensor of masksboxes (torch.Tensor): [n, 4] tensor of bbox coordinates in relative point formReturns:(torch.Tensor): The masks are being cropped to the bounding box."""n, h, w = masks.shapex1, y1, x2, y2 = torch.chunk(boxes[:, :, None], 4, 1)  # x1 shape(n,1,1)r = torch.arange(w, device=masks.device, dtype=x1.dtype)[None, None, :]  # rows shape(1,1,w)c = torch.arange(h, device=masks.device, dtype=x1.dtype)[None, :, None]  # cols shape(1,h,1)return masks * ((r >= x1) * (r < x2) * (c >= y1) * (c < y2))

上面代码最后一句return,如下图理解,mask中所有点,例如点(r,c)必须在bbox内部。做法就是将bbox缩放到和mask一样的坐标系(160x160)如下图,然后使用绿色的bbox将mask进行截断:

3.2、mask可视化

直接将mask从灰度图转为彩色图,然后将类别对应的颜色乘以0.4,最后加在彩色图上就行了。

四、完整pytorch代码

将以上流程合并起来,并加以修改,完整代码如下:

import torch
import cv2 as cv
import numpy as np
from ultralytics.data.augment import LetterBox
from ultralytics.utils import ops
from ultralytics.engine.results import Results
import copy# path = 'd:/Data/1.jpg'
path = 'd:/Data/640640.jpg'
device = 'cuda:0'
conf = 0.25
iou = 0.7# preprocess
im = cv.imread(path)
# letterbox
im = [im]
orig_imgs = copy.deepcopy(im)
im = [LetterBox([640, 640], auto=True, stride=32)(image=x) for x in im]
im = im[0][None] # im = np.stack(im)
im = im[..., ::-1].transpose((0, 3, 1, 2))  # BGR to RGB, BHWC to BCHW, (n, 3, h, w)
im = np.ascontiguousarray(im)  # contiguous
im = torch.from_numpy(im)
img = im.to(device)
img = img.float()
img /= 255
# load model pt
ckpt = torch.load('yolov8n-seg.pt', map_location='cpu')
model = ckpt['model'].to(device).float()  # FP32 model
model.eval()# inference
preds = model(img)# poseprocess
p = ops.non_max_suppression(preds[0], conf, iou, agnostic=False, max_det=300, nc=80, classes=None)
results = []
# 如果导出onnx,第二个输出维度是1,应该就是mask,需要后续上采样
proto = preds[1][-1] if len(preds[1]) == 3 else preds[1]  # second output is len 3 if pt, but only 1 if exported???????
for i, pred in enumerate(p):orig_img = orig_imgs[i]if not len(pred):  # save empty boxesresults.append(Results(orig_img=orig_img, path=path, names=model.names, boxes=pred[:, :6]))continuemasks = ops.process_mask(proto[i], pred[:, 6:], pred[:, :4], img.shape[2:], upsample=True)  # HWCif not isinstance(orig_imgs, torch.Tensor):pred[:, :4] = ops.scale_boxes(img.shape[2:], pred[:, :4], orig_img.shape)results.append(Results(orig_img=orig_img, path=path, names=model.names, boxes=pred[:, :6], masks=masks))# show
plot_args = {'line_width': None,'boxes': True,'conf': True, 'labels': True}
plot_args['im_gpu'] = img[0]
result = results[0]
plotted_img = result.plot(**plot_args)
cv.imshow('plotted_img', plotted_img)
cv.waitKey(0)
cv.destroyAllWindows()

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

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

相关文章

探索数字化转型项目的基础

从消费品到特种化学品&#xff0c;数字化转型正在各行各业中逐渐普及。然而&#xff0c;尽管使用智能化设备、连接解决方案和数据分析对改造升级制造运营模式有巨大帮助&#xff0c;但起步过程&#xff08;奠定一个良好的基础来支撑工厂的可访问性、可靠性、可维护性、可扩展性…

java中IO知识点概念

这里写自定义目录标题 内存中的数据以电子信号的形式表示&#xff0c;而磁盘中的数据是以磁场的方向表示。1.流的分类2.File类3.流的API 关键4.理解缓冲的作用-一次性多拿些读写文件的时候为什么要有缓冲流 -意义是什么缓冲流的使用 5.路径问题6.文件的创建7.内存和磁盘存储本质…

【3D程序软件】SideFX与上海道宁一直为设计师提供程序化 3D动画和视觉效果工具,旨在创造高质量的电影效果

Houdini是一个 从头开始构建的程序系统 使艺术家能够自由工作 创建多次迭代 并与同事快速共享工作流程 Houdini FX为 视觉特效艺术家创作故事片 广告或视频游戏 凭借其基于程序节点的工作流程 Houdini FX可让 您更快地创建更多内容 从而缩短时间并 在所有创意任务中…

ESP Multi-Room Music 方案:支持音频实时同步播放 实现音乐互联共享

项目背景 随着无线通信技术的发展&#xff0c;针对不同音频应用领域的无线音频产品正不断涌现。近日&#xff0c;乐鑫科技推出了基于 Wi-Fi 的多扬声器互联共享音乐通信协议——ESP Multi-Room Music 方案。该方案使用乐鑫自研的基于 Wi-Fi 局域网的音频同步播放技术&#xff…

51单片机使用串口查看程序执行的数据

51单片机使用串口查看程序执行的数据 1.概述 这篇文章介绍利用串口输出程序执行的数据&#xff0c;辅助我们调试程序&#xff0c;提高代码定位问题的效率。 2.硬件电路原理 3.串口助手查看程序数据 输出串口数据的方式分为CPU查询方式和中断方式。他们各有优缺点&#xff0…

源码剖析 Spring Security 的实现原理

Spring Security 是一个轻量级的安全框架&#xff0c;可以和 Spring 项目很好地集成&#xff0c;提供了丰富的身份认证和授权相关的功能&#xff0c;而且还能防止一些常见的网络攻击。我在工作中有很多项目都使用了 Spring Security 框架&#xff0c;但基本上都是浅尝辄止&…

Java 8 中 ReentrantLock 与 Synchronized 的区别

&#x1f680; 作者主页&#xff1a; 有来技术 &#x1f525; 开源项目&#xff1a; youlai-mall &#x1f343; vue3-element-admin &#x1f343; youlai-boot &#x1f33a; 仓库主页&#xff1a; Gitee &#x1f4ab; Github &#x1f4ab; GitCode &#x1f496; 欢迎点赞…

《微信小程序开发从入门到实战》学习三十五

4.2 云开发JSON数据库 4.2.3 权限控制 在云开发控制台可以对数据库中的数据进行操作&#xff0c; 在小程序端和云函数可以分别使用小程序API和服务端API对数据中的数据进行操作。 以上操作受到权限控制。 对数据库进行查询属于读操作&#xff0c;增删改操作属于写操作。 …

Day44力扣打卡

打卡记录 给小朋友们分糖果 II&#xff08;容斥原理 隔板法&#xff09; 链接 def c2(n):return n * (n - 1) // 2 if n > 1 else 0class Solution:def distributeCandies(self, n: int, limit: int) -> int:return c2(n 2) - 3 * c2(n - limit 1) 3 * c2(n - 2 * …

uniapp+微信小程序监听返回事件

代码附在最后 适用场景&#xff1a;uniapp开发微信小程序 需求是我点击列表进入数据信息的详情界面&#xff0c;点击详情界面的收藏&#xff0c;返回上一界面后&#xff0c;更新列表中的收藏情况。 目录 一、使用onUnload监听页面卸载 二、使用getCurrentPages()获取当前页…

【双指针】四数之和

四数之和 建议做过了解三数之和的思想再做这道题&#xff0c;思路是一样的~ 题目描述 18. 四数之和 - 力扣&#xff08;LeetCode&#xff09; 给你一个由 n 个整数组成的数组 nums &#xff0c;和一个目标值 target 。请你找出并返回满足下述全部条件且不重复的四元组 [num…

Java大型智慧工地APP云平台源码带AI智能识别功能

智慧工地为建筑全生命周期赋能&#xff0c;用创新的可视化与智能化方法&#xff0c;降低成本&#xff0c;创造价值。 一、智慧工地APP概述 智慧工地”立足于互联网&#xff0c;采用云计算&#xff0c;大数据和物联网等技术手段&#xff0c;针对当前建筑行业的特点&#xff0c;…

C语言 移位操作符

<< 左移操作符>> 右移操作符 注&#xff1a;移位操作符的操作数只能是整数。 移位操作符移动的是二进制位。 整数的二进制表示有3种&#xff1a; 原码反码补码 正的整数的原码、反码、补码相同。 负的整数的原码、反码、补码是要计算的。 由负整数原码计算出反…

编写安全 JavaScript 代码的最佳实践

编写安全 JavaScript 代码的最佳实践 JavaScript 的动态特性使其成为事实上的浏览器语言和世界上最流行的编程语言。 JS 最受欢迎的有用功能之一是即时分析。这意味着浏览器在下载内容的同时执行代码&#xff0c;这显然有其优势。然而&#xff0c;这种程度的自由也伴随着问题…

【工业智能】Solutions

各类问题对应的解决方案 工艺参数推荐APC 排产调度智能算法强化学习 运筹优化空压机群控 预测 工艺参数推荐 APC 排产调度 智能算法 遗传算法 强化学习 DDQN 运筹优化 空压机群控 MIP混合整数规划 能耗优化 预测 电池容量预测 时序预测&#xff0c;回归预测 点击剩余…

【好用的个人工具】在Docker环境下部署Simple mind map思维导图工具

【好用的个人工具】在Docker环境下部署Simple mind map思维导图工具 一、Simple mind map介绍1.1 Simple mind map简介1.2 Simple mind map特点 二、本地环境介绍2.1 本地环境规划2.2 本次实践介绍 三、本地环境检查3.1 检查Docker服务状态3.2 检查Docker版本3.3 检查docker co…

freerots启动过程分析(qemu仿真RISC-V架构为例)

1、前言 本文是基于qemu上virt板子适配的freertos系统源码进行讲解qemu安装可参考博客&#xff1a;《qemu源码下载和安装》&#xff1b;freertos移植到qemu上运行可参考博客&#xff1a;《移植freertos到qemu上运行》&#xff1b; 2、汇编代码部分 汇编文件&#xff1a;FreeR…

Web框架与Django路由层

Web框架 一 web框架 Web框架&#xff08;Web framework&#xff09;是一种开发框架&#xff0c;用来支持动态网站、网络应用和网络服务的开发。这大多数的web框架提供了一套开发和部署网站的方式&#xff0c;也为web行为提供了一套通用的方法。web框架已经实现了很多功能&…

基于单片机的智能饮水机控制系统(论文+源码)

1. 系统设计 本次智能饮水机控制系统的设计研究一款以STC89C52单片机为核心的智能饮水机控制系统&#xff0c;其主要功能设计如下&#xff1a; 1.该饮水机利用DS18B20数字温度传感器实时采集饮水机内水的温度&#xff0c;其检测温度范围为0-100℃&#xff0c;精度0.1℃&#…

拆解按摩器:有意思的按键与LED控制电路,学习借鉴一下!

拆解 外观和配色个人感觉还行,比较青春 拉开拉链&#xff0c;拆开外面的布面&#xff0c;里面还有一层纱面 按键部分使用魔术贴固定 拆开纱面后&#xff0c;看到里面的结构&#xff0c;整体是一个海绵 可以看到如下&#xff0c;电池&#xff0c;按键板&#xff0c;充电线的三条…