YOLOv8 极简分割代码并输出各类别像素占比

文章目录

  • 前言
  • 功能概述
  • 必要环境
  • 一、代码结构
    • 1. 参数定义
    • 2. 定义检测器类
    • 3. 计算各类别像素占比
      • 3.1 遍历每个检测到的目标
      • 3.2 获取当前目标的掩码和类别
      • 3.3 将掩码转换为整数多边形
      • 3.4 创建空白掩码图像并填充多边形
      • 3.5 计算掩码像素数
      • 3.6 计算掩码多边形的质心
      • 3.7 计算像素占比并更新类别计数
      • 3.8 在结果图像上显示像素占比
      • 3.9 完整计算像素比代码
    • 4. 显示像素占比
  • 二、完整代码
  • 三、效果展示
  • 总结


前言

在计算机视觉领域,图像分割是一个重要的研究方向,它能帮助我们精确地提取图像中的各个目标物体,对于图像分析、自动驾驶等应用都具有重要意义。本文将介绍如何利用YOLOv8模型进行图像分割,并输出各类别像素占比。


功能概述

1. 选择需要分割的图像的文件夹
2. 加载 YOLOv8 模型并进行目标分割
3. 计算各类别像素占比
4. 可视化分割结果


必要环境

  1. 配置yolov8/10环境 可参考往期博客
    地址:https://blog.csdn.net/Dora_blank/article/details/139302363?spm=1001.2014.3001.5502

一、代码结构

1. 参数定义

parser = argparse.ArgumentParser()
# 分割参数
parser.add_argument('--seg_weights', default=r"yolov8n-seg.pt", type=str, help='segment weights path')
parser.add_argument('--source', default=r"test", type=str, help='img path')
parser.add_argument('--save', default=r"./save", type=str, help='save img or video path')
parser.add_argument('--conf_thre', type=float, default=0.5, help='conf_thre')
parser.add_argument('--iou_thre', type=float, default=0.5, help='iou_thre')
parser.add_argument('--vis', default=True, action='store_true', help='visualize image')
opt = parser.parse_args()
device = torch.device('cuda:0' if torch.cuda.is_available() else 'cpu')

参数作用如下:
–seg_weights:YOLOv8分割权重路径
–source:输入图像文件夹路径
–save:结果保存路径
–conf_thre:置信度阈值
–iou_thre:IoU阈值
–vis:可视化跟踪结果

2. 定义检测器类

初始化YOLOv8模型,设置分割参数,包含分割和绘制结果的功能

class Segmentor(object):def __init__(self, model_path, conf_threshold=0.5, iou_threshold=0.5, device='cpu'):self.device = deviceself.model = YOLO(model_path)self.conf_threshold = conf_thresholdself.iou_threshold = iou_thresholdself.names = self.model.namesself.classes = [self.names[key] for key in self.names.keys()]

3. 计算各类别像素占比

call 方法中,核心部分是对图像进行分割并计算各类别像素占比,下面将详细介绍这部分代码的实现

for idx in range(len(bboxes_cls)):mask = masks[idx]box_cls = int(bboxes_cls[idx])bbox_label = self.names[box_cls]mask_polygon = mask.astype(np.int32)mask_img = np.zeros(img.shape[:2], dtype=np.uint8)cv2.fillPoly(mask_img, [mask_polygon], 1)mask_pixels = np.sum(mask_img)M = cv2.moments(mask_polygon)if M["m00"] != 0:cx = int(M["m10"] / M["m00"])cy = int(M["m01"] / M["m00"])pixel_ratio = mask_pixels / total_pixelsclass_counts[bbox_label] += pixel_ratiocv2.putText(res, f'{pixel_ratio:.1%}', (cx, cy),cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 255, 0), 2)

3.1 遍历每个检测到的目标

bboxes_cls 包含了所有检测到的目标的类别索引,通过遍历它们,我们可以对每个目标进行处理

for idx in range(len(bboxes_cls)):

3.2 获取当前目标的掩码和类别

masks[idx] 获取当前目标的掩码,bboxes_cls[idx] 获取当前目标的类别索引并转换为整数,然后通过索引在 self.names 中获取类别标签

mask = masks[idx]
box_cls = int(bboxes_cls[idx])
bbox_label = self.names[box_cls]

3.3 将掩码转换为整数多边形

掩码数据通常是浮点数形式,为了绘制多边形,我们需要将其转换为整数

mask_polygon = mask.astype(np.int32)

