当前位置: 首页 > article >正文

yolov5-seg分割后处理流程

在 YOLOv5s-seg 模型中,分割后处理的目的是将模型的原始输出(包括检测框、类别概率和掩码系数)转换为最终的实例分割结果。以下是使用 Python 实现分割后处理的完整代码示例:


1. 分割后处理步骤

  1. 解析模型输出
    • 从模型输出中提取检测框、类别概率和掩码系数。
  2. 过滤低置信度的检测框
    • 使用置信度阈值过滤掉低置信度的检测框。
  3. 非极大值抑制(NMS)
    • 去除重叠的检测框,保留最优的检测结果。
  4. 生成实例分割掩码
    • 使用掩码系数和掩码原型生成每个检测框的分割掩码。
  5. 调整掩码分辨率并裁剪
    • 将掩码调整到检测框的实际大小,并裁剪到检测框范围。

2. 完整代码实现

import numpy as np
import torch
import cv2

def seg_postprocess(output, mask_prototypes, conf_thres=0.25, iou_thres=0.45, img_size=640):
    """
    YOLOv5s-seg 分割后处理函数。

    参数:
        output: 模型原始输出,形状为 (1, 25200, 117)。
        mask_prototypes: 掩码原型,形状为 (32, 160, 160)。
        conf_thres: 置信度阈值。
        iou_thres: NMS 的 IoU 阈值。
        img_size: 输入图像的尺寸。

    返回:
        boxes: 检测框,形状为 (N, 4),格式为 (x1, y1, x2, y2)。
        scores: 置信度分数,形状为 (N,)。
        labels: 类别标签,形状为 (N,)。
        masks: 实例分割掩码,形状为 (N, H, W)。
    """
    # 1. 解析模型输出
    preds = output[0]  # (25200, 117)
    boxes = preds[:, :4]  # 检测框 (x_center, y_center, width, height)
    scores = preds[:, 4]  # 置信度分数
    class_probs = preds[:, 5:85]  # 类别概率 (80 个类别)
    mask_coefficients = preds[:, 85:]  # 掩码系数 (32 个)

    # 2. 过滤低置信度的检测框
    keep = scores > conf_thres
    boxes = boxes[keep]
    scores = scores[keep]
    class_probs = class_probs[keep]
    mask_coefficients = mask_coefficients[keep]

    # 3. 非极大值抑制 (NMS)
    keep = nms(boxes, scores, iou_thres)
    boxes = boxes[keep]
    scores = scores[keep]
    class_probs = class_probs[keep]
    mask_coefficients = mask_coefficients[keep]

    # 4. 生成实例分割掩码
    masks = generate_masks(mask_coefficients, mask_prototypes, boxes, img_size)

    # 5. 返回结果
    labels = np.argmax(class_probs, axis=1)  # 类别标签
    return boxes, scores, labels, masks


def nms(boxes, scores, iou_thres):
    """
    非极大值抑制 (NMS)。

    参数:
        boxes: 检测框,形状为 (N, 4),格式为 (x1, y1, x2, y2)。
        scores: 置信度分数,形状为 (N,)。
        iou_thres: IoU 阈值。

    返回:
        keep: 保留的检测框索引。
    """
    x1 = boxes[:, 0]
    y1 = boxes[:, 1]
    x2 = boxes[:, 2]
    y2 = boxes[:, 3]

    areas = (x2 - x1) * (y2 - y1)
    order = scores.argsort()[::-1]

    keep = []
    while order.size > 0:
        i = order[0]
        keep.append(i)
        xx1 = np.maximum(x1[i], x1[order[1:]])
        yy1 = np.maximum(y1[i], y1[order[1:]])
        xx2 = np.minimum(x2[i], x2[order[1:]])
        yy2 = np.minimum(y2[i], y2[order[1:]])

        w = np.maximum(0, xx2 - xx1)
        h = np.maximum(0, yy2 - yy1)
        inter = w * h
        iou = inter / (areas[i] + areas[order[1:]] - inter)

        inds = np.where(iou <= iou_thres)[0]
        order = order[inds + 1]

    return keep


