yolov8分割任务的推理和后处理解析

在这里插入图片描述

文章目录

  • 一、前言
  • 二、分割模型的前向推理
    • 1. 检测结果:来自Detect类的输出
    • 2. 分割结果(最终)
    • 3. 与Detect的主要区别
    • 4. 工作流程
  • 三、后处理
    • 1. 非极大值抑制(NMS)过滤检测框
    • 2. 分割原型(Mask Prototypes)提取
    • 3. 掩码生成

一、前言

这篇文章主要分享yolov8模型用于图像分割时,模型输出和后处理。彻底理了下,可以总结为以下3点:

  1. 分割继承检测,前向推理时也会调用检测的方法把目标框检测出来;
  2. 但是前向推理分割和检测是各自进行的,训练也是分别去计算loss;
  3. 在后处理时为了提精度,在有目标处才去分割,然后为了提速掩膜才去系数和乘以原始掩膜的方法,系数和原始掩膜都是分割模型的前向推理输出;

yolov8官方代码路径:https://github.com/ultralytics/ultralytics

二、分割模型的前向推理

代码位置:yolo/ultralytics/nn/modules/head.py
在这里插入图片描述
解释:

  1. 继承关系:
  • Segment继承了Detect的所有基础功能,包括目标检测的能力
  • 它扩展了Detect的功能,增加了实例分割的能力
  1. 主要组件:
def __init__(self, nc=80, nm=32, npr=256, ch=()):super().__init__(nc, ch)self.nm = nm  # 掩码数量self.npr = npr  # 原型数量self.proto = Proto(ch[0], self.npr, self.nm)  # 原型网络self.detect = Detect.forward  # 保留检测功能
  1. 推理输出:
    从forward方法可以看出,Segment模型在推理时返回两个主要部分:
def forward(self, x):p = self.proto(x[0])  # 生成掩码原型bs = p.shape[0]  # batch size# 生成掩码系数mc = torch.cat([self.cv4[i](x[i]).view(bs, self.nm, -1) for i in range(self.nl)], 2)x = self.detect(self, x)  # 调用检测功能if self.training:return x, mc, preturn (torch.cat([x, mc], 1), p) if self.export else (torch.cat([x[0], mc], 1), (x[1], mc, p))

推理时返回的内容包括:

1. 检测结果:来自Detect类的输出


变量解释:

  • x:分别为3个head输出的特征图(大中小)
    shape为:(bs, 4+类别数,特征图宽,特征图高)

  • y: 边界框坐标+类别预测(经过sigmoid)——纵向拼接
    shape为:(bs, 4+类别数,框的个数)

  • 训练模式,则输出x;

  • 推理模式:
    export为onnx时则输出:y
    否则输出一个元组:(y, x)

2. 分割结果(最终)

变量解释:

  • 掩码系数mc(mask coefficients)
    shape为:(bs, 32(系数个数),框的个数)
  • 原型掩码p(prototype masks)
    shape为:(bs, 32(系数个数),mask图宽,mask图高)

训练模式,输出三个元素:x(detect的输出,对应x),mc,p

推理模式:

export为onnx时输出元组包含2个元素:

  • 第一个元素:纵向(第1维)拼接x(这里对应detect输出的y)和mc
    shape为:(bs, 4+类别数+32(系数个数),框的个数)
  • 第二个元素:p