3.4 创建空白掩码图像并填充多边形

创建一个与输入图像大小相同的空白掩码图像,然后使用 cv2.fillPoly 函数在掩码图像上填充多边形

mask_img = np.zeros(img.shape[:2], dtype=np.uint8)
cv2.fillPoly(mask_img, [mask_polygon], 1)

3.5 计算掩码像素数

通过对掩码图像求和,计算出掩码覆盖的像素数

mask_pixels = np.sum(mask_img)

3.6 计算掩码多边形的质心

使用 cv2.moments 计算多边形的矩,然后通过矩的计算公式得到质心坐标 (cx, cy)

M = cv2.moments(mask_polygon)
if M["m00"] != 0:cx = int(M["m10"] / M["m00"])cy = int(M["m01"] / M["m00"])

3.7 计算像素占比并更新类别计数

计算掩码像素数占总像素数的比例,并将其添加到 class_counts 字典中对应类别的计数中

pixel_ratio = mask_pixels / total_pixels
class_counts[bbox_label] += pixel_ratio

3.8 在结果图像上显示像素占比

使用 cv2.putText 在结果图像的质心位置显示当前目标的像素占比

cv2.putText(res, f'{pixel_ratio:.1%}', (cx, cy),cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 255, 0), 2)

3.9 完整计算像素比代码

    for idx in range(len(bboxes_cls)):mask = masks[idx]box_cls = int(bboxes_cls[idx])bbox_label = self.names[box_cls]mask_polygon = mask.astype(np.int32)mask_img = np.zeros(img.shape[:2], dtype=np.uint8)cv2.fillPoly(mask_img, [mask_polygon], 1)mask_pixels = np.sum(mask_img)M = cv2.moments(mask_polygon)if M["m00"] != 0:cx = int(M["m10"] / M["m00"])cy = int(M["m01"] / M["m00"])pixel_ratio = mask_pixels / total_pixelsclass_counts[bbox_label] += pixel_ratiocv2.putText(res, f'{pixel_ratio:.1%}', (cx, cy),cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 255, 0), 2)

4. 显示像素占比

在完成图像分割和像素占比计算后,接下来我们要在图像上显示每个类别的像素占比信息

text_start_y = 35
for key, value in class_counts.items():label = f'{key}: {value:.1%}'print(label)cv2.putText(res, label, (20, text_start_y),cv2.FONT_HERSHEY_COMPLEX, 1.2, (0, 255, 0), thickness=3)text_start_y += 35
return res

二、完整代码

完整代码如下:

# -*- coding:utf-8 -*-
import cv2
from ultralytics import YOLO
import argparse
import torch
from collections import defaultdict
import os
import numpy as npparser = argparse.ArgumentParser()
# 分割参数
parser.add_argument('--seg_weights', default=r"yolov8n-seg.pt", type=str, help='segment weights path')
parser.add_argument('--source', default=r"test", type=str, help='img path')
parser.add_argument('--save', default=r"./save", type=str, help='save img or video path')
parser.add_argument('--conf_thre', type=float, default=0.5, help='conf_thre')
parser.add_argument('--iou_thre', type=float, default=0.5, help='iou_thre')
parser.add_argument('--vis', default=True, action='store_true', help='visualize image')
opt = parser.parse_args()
device = torch.device('cuda:0' if torch.cuda.is_available() else 'cpu')class Segmentor(object):def __init__(self, model_path, conf_threshold=0.5, iou_threshold=0.5, device='cpu'):self.device = deviceself.model = YOLO(model_path)self.conf_threshold = conf_thresholdself.iou_threshold = iou_thresholdself.names = self.model.namesself.classes = [self.names[key] for key in self.names.keys()]def __call__(self, img):class_counts = defaultdict(int)total_pixels = img.shape[0] * img.shape[1]result = self.model(img, verbose=False, conf=self.conf_threshold,iou=self.iou_threshold, device=self.device)[0]res = result.plot()  # 可视化bboxes_cls = result.boxes.clsmasks = result.masks.xyfor idx in range(len(bboxes_cls)):mask = masks[idx]box_cls = int(bboxes_cls[idx])bbox_label = self.names[box_cls]mask_polygon = mask.astype(np.int32)mask_img = np.zeros(img.shape[:2], dtype=np.uint8)cv2.fillPoly(mask_img, [mask_polygon], 1)mask_pixels = np.sum(mask_img)M = cv2.moments(mask_polygon)if M["m00"] != 0:cx = int(M["m10"] / M["m00"])cy = int(M["m01"] / M["m00"])pixel_ratio = mask_pixels / total_pixelsclass_counts[bbox_label] += pixel_ratiocv2.putText(res, f'{pixel_ratio:.1%}', (cx, cy),cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 255, 0), 2)text_start_y = 35for key, value in class_counts.items():label = f'{key}: {value:.1%}'print(label)cv2.putText(res, label, (20, text_start_y),cv2.FONT_HERSHEY_COMPLEX, 1.2, (0, 255, 0), thickness=3)text_start_y += 35return res# Example usage
if __name__ == '__main__':model = Segmentor(opt.seg_weights, conf_threshold=opt.conf_thre, iou_threshold=opt.iou_thre)images_format = ['.png', '.jpg', '.jpeg', '.JPG', '.PNG', '.JPEG']image_names = [name for name in os.listdir(opt.source) for item in images_format ifos.path.splitext(name)[1] == item]for img_name in image_names:img_path = os.path.join(opt.source, img_name)img_ori = cv2.imread(img_path)img_vis = model(img_ori)img_vis = cv2.resize(img_vis, None, fx=1.0, fy=1.0, interpolation=cv2.INTER_NEAREST)cv2.imwrite(os.path.join(opt.save, img_name), img_vis)if opt.vis:cv2.imshow(img_name, img_vis)cv2.waitKey(0)cv2.destroyAllWindows()