def generate_masks(mask_coefficients, mask_prototypes, boxes, img_size):
    """
    生成实例分割掩码。

    参数:
        mask_coefficients: 掩码系数,形状为 (N, 32)。
        mask_prototypes: 掩码原型,形状为 (32, 160, 160)。
        boxes: 检测框,形状为 (N, 4),格式为 (x1, y1, x2, y2)。
        img_size: 输入图像的尺寸。

    返回:
        masks: 实例分割掩码,形状为 (N, H, W)。
    """
    masks = []
    for i in range(len(boxes)):
        # 1. 加权组合掩码原型
        mask = np.sum(mask_coefficients[i][:, None, None] * mask_prototypes, axis=0)  # (160, 160)

        # 2. 调整掩码分辨率到检测框大小
        x1, y1, x2, y2 = boxes[i]
        mask = cv2.resize(mask, (int(x2 - x1), int(y2 - y1)), interpolation=cv2.INTER_LINEAR)

        # 3. 将掩码裁剪到检测框范围
        full_mask = np.zeros((img_size, img_size))
        full_mask[int(y1):int(y2), int(x1):int(x2)] = mask
        masks.append(full_mask)

    return np.array(masks)


# 示例用法
if __name__ == "__main__":
    # 假设模型输出和掩码原型已经加载
    output = np.random.randn(1, 25200, 117)  # 模型原始输出
    mask_prototypes = np.random.randn(32, 160, 160)  # 掩码原型

    # 执行分割后处理
    boxes, scores, labels, masks = seg_postprocess(output, mask_prototypes)

    # 打印结果
    print("检测框:", boxes)
    print("置信度分数:", scores)
    print("类别标签:", labels)
    print("实例分割掩码形状:", masks.shape)

3. 代码说明

  1. seg_postprocess 函数
    • 解析模型输出,过滤低置信度的检测框,执行 NMS,并生成实例分割掩码。
  2. nms 函数
    • 实现非极大值抑制,去除重叠的检测框。
  3. generate_masks 函数
    • 使用掩码系数和掩码原型生成实例分割掩码,并调整掩码分辨率。

4. 注意事项

  • 掩码原型的形状和分辨率需要与模型配置一致。
  • 输入图像的尺寸(img_size)需要与模型输入尺寸一致。
  • 代码中的 mask_prototypes 需要从模型中加载。


http://www.kler.cn/a/550976.html

相关文章:

  • DeepSeek 开放平台无法充值 改用其他平台API调用DeepSeek-chat模型方法
  • 跨平台AES/DES加密解密算法【超全】
  • 数据库加密全解析:从传输到存储的安全实践
  • VScode内接入deepseek包过程(本地部署版包会)
  • 腾讯的webUI怎样实现deepseek外部调用 ; 腾讯云通过API怎样调用deepseek
  • 解决 nodejs 设置cors 不生效问题
  • Linux nohup
  • Ruby语言的移动应用开发
  • 本地部署Anything LLM+Ollama+DeepSeek R1打造AI智能知识库教程
  • 【C++ 算法竞赛函数速查表】
  • 盛铂科技 SCP4006/4018/4040:国产袖珍式功率计 射频微波功率探头 平均功率计
  • 智能猫眼实现流程图
  • 基于SpringBoot的医院药房管理系统【源码+答辩PPT++项目部署】高质量论文1-1.5W字
  • 提示工程(Prompt Engineering)的进阶策略与实践指南
  • 人工智能神经网络
  • WebP2P+自研回音消除:视频通话SDK嵌入式EasyRTC构建高交互性音视频应用
  • 《StyleDiffusion:通过扩散模型实现可控的解耦风格迁移》学习笔记
  • 摄像头畸变矫正
  • 【力扣】105.从前序与中序遍历序列构造二叉树
  • 多层代理模式解析Invocation