否则也是输出元组包含2个元素:

  • 第一个元素只有1个元素:纵向拼接x0和mc
    可以理解为:目标检测的结果+掩码系数
    shape为 (bs, 4+类别数+32,mask(或框)的个数)
    –>(4后处理的输入[0]
  • 第二个元素是个元组有3个元素:(x1, mc, p)
    可以理解为:目标检测的head特征,掩码系数,原型掩码
    –>(4后处理的输入[1]

3. 与Detect的主要区别

  • Detect只输出检测结果(边界框和类别)
  • Segment在Detect的基础上增加了分割能力,可以输出实例掩码
  • Segment使用原型网络(Proto)来生成掩码,这是分割特有的组件

4. 工作流程

  • 首先通过原型网络生成基础掩码
  • 同时进行目标检测
  • 将检测结果和掩码系数结合,生成最终的实例分割结果
    这种设计使得Segment模型能够同时完成目标检测和实例分割任务,是一个多任务的模型架构。

三、后处理

代码位置:yolo/ultralytics/yolo/v8/segment/predict.py
在这里插入图片描述
其中:
pred[0]实际上就是:纵向拼接x0和mc
pred[1]实际上就是:(x1, mc, p)
在这里插入图片描述

1. 非极大值抑制(NMS)过滤检测框

  • 功能:
    • 过滤掉低置信度(< conf)的检测框。
    • 合并IoU超过阈值(iou)的重叠框。
    • 若启用agnostic_nms,不同类别的框也会被合并(适用于类别无关任务)。
    • 输出p为一个列表,每个元素对应一张图像的检测结果(形状:(num_boxes, 6 + num_masks),其中num_boxes为保留的检测框数,6包含x1,y1,x2,y2,conf,cls,mask1系数,mask2系数,…32个系数)。
  • 注意:
    • preds[0]形状为(batch_size, 4 + num_classes + num_masks, num_boxes)
    • num_masks 为 mask系数数量,通常是32个
    • mask_coeffs用于和原型掩码线性组合生成实例分割
    • 原型掩码是由模型预测出来的,对应output1

2. 分割原型(Mask Prototypes)提取

  • 背景:
    • preds[1]是分割头的输出,包含掩码原型。
    • 若模型为PyTorch格式(未导出),preds[1]可能有3个元素(如不同尺度的原型),需取最后一个(最高分辨率)。
    • 若模型已导出(如ONNX),preds[1]直接为原型张量。
  • 形状:
    • proto的典型形状为[batch, K, H, W],其中:
      • K:原型数量(如32)。
      • H, W:原型的分辨率(如输入图像的1/4大小)

3. 掩码生成

在这里插入图片描述
注意:每一个框对应一组掩码系数。

分为两个模式:
有四个尺寸:特征图尺寸(框对应);input尺寸;mask尺寸;原图尺寸

(1) 视网膜掩码:(标蓝是一个过程)
精度更高

放大box坐标到原图->生成mask(小图)->裁剪mask图(因为输入的时候为了保持图像不变形,会在两侧添加填充)->resize mask到原图->裁切mask对齐框(保留检测框内的区域,框外区域置为0)

(2) 普通掩码:(标蓝是一个过程)-- 推理默认
性能更好

生成mask(小图)->把坐标缩放到mask->裁切mask对齐框(保留检测框内的区域,框外区域置为0)->resize mask到input尺寸->把坐标放大到原图
注意:这个时候resize mask跟box坐标不在同一个尺寸标准下,画图的时候会把mask缩放到原图大小。

代码位置:yolo/ultralytics/yolo/utils/plotting.py
在这里插入图片描述

(3) 这两个模式都包括了两个操作:

(a) 缩放坐标

  1. 将检测框坐标从模型输入尺寸(img.shape[2:])缩放到原始图像尺寸(orig_img.shape),处理填充(padding)和缩放比例,确保框位置正确映射。
  2. 拆切超出图像边缘部分的框。

(b) 生成掩码
代码位置:yolo/ultralytics/yolo/utils/ops.py

如果是视网膜掩码,则使用process_mask_native

  1. 输入参数:
def process_mask_native(protos, masks_in, bboxes, shape):"""protos: 原型掩码 [mask_dim, mask_h, mask_w]masks_in: 预测的掩码系数 [n, mask_dim]bboxes: 检测框 [n, 4]shape: 原始图像尺寸 (h,w)"""
  1. 掩码生成:
c, mh, mw = protos.shape  # 获取原型掩码的维度
# 将掩码系数与原型掩码相乘,得到最终掩码
masks = (masks_in @ protos.float().view(c, -1)).sigmoid().view(-1, mh, mw)
  • 将原型掩码展平为2D矩阵
  • 与掩码系数进行矩阵乘法
  • 应用sigmoid激活函数
  • 重塑为3D张量
  1. 计算缩放和填充:
# 计算缩放比例
gain = min(mh / shape[0], mw / shape[1])  # gain = 旧尺寸/新尺寸# 计算填充值
pad = (mw - shape[1] * gain) / 2, (mh - shape[0] * gain) / 2  # wh padding
top, left = int(pad[1]), int(pad[0])  # y, x
bottom, right = int(mh - pad[1]), int(mw - pad[0])
  • 计算保持宽高比的缩放比例
  • 计算图像两侧的填充值
  • 确定裁剪区域
  1. 裁剪掩码:
# 裁剪掉填充区域
masks = masks[:, top:bottom, left:right]
  • 移除填充区域
  • 保持有效区域
  1. 调整大小:
# 将掩码调整到原始图像大小
masks = F.interpolate(masks[None], shape, mode='bilinear', align_corners=False)[0]
  • 使用双线性插值
  • 调整到原始图像尺寸
  • 保持掩码质量
  1. 根据检测框裁剪(保留检测框内的区域,框外区域置为0):
# 根据检测框裁剪掩码
masks = crop_mask(masks, bboxes)
  • 将掩码裁剪到检测框区域
  • 确保掩码与检测框对齐
  1. 二值化处理:
# 将掩码二值化
return masks.gt_(0.5)
  • 使用0.5作为阈值
  • 将掩码转换为二值图像

如果是普通掩码,则使用process_mask

  1. 生成mask
  2. 将检测框坐标从图像尺寸缩放到掩码尺寸
  3. 使用缩放后的检测框裁剪掩码,确保掩码与检测框对齐
  4. mask上采样要原图

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

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

相关文章

4.1.1 Spark SQL概述

Spark SQL是Apache Spark的一个模块&#xff0c;专门用于处理结构化数据。它引入了DataFrame这一编程抽象&#xff0c;DataFrame是带有Schema信息的分布式数据集合&#xff0c;类似于关系型数据库中的表。用户可以通过SQL、DataFrames API和Datasets API三种方式操作结构化数据…

华为OD机试真题——书籍叠放(2025A卷:200分)Java/python/JavaScript/C/C++/GO最佳实现

2025 A卷 200分 题型 本专栏内全部题目均提供Java、python、JavaScript、C、C++、GO六种语言的最佳实现方式; 并且每种语言均涵盖详细的问题分析、解题思路、代码实现、代码详解、3个测试用例以及综合分析; 本文收录于专栏:《2025华为OD真题目录+全流程解析+备考攻略+经验分…

尚硅谷redis7 63-69 redis哨兵监控之理论简介

63 redis哨兵监控之理论简介 什么是哨兵 master挂了如何办?从机原地待命。此时数据只能读取不能更新。因此需要&#xff1a; 吹哨人巡查监控后台master主机是否故障,如果故障了根据投票数自动将某一个从库转换为新主库, 哨兵的作用 1、监控redis运行状态,包括master和slave…

word文档格式规范(论文格式规范、word格式、论文格式、文章格式、格式prompt)

文章目录 prompt prompt [格式要求] - 字体&#xff1a;中文宋体小四&#xff1b;英文Times New Roman 12pt&#xff1b;标题黑体 - 行距&#xff1a;1.5倍&#xff08;段前段后0行&#xff09; - 边距&#xff1a;A4默认&#xff08;上下2.54cm&#xff0c;左右3.17cm&…

SpringBoot+tabula+pdfbox解析pdf中的段落和表格数据

一、前言 在日常业务需求中&#xff0c;往往会遇到解析pdf文件中的段落或者表格数据的需求。 常见的做法是使用 pdfbox 来做&#xff0c;但是它只能提取文本数据&#xff0c;没有我们在文件页面上面的那种结构化组织&#xff0c;文本通常是散乱的包含各种换行回车空格等格式&a…

【Elasticsearch】stored_fields

在 Elasticsearch 中&#xff0c;stored_fields 是一个非常重要的概念&#xff0c;主要用于控制文档存储和检索时的行为。以下是对 stored_fields 的详细解释&#xff1a; 1\. stored_fields 的作用 stored_fields 用于指定在检索文档时需要返回的字段。默认情况下&#xff0c;…

计算机网络 | 1.1 计算机网络概述思维导图

附大纲&#xff1a; 计算机网络的概念 一个通过通信设备与线路把不同计算机系统连接起来&#xff0c;实现资源共享和信息传递的系统 计算机网络的组成 从组成成分上 硬件&#xff1a;主机、通信链路、交换设备、通信处理机软件&#xff1a;网络操作系统、聊天软件等协议&…

HOW - 简历和求职面试宝典(三)

文章目录 1. 面试邀约2. 开始面试和自我介绍第一、面试前的准备工作第二、如何全面地介绍自己1. 面试邀约 第一、先认识日常HR 的工作流程 首先,电话沟通是 HR 核心工作内容的一部分。电话沟通分为两种:一种是电话预约;另外一种是电话确认。 电话预约很清晰,就是确认面试…

Java基础 Day24

一、进程和线程 1、进程 &#xff08;1&#xff09;概念 进程 (Process) 是计算机中的程序关于某数据集合上的一次运行活动 是系统进行资源分配的基本单位 简单理解&#xff1a;程序的执行过程&#xff08;正在运行的应用程序&#xff09; &#xff08;2&#xff09;特性…

C#学习:基于LLM的简历评估程序

前言 在pocketflow的例子中看到了一个基于LLM的简历评估程序的例子&#xff0c;感觉还挺好玩的&#xff0c;为了练习一下C#&#xff0c;我最近使用C#重写了一个。 准备不同的简历&#xff1a; 查看效果&#xff1a; 不足之处是现实的简历应该是pdf格式的&#xff0c;后面可以…

git怎么合并两个分支

git怎么合并分支代码 注意: 第一步你得把当前分支合到远程分支去才能有下面的操作 另外我是将develop分支代码合并到release分支去 git 命令 查看本地所有分支 git branch切换分支 例如切换到release分支 git checkout release拉取代码 git pull up release 合并分支 …

Android-kotlin协程学习总结

Kotlin协程实战对话​ ​真题1&#xff1a;协程与线程的本质区别是什么&#xff1f;为什么说协程是轻量级的&#xff1f;​​ ​面试官​&#xff1a; “我看你项目中用协程替代了线程池&#xff0c;能说说协程和线程的核心区别吗&#xff1f;为什么协程更适合高并发&#xf…

uni-app学习笔记十四-vue3中emit的使用

在组件传值中&#xff0c;无论是props还是slot都是单向数据流&#xff0c;父组件向子组件传值&#xff0c;子组件不能直接对父组件传过来的值进行重新赋值。 下面学习子组件向父组件传值的工具--emit。 在子组件emit设置传递的函数名和值 <template><view>子组件…

Java设计模式从基础到实际运用

第一部分&#xff1a;设计模式基础 1. 设计模式概述 设计模式(Design Pattern)是一套被反复使用、多数人知晓的、经过分类编目的代码设计经验的总结&#xff0c;它描述了在软件设计过程中一些不断重复出现的问题以及该问题的解决方案。设计模式是在特定环境下解决软件设计问题…

鸿蒙OSUniApp 制作自定义的进度条组件#三方框架 #Uniapp

使用 UniApp 制作自定义的进度条组件 在移动应用开发中&#xff0c;进度条是非常常见的 UI 组件&#xff0c;无论是文件上传、下载、任务进度还是表单填写反馈&#xff0c;进度条都能为用户提供直观的进度提示。虽然 UniApp 提供了一些基础的进度条能力&#xff0c;但在实际项…

Python爬虫实战:研究Beautiful Soup框架相关技术

1. 引言 1.1 研究背景与意义 随着互联网的快速发展,网络上的数据量呈爆炸式增长。如何从海量的网页数据中高效提取有价值的信息,成为信息科学领域的重要研究课题。网络爬虫作为一种自动获取网页内容的技术,能够按照预设规则遍历互联网并采集数据,为信息检索、舆情分析、商…

【Tips】关于PCI和PCIe的配置空间差异和io/memory io读写

最近在看同事2023年讲的PCI基础课&#xff0c;感觉确实是豁然开朗了&#xff0c;赞美同事。 PCIe实际上是PCI的扩展&#xff08;extended&#xff09;&#xff0c;PCIe设备相当于是迭代升级产品。 而PCIe的配置空间基于PCI原有的0xFF&#xff08;256字节&#xff09;配置空间…

桂花网体育运动监测方案:开启幼儿园运动健康管理新篇章

在幼儿教育领域&#xff0c;运动能力的培养与健康监测始终是备受关注的核心环节。随着科技的飞速发展&#xff0c;如何科学、有效地监测幼儿的运动状态&#xff0c;成为了幼儿园教育者面临的一大挑战。桂花网体育运动监测方案凭借其高效、精准、智能化的特性&#xff0c;为幼儿…

Perforce P4产品简介:无限扩展+全球协作+安全管控+工具集成(附下载)

本产品简介由Perforce中国授权合作伙伴——龙智编辑整理&#xff0c;旨在带您快速了解Perforce P4版本控制系统的强大之处。 世界级无限可扩展的版本控制系统 Perforce P4&#xff08;原Helix Core&#xff09;是业界领先的版本控制平台&#xff0c;备受19家全球Top20 AAA级游…

pikachu靶场通关笔记08 XSS关卡04-DOM型XSS

目录 一、XSS原理 二、DOM型XSS 三、源码分析 1、进入靶场 2、XSS探测 3、源码分析 四、渗透实战 1、Payload1 2、Payload2 3、Payload3 本系列为通过《pikachu靶场通关笔记》的XSS关卡(共10关&#xff09;渗透集合&#xff0c;通过对XSS关卡源码的代码审计找到XSS风…