三、效果展示

在这里插入图片描述
在这里插入图片描述


总结

本期博客就到这里啦,喜欢的小伙伴们可以点点关注,感谢!

最近经常在b站上更新一些有关目标检测的视频,大家感兴趣可以来看看 https://b23.tv/1upjbcG

学习交流群:995760755

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

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

相关文章

发光二极管十大品牌

日常电路设计中,LED是必用的元器件之一,辅助判定电路异常。 十大发光二极管品牌-LED灯珠生产厂家哪家好-LED发光二极管厂家前十-Maigoo品牌榜

Zabbix6.0自定义监控项

文章目录 一、自定义监控整体流程二、自定义监控案例1、监控TCP 443端口案例2、监控服务器异地登入(带参监控项) 一、自定义监控整体流程 操作端流程备注Agent端1️⃣ linux:通过命令、脚本取出对应的值2️⃣ linux:根据zbx要求按照格式、编写配置文件、…

Sui Generis如何为艺术家弥合Web3的鸿沟

Sui Generis是一家于3月推出的NFT拍卖行,其联合创始人兼CEO Gab9说其愿景是——更好、更大、更强! 表面上看,Sui Generis是备受欢迎的Tombheads NFT拍卖行的重新品牌化,该拍卖行今年早些时候从Fantom区块链迁移出来。但它于3月31…

找出链表倒数第k个元素-链表题

