实现YOLO V3数据加载器:从文件系统读取图像与标签
引言
在深度学习项目中,数据准备是非常重要的一环。特别是在物体检测任务中,数据的组织和预处理直接影响到模型的训练效果。YOLO V3(You Only Look Once Version 3)作为一种高效的实时物体检测框架,其数据加载器的设计对于确保模型训练的顺利进行至关重要。本文将详细介绍如何使用Python和PyTorch实现一个YOLO V3的数据加载器,以支持从文件系统中读取图像及其对应的标签文件,并进行必要的预处理。
数据集组织
首先,我们需要了解数据集是如何组织的。通常情况下,图像数据集会被分成两个主要的部分:
- 图像文件:这些文件通常保存在磁盘上,并且每张图像都有一个对应的文件名。
- 标签文件:与图像文件一一对应,每个标签文件记录了图像中物体的位置和类别信息。
标签文件通常是以文本格式存储的,每一行代表一个物体的边界框信息,格式为 类别 中心点X 中心点Y 宽度 高度。这些值通常是归一化的,即相对于图像的宽度和高度而言。
数据加载器实现
为了实现YOLO V3的数据加载器,我们需要创建一个继承自torch.utils.data.Dataset的类,并重写其__init__、__len__和__getitem__方法。此外,我们还需要定义一些辅助函数来处理图像的预处理工作,如填充、调整大小等。
导入必要的库
import glob
import random
import os
import numpy as np
from PIL import Image
import torch
import torch.nn.functional as F
from torch.utils.data import Dataset
import torchvision.transforms as transforms
这段代码导入了构建数据加载器所需的库,包括文件处理、图像处理、张量操作等。
辅助函数定义
pad_to_square 函数
# 定义将图像填充为正方形的函数
def pad_to_square(img, pad_value):# 获取图像的通道数、高度和宽度c, h, w = img.shape# 计算高度和宽度的差值dim_diff = np.abs(h - w)# 计算需要在较短边填充的数量pad1, pad2 = dim_diff // 2, dim_diff - dim_diff // 2# 根据高度和宽度确定填充的方向(左侧/右侧 或 上侧/下侧)pad = (0, 0, pad1, pad2) if h <= w else (pad1, pad2, 0, 0)# 对图像进行填充img = F.pad(img, pad, "constant", value=pad_value)return img, pad
此函数将图像填充为正方形,以便后续处理。它计算图像的高度和宽度之差,并据此决定在哪个方向上添加填充。
resize 函数
# 定义调整图像大小的函数
def resize(image, size):# 使用最近邻插值调整图像大小image = F.interpolate(image.unsqueeze(0), size=size, mode="nearest").squeeze(0)return image
此函数将图像调整为指定的大小。它首先将图像的维度扩展到 (1, C, H, W),然后使用最近邻插值进行缩放,最后再压缩回原来的维度。
数据集类定义
ListDataset 类
# 定义数据集类
class ListDataset(Dataset):# 初始化方法def __init__(self, list_path, img_size=416, augment=True, multiscale=True, normalized_labels=True):# 读取包含图像路径的列表文件with open(list_path, "r") as file:self.img_files = file.readlines()# 根据图像路径找到对应的标签文件路径self.label_files = [path.replace("images", "labels").replace(".png", ".txt").replace(".jpg", ".txt")for path in self.img_files]# 设置图像大小self.img_size = img_size# 最大对象数量self.max_objects = 100# 是否启用数据增强self.augment = augment# 是否启用多尺度训练self.multiscale = multiscale# 标签是否已经归一化self.normalized_labels = normalized_labels# 设置图像大小的最小值和最大值self.min_size = self.img_size - 3 * 32self.max_size = self.img_size + 3 * 32# 用于追踪批次计数self.batch_count = 0
这是数据集类的初始化方法,它读取包含图像路径的列表文件,并根据图像路径找到对应的标签文件路径。
__getitem__ 方法
# 获取数据集中指定索引的项目def __getitem__(self, index):# 获取图像路径img_path = self.img_files[index % len(self.img_files)].rstrip()# 读取图像并转换为张量img = transforms.ToTensor()(Image.open(img_path).convert('RGB'))# 如果图像不是三通道,则扩展为三通道if len(img.shape) != 3:img = img.unsqueeze(0)img = img.expand((3, img.shape[1:]))# 获取图像的高度和宽度_, h, w = img.shape# 计算填充因子h_factor, w_factor = (h, w) if self.normalized_labels else (1, 1)# 将图像填充为正方形img, pad = pad_to_square(img, 0)# 获取填充后的图像的高度和宽度_, padded_h, padded_w = img.shape# 获取标签文件路径label_path = self.label_files[index % len(self.img_files)].rstrip()targets = Noneif os.path.exists(label_path):# 读取标签文件boxes = torch.from_numpy(np.loadtxt(label_path).reshape(-1, 5))# 计算边界框的真实坐标x1 = w_factor * (boxes[:, 1] - boxes[:, 3] / 2)y1 = h_factor * (boxes[:, 2] - boxes[:, 4] / 2)x2 = w_factor * (boxes[:, 1] + boxes[:, 3] / 2)y2 = h_factor * (boxes[:, 2] + boxes[:, 4] / 2)# 考虑到填充的影响,调整边界框坐标x1 += pad[0]y1 += pad[2]x2 += pad[1]y2 += pad[3]# 重新归一化边界框坐标boxes[:, 1] = ((x1 + x2) / 2) / padded_wboxes[:, 2] = ((y1 + y2) / 2) / padded_hboxes[:, 3] *= w_factor / padded_wboxes[:, 4] *= h_factor / padded_h# 创建目标张量targets = torch.zeros((len(boxes), 6))targets[:, 1:] = boxes# 应用数据增强if self.augment and np.random.random() < 0.5:img, targets = horisontal_flip(img, targets)return img_path, img, targets
此方法用于获取数据集中单个样本。它读取图像,进行必要的预处理(如转换为张量、填充至正方形、调整大小),并读取对应的标签文件,调整边界框坐标以适应图像处理后的变化。
collate_fn 方法
# 用于处理一批数据的方法def collate_fn(self, batch):# 解压批次数据paths, imgs, targets = zip(*batch)# 移除空的占位标签targets = [boxes for boxes in targets if boxes is not None]# 给每个目标添加样本索引for i, boxes in enumerate(targets):boxes[:, 0] = i# 合并所有目标targets = torch.cat(targets, 0)# 每十个批次选择一个新的图像大小if self.multiscale and self.batch_count % 10 == 0:self.img_size = random.choice(range(self.min_size, self.max_size + 1, 32))# 调整图像大小imgs = torch.stack([resize(img, self.img_size) for img in imgs])# 更新批次计数self.batch_count += 1return paths, imgs, targets
此方法用于处理从数据集中获取的一批数据。它合并不同样本的标签,并根据需要调整图像大小。
__len__ 方法
# 返回数据集中样本的数量def __len__(self):return len(self.img_files)
返回数据集中样本的数量。
相关文章:
实现YOLO V3数据加载器:从文件系统读取图像与标签
引言 在深度学习项目中,数据准备是非常重要的一环。特别是在物体检测任务中,数据的组织和预处理直接影响到模型的训练效果。YOLO V3(You Only Look Once Version 3)作为一种高效的实时物体检测框架,其数据加载器的设计…...
安装pygod
了解pygod。 It is recommended to use pip for installation. Please make sure the latest version is installed, as PyGOD is updated frequently: pip install pygod # normal install pip install --upgrade pygod # or update if needed如果pip不是最新的&…...
探索Python与Excel的无缝对接:xlwings库的神秘面纱
文章目录 探索Python与Excel的无缝对接:xlwings库的神秘面纱1. 背景介绍:为何选择xlwings?2. xlwings是什么?3. 如何安装xlwings?4. 简单的库函数使用方法打开工作簿创建工作簿读取单元格数据写入单元格数据保存并关闭…...
CISE|暴雨受邀出席第二十六届中国国际软件博览会
10月24日至26日,备受瞩目的第二十六届中国国际软件博览会(简称CISE)在国家会展中心(天津)圆满举办。CISE不仅汇聚了来自全国各地的顶尖软件企业和机构,还吸引了众多专家学者和行业精英共襄盛举,…...
OpenEuler22.03-sp2下安装docker-非常实用
1、确定系统版本是openEuler22.03-SP2 [root192 ~]# wget https://download.docker.com/linux/static/stable/x86_64/docker-20.10.23.tgz #或者自己下载之后上传到/root下,测试最好是自己下载到本地再上传到服务器上 下载地址:https://download.dock…...
【学术会议论文投稿】前端框架巅峰对决:React、Vue与Angular的全面解析与实战指南
【JPCS独立出版】第三届能源与动力工程国际学术会议(EPE 2024)_艾思科蓝_学术一站式服务平台 更多学术会议请看:https://ais.cn/u/nuyAF3 引言 在快速发展的前端技术领域,选择合适的框架或库对于项目的成功至关重要。React、Vu…...
[0152].第3节:IDEA中工程与模块
我的后端学习大纲 IDEA大纲 1、Project和Module的概念: 2、Module操作: 2.1.创建Module: 2.2.删除Module: 2.3.导入Module: 1.导入外来模块的代码: 查看Project Structure,选择import module:…...
【modbus协议】libmodbus库移植基于linux平台
文章目录 下载库函数源码编译路径添加libmodbus 源码分析核心数据结构常用接口函数 开发 TCP Server 端开发TCP Client 端 下载库函数源码 编译路径添加 libmodbus 源码分析 核心数据结构 modbus_t结构体: 这是 libmodbus 的核心数据结构,代表一个 Mod…...
SpringBoot+Minio实现多文件下载和批量下载
文章目录 SpringBoot+minio实现多文件下载1、SpringBoot+minio实现多文件打成一个压缩包下载1. 添加依赖2. 配置 MinIO 客户端3. 创建下载和压缩逻辑4. 创建控制器方法来触发下载5. 测试下载功能注意事项2、在minio指定的桶名下面生产一个文件夹1. MinIO 配置2. 编写业务逻辑文…...
3.swoole安装【Docker】
一、拉取最新 swoole 镜像 docker pull phpswoole/swoole二、第一次启动swoole容器 docker run --name swoole phpswoole/swoole 三、 拷贝配置文件 docker cp swoole:/var/www /docker/swoole四、 停止 swoole 容器 dcoker stop swoole五、 删除第一次启动的swoole容器 d…...
React 探秘(三): 时间切片
文章目录 背景时间切片原理requestIderCallback 方法setImmediateMessageChannelsetTimeout React 18 时间切片源码手撸时间切片问题拆解构建任务队列宏任务包装首次开启任务递归任务执行workLoop 开启工作循环demo 模拟 总结 背景 前文学习了 fiber 架构和双缓存技术ÿ…...
OSError: Can‘t load tokenizer for ‘bert-base-uncased‘.
一、具体报错: 报错如下: OSError: Cant load tokenizer for bert-base-uncased. If you were trying to load it from https://huggingface.co/models, make sure you dont have a local directory with the same name. Otherwise, make sure bert-bas…...
中国人寿财险青岛市分公司:专业团队,卓越服务
中国人寿财险青岛市分公司拥有一支专业的团队,为客户提供卓越的保险服务。 公司的保险从业人员都经过严格的专业培训和考核,具备扎实的保险知识和丰富的实践经验。他们以客户为中心,用心倾听客户需求,为客户提供个性化的保险方案…...
【SpringCloud】基础问题
文章目录 spring-cloud-dependencies和spring-cloud-alibaba-dependencies的区别<dependencyManagement>和<dependencies>的区别<dependencyManagement><dependencies> 为什么在主函数上加上SpringBootApplication注解就可以扫描到对象为什么bootstrap…...
牛客网刷题(1)(java之数据类型、数组的创建(静态/动态初始化)、static关键字与静态属性和方法、常用的servlet包、面向对象程序设计方法优点)
目录 一、Java变量的数据类型。 <1>Java中变量的数据类型。 <2>基本数据类型。 <3>引用数据类型。 二、Java中一维数组的初始化。(静态、动态初始化) <1>数组。 <2>动态初始化。 <3>静态初始化。 三、看清代码后&am…...
电磁干扰(EMI)与电磁兼容性(EMC)【小登培训】
电磁干扰(EMI)和电磁兼容性(EMC)是每个产品在3C ,CE认证过程中必不可少的测试项目: 一、电磁干扰(EMI) EMI(Electromagnetic Interference)是指电子设备在工作…...
保险行业的智能客服:企业AI助理与知识库的加速效应
在保险行业,客户服务是企业与客户之间建立信任与忠诚度的关键桥梁。随着人工智能技术的飞速发展,企业AI助理正逐步成为保险客服领域的重要革新力量。 一、AI助理:保险客服的新篇章 企业AI助理,以其强大的自然语言处理能力、数据分…...
PSINS工具箱函数介绍——inserrplot
关于工具箱 i n s e r r p l o t inserrplot in...
龙蟠科技业绩压力显著:资产负债率持续攀升,产能利用率也不乐观
《港湾商业观察》施子夫 黄懿 去年十月至今两度递表后,10月17日,江苏龙蟠科技股份有限公司(以下简称,龙蟠科技;603906.SH,02465.HK)通过港交所主板上市聆讯。 很快,龙蟠科技发布公告称,公司全…...
使用 Spring Cloud 有什么优势?
使用 Spring Cloud 有什么优势? 在当今的微服务架构时代,Spring Cloud 作为一个强大的开发框架,备受开发者青睐。那么,使用 Spring Cloud 究竟有哪些优势呢? 一、微服务架构简介 微服务架构是一种将单一应用程序拆分…...
XML Group端口详解
在XML数据映射过程中,经常需要对数据进行分组聚合操作。例如,当处理包含多个物料明细的XML文件时,可能需要将相同物料号的明细归为一组,或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码,增加了开…...
python打卡day49
知识点回顾: 通道注意力模块复习空间注意力模块CBAM的定义 作业:尝试对今天的模型检查参数数目,并用tensorboard查看训练过程 import torch import torch.nn as nn# 定义通道注意力 class ChannelAttention(nn.Module):def __init__(self,…...
从深圳崛起的“机器之眼”:赴港乐动机器人的万亿赛道赶考路
进入2025年以来,尽管围绕人形机器人、具身智能等机器人赛道的质疑声不断,但全球市场热度依然高涨,入局者持续增加。 以国内市场为例,天眼查专业版数据显示,截至5月底,我国现存在业、存续状态的机器人相关企…...
【算法训练营Day07】字符串part1
文章目录 反转字符串反转字符串II替换数字 反转字符串 题目链接:344. 反转字符串 双指针法,两个指针的元素直接调转即可 class Solution {public void reverseString(char[] s) {int head 0;int end s.length - 1;while(head < end) {char temp …...
Spring Boot面试题精选汇总
🤟致敬读者 🟩感谢阅读🟦笑口常开🟪生日快乐⬛早点睡觉 📘博主相关 🟧博主信息🟨博客首页🟫专栏推荐🟥活动信息 文章目录 Spring Boot面试题精选汇总⚙️ **一、核心概…...
MySQL中【正则表达式】用法
MySQL 中正则表达式通过 REGEXP 或 RLIKE 操作符实现(两者等价),用于在 WHERE 子句中进行复杂的字符串模式匹配。以下是核心用法和示例: 一、基础语法 SELECT column_name FROM table_name WHERE column_name REGEXP pattern; …...
Linux 中如何提取压缩文件 ?
Linux 是一种流行的开源操作系统,它提供了许多工具来管理、压缩和解压缩文件。压缩文件有助于节省存储空间,使数据传输更快。本指南将向您展示如何在 Linux 中提取不同类型的压缩文件。 1. Unpacking ZIP Files ZIP 文件是非常常见的,要在 …...
Ubuntu Cursor升级成v1.0
0. 当前版本低 使用当前 Cursor v0.50时 GitHub Copilot Chat 打不开,快捷键也不好用,当看到 Cursor 升级后,还是蛮高兴的 1. 下载 Cursor 下载地址:https://www.cursor.com/cn/downloads 点击下载 Linux (x64) ,…...
深入浅出Diffusion模型:从原理到实践的全方位教程
I. 引言:生成式AI的黎明 – Diffusion模型是什么? 近年来,生成式人工智能(Generative AI)领域取得了爆炸性的进展,模型能够根据简单的文本提示创作出逼真的图像、连贯的文本,乃至更多令人惊叹的…...
Axure零基础跟我学:展开与收回
亲爱的小伙伴,如有帮助请订阅专栏!跟着老师每课一练,系统学习Axure交互设计课程! Axure产品经理精品视频课https://edu.csdn.net/course/detail/40420 课程主题:Axure菜单展开与收回 课程视频:...