LCR 140. 训练计划 II - 力扣(LeetCode) 快慢指针。快指针臂慢指针快cnt个元素到最后; class Solution { public:ListNode* trainingPlan(ListNode* head, int cnt) {struct ListNode* quick head;struct ListNode* slow head;for(int i …

如何学习Golang语言!

第一部分:Go语言概述 起源与设计哲学:Go语言由Robert Griesemer、Rob Pike和Ken Thompson三位Google工程师设计,旨在解决现代编程中的一些常见问题,如编译速度、运行效率和并发编程。主要特点:Go语言的语法简单、编译…

人体部位眼耳手腿分类数据集4376张4类别

数据集类型:图像分类用,不可用于目标检测无标注文件 数据集格式:仅仅包含jpg图片,每个类别文件夹下面存放着对应图片 图片数量(jpg文件个数):4376 分类类别数:4 类别名称:["Ears","Eyes&quo…

计算机组成刷题一轮(包过版)

搭配食用 计算机组成原理一轮-CSDN博客 目录 一、计算机系统概述 选择 计算机系统组成 冯诺依曼机 软件和硬件的功能 CPU等概念 计算机系统的工作原理 机器字长 运行速度 求MIPS 编译程序 机器语言程序 平均CPI和CPU执行时间 综合应用 存储程序原理 二…

System Verilog实现流水灯

文章目录 一 System Verilog1.1 Systemverilog简介1.2 与verilog的区别1.2.1 两态数据类型(1,0)1.2.2 枚举类型和用户自定义类型1.2.3 数组与队列1.2.4 字符串1.2.5 结构体和联合体1.2.6 常量1.2.7 过程语句等等 二 流水灯代码三 实验效果总结参考资料 一…

基于睡眠声音评估睡眠质量

随着健康意识的增强,人们越来越关注睡眠质量。确保获得充足的高质量睡眠对于维持身体健康和心理平衡至关重要。专业的睡眠状态测量主要通过多导睡眠图(PSG)进行。然而,PSG会给受试者带来显著的身体负担,并且在没有专业…

十大人工智能企业

​​​​​​链接:​​​​​​人工智能品牌排行-人工智能十大公司-人工智能十大品牌-Maigoo品牌榜

C# WPF入门学习主线篇(二十一)—— 静态资源和动态资源

C# WPF入门学习主线篇(二十一)—— 静态资源和动态资源 欢迎来到C# WPF入门学习系列的第二十一篇。在上一章中,我们介绍了WPF中的资源和样式。本篇文章将深入探讨静态资源(StaticResource)和动态资源(Dynam…

数据挖掘--认识数据

数据挖掘--引论 数据挖掘--认识数据 数据挖掘--数据预处理 数据挖掘--数据仓库与联机分析处理 数据挖掘--挖掘频繁模式、关联和相关性:基本概念和方法 数据挖掘--分类 数据挖掘--聚类分析:基本概念和方法 数据对象与属性类型 属性:是一…

# log.info(“消息发送成功“); 红色报错 解决方案

log.info(“消息发送成功”); 红色报错 解决方案 一、错误描述: 在使用 idea 创建 maven 项目导入 lombok 依赖时,出现 log.info 报红错误,检查导入依赖正确,网络正常,错误依旧。 二、解决方案: 1、在 i…

【Java毕业设计】基于JavaWeb的洗衣店管理系统

文章目录 摘要ABSTRACT目 录1 概述1.1 研究背景及意义1.2 国内外研究现状1.3 拟研究内容1.4 系统开发技术1.4.1 SpringBoot框架1.4.2 MySQL数据库1.4.3 MVC模式 2 系统需求分析2.1 可行性分析2.2 功能需求分析 3 系统设计3.1 功能模块设计3.2 系统流程设计3.3 数据库设计3.3.1 …

嵌入式中C语言经典的面试题分享

#error的作用是什么? #error 指令让预处理器发出一条错误信息,并且会中断编译过程。下面我们从Linux代码中抽取出来一小段代码并做修改得到示例代码: 这段示例代码很简单,当RX_BUF_IDX宏的值不为0~3时,在预处理阶段就会通过 #error 指令输出一条错误提示信息: "…

GPT-4与GPT-4O的区别详解:面向小白用户

1. 模型介绍 在人工智能的语言模型领域,OpenAI的GPT-4和GPT-4O是最新的成员。这两个模型虽然来源于相同的基础技术,但在功能和应用上有着明显的区别。 GPT-4:这是一个通用型语言模型,可以理解和生成自然语言。无论是写作、对话还…

【Python】探索 One-Class SVM:异常检测的利器

我已经从你的 全世界路过 像一颗流星 划过命运 的天空 很多话忍住了 不能说出口 珍藏在 我的心中 只留下一些回忆 🎵 牛奶咖啡《从你的全世界路过》 在数据科学和机器学习领域,异常检测(Anomaly Detection)是…

Mysql学习(七)——约束

文章目录 四、约束4.1 概述4.2 约束演示4.3 外键约束 总结 四、约束 4.1 概述 概念:约束是作用于表中字段上的规则,用于限制存储在表中的数据。目的:保证数据库中数据的正确、有效性和完整性。分类: 4.2 约束演示 根据需求&…

著名AI人工智能社会学家唐兴通谈数字社会学网络社会学主要矛盾与数字空间社会网络社会的基本议题与全球海外最新热点与关注社会结构社会分工数字财富数字游民数字经济

如果人工智能解决了一切,人类会做什么? 这个问题的背后是人工智能时代的社会主要矛盾会是什么?那么整个社会的大的分工体系就会围绕主要矛盾开展。 《人工智能社会主要矛盾》 在农业社会,主要矛盾是人口增长和土地资源之间的关…

【日常记录】【JS】中文转拼音的库 pinyin-pro

文章目录 1、介绍2、pinyin-pro 基本使用3、参考链接 1、介绍 pinyin-pro 是一个专业的 JavaScript 中文转拼音的库,具备多音字识别准确、体积轻量、性能优异、功能丰富等特点。 常用的案例 搜索功能增强:在输入框输入汉字时,可以转化为拼音输…