YOLOv8训练自己的数据集,通过LabelImg

记录下labelImg标注数据到YOLOv8训练的过程,其中容易遇到labelImg的坑

数据集处理

首先在mydata下创建4个文件夹

在这里插入图片描述
images文件夹下存放着所有的图片,包括训练集和测试集等。后续会根据代码进行划分。
json文件夹里存放的是labelImg标注的所有数据。需要注意的是,json文件的命名应与images文件夹中的图片一一对应。labels文件夹是空的,后续会根据代码将json转化为YOLOv8支持的训练数据集。接下来需要创建一个 split_train_val.py 文件,放在mydata目录下,用于将images文件夹中的图片划分为训练集和测试集。代码如下:

import os
import json
import random
import argparseclass DatasetSplitter:def __init__(self, json_path, txt_path):self.json_path = json_pathself.txt_path = txt_pathself.trainval_percent = 1.0self.train_percent = 0.9self.total_json = os.listdir(json_path)self.num = len(self.total_json)self.list_index = list(range(self.num))if not os.path.exists(txt_path):os.makedirs(txt_path)def split_dataset(self):tv = int(self.num * self.trainval_percent)tr = int(tv * self.train_percent)trainval = random.sample(self.list_index, tv)train = random.sample(trainval, tr)file_trainval = open(os.path.join(self.txt_path, 'trainval.txt'), 'w')file_test = open(os.path.join(self.txt_path, 'test.txt'), 'w')file_train = open(os.path.join(self.txt_path, 'train.txt'), 'w')file_val = open(os.path.join(self.txt_path, 'val.txt'), 'w')for i in self.list_index:name = self.total_json[i][:-5] + '\n'  # Assuming filenames end with '.json'if i in trainval:file_trainval.write(name)if i in train:file_train.write(name)else:file_val.write(name)else:file_test.write(name)file_trainval.close()file_train.close()file_val.close()file_test.close()if __name__ == "__main__":parser = argparse.ArgumentParser()parser.add_argument('--json_path', default='json', type=str, help='input json label path')parser.add_argument('--txt_path', default='dataSet', type=str, help='output txt label path')opt = parser.parse_args()dataset_splitter = DatasetSplitter(opt.json_path, opt.txt_path)dataset_splitter.split_dataset()

运行后会在dataSet生成四个文件.
如图所示
然后前往mydata目录的上一级目录,例如我这里是test目录下,创建voc_label.py文件.用于将labelImg标注的json数据转化为txt文本数据.

请注意,YULO的标注框中的x和y表示矩形框的左上角,而labelImg中的(x,y,w,h)可能表示矩形框的中心点坐标。在使用时需要确认,以免训练出来的YOLO存在偏差。
可以通过以下代码draw_picture_by_json.py进行绘图测试,以下我是默认labelImg的格式是(x_center,y_center,w,h)的格式进行绘制.

from typing import Dict
from PIL import Image, ImageDraw
import jsondef draw_pic_by_raw_data(image_path:str, output_path:str, json_data: Dict):data = json_dataimg = Image.open(image_path)draw = ImageDraw.Draw(img)# Load JSON file with bounding box information# Iterate through bounding boxes and draw them on the imageannotations = data[0]["annotations"]for bbox in annotations:label = bbox["label"]x_center, y_center, width, height = (bbox["coordinates"]["x"],bbox["coordinates"]["y"],bbox["coordinates"]["width"],bbox["coordinates"]["height"])#FIXME TODO 从中心坐标x,y LabelImg 计算左上角坐标x, y = x_center - width / 2, y_center - height / 2# Draw bounding boxdraw.rectangle([x, y, x+width, y+height], outline="red", width=2)# Draw labeldraw.text((x, y-15), label, fill="red")# Save the resultimg.save(output_path)img.show()if __name__ == "__main__":test_img_path = "3157.jpg"test_json_path = "3157.json"output_path = "out.jpg"with open(test_json_path, 'r') as f:data = json.load(f)draw_pic_by_raw_data(test_img_path, output_path, data)

通过以上代码,如果矩形框正确,则验证了labelImg的x、y、w和h坐标应该是x_center、y_center、w和h的情况。需要在将json转换为txt文本时进行处理。这里给出voc_label.py的代码如下:请注意修改classes中的类别,修改为和mydata.yaml的顺序一致,否则会导致标签错误。

代码运行前请在mydata目录的上一级,也就是我这里的test目录下创建一个paper_data文件夹,用于等会在mydata.yaml中指定路径.

import os
import json
from os import getcwdsets = ['train', 'val', 'test']
classes = ["A", "B", "C", "D", "E"]  # 请根据您的实际类别进行修改 对齐yaml文件中的names
abs_path = os.getcwd()
print(abs_path)def convert(size, box):dw = 1. / size[0]dh = 1. / size[1]x = (box[0] + box[1]) / 2.0 - 1y = (box[2] + box[3]) / 2.0 - 1w = box[1] - box[0]h = box[3] - box[2]x = x * dww = w * dwy = y * dhh = h * dhreturn x, y, w, hdef convert_annotation(image_id):in_file = open('mydata/json/%s.json' % (image_id), 'r', encoding='UTF-8')out_file = open('mydata/labels/%s.txt' % (image_id), 'w')data = json.load(in_file)for obj in data[0]["annotations"]:w = obj["coordinates"]["width"]h = obj["coordinates"]["height"]difficult = 0  # JSON数据中没有difficult字段,设为0cls = obj["label"]if cls not in classes or difficult == 1:continuecls_id = classes.index(cls)##注意:这里的box是左上角和右下角的坐标,而不是中心点坐标x_center = obj["coordinates"]["x"]y_center = obj["coordinates"]["y"]width = obj["coordinates"]["width"]height = obj["coordinates"]["height"]x, y = x_center - width / 2, y_center - height / 2b = x, x + width, y, y + height# b = obj["coordinates"]["x"], obj["coordinates"]["x"] + obj["coordinates"]["width"], \#     obj["coordinates"]["y"], obj["coordinates"]["y"] + obj["coordinates"]["height"]b1, b2, b3, b4 = b# 标注越界修正if b2 > w:b2 = wif b4 > h:b4 = hb = (b1, b2, b3, b4)bb = convert((w, h), b)out_file.write(str(cls_id) + " " + " ".join([str(a) for a in bb]) + '\n')wd = getcwd()
for image_set in sets:if not os.path.exists('mydata/labels/'):os.makedirs('mydata/labels/')image_ids = open('mydata/dataSet/%s.txt' % (image_set)).read().strip().split()list_file = open('paper_data/%s.txt' % (image_set), 'w')for image_id in image_ids:list_file.write(abs_path + '/mydata/images/%s.jpg\n' % (image_id))convert_annotation(image_id)list_file.close()

yaml文件配置

截止到这里数据preprocess处理完毕.接下来进行训练前的yaml文件配置.
修改为刚才创建的paper_data的绝对路径
如上配置

并进行names的配置,注意顺序和数量需要与voc_label.py里面的列表顺序一致.

最后修改yolov8.yaml文件配置

yolov8.yaml的路径一般在ultralytics/ultralytics/cfg/models/v8目录下
修改nc为names中的类别数量
在这里插入图片描述

训练模型

yolo task=detect mode=train model=yolov8s.yaml data=mydata.yaml epochs=25 batch=16

这些模型可以支持多种尺寸,包括小(n)、中(s)、中大(m)、大(l)和超大(x)。模型的尺寸参数越大,所需的显存和训练时间也越多。要切换模型尺寸,只需在"model=yolov8"后面加上相应的尺寸参数(n、s、m、l、x),然后再加上.yaml即可。另外,epochs设置为25,batch大小为16。epochs表示训练的轮数, batch为每个批次的样本数量为16.

推理

训练结束后可以通过以下代码进行测试.

yolo predict model=xxxx/weights/best.pt source=xxxx/mydata/testvedio.mp4 imgsz=1280

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

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

相关文章

【代码随想录-数组】长度最小的子数组

💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学习,不断总结,共同进步,活到老学到老导航 檀越剑指大厂系列:全面总结 jav…

Redis-持久机制

文章目录 为什么有持久化什么是持久化RDB文件创建SAVEBGSAVE 文件载入 优缺点 AOF日志步骤 对比数据恢复 总结 Redis是一个开源的内存数据结构存储系统,被广泛应用于Web应用中,可以用作数据库和缓存服务器。它具有高性能、高并发、高可用性等特点&#x…

ORB-SLAM中的RANSAC算法解析

RANSAC算法解析 RANSAC是一种在具有噪声的模型中去估计最优的一个算法,其核心思想是采用不断迭代的方法去选择一组全是内点的集合,并采用该集合进行模型估计的一种方法,可以提高模型估计的鲁棒性。 假设目前有 K K K组采集到的数据&#xff…

2024年人工智能产业十大发展趋势

2024年人工智能产业十大发展趋势 技术变革1. 多模态预训练大模型将是人工智能产业的标配2. 高质量数据愈发稀缺将倒逼数据智能飞跃3. 智能算力无处不在的计算新范式加速实现 应用创新4. 人工智能生成内容(AIGC)应用向全场景渗透5. 人工智能驱动科学研究&…

仅使用 Python 创建的 Web 应用程序(前端版本)第07章_商品列表

在本章中,我们将实现一个产品列表页面。 完成后的图像如下 创建过程与User相同,流程如下。 No分类内容1Model创建继承BaseDataModel的数据类Item2MockDB创建产品表并生成/添加虚拟数据3Service创建一个 ItemAPIClient4Page定义PageId并创建继承自BasePage的页面类5Applicati…

ElasticSearch7.7.1集群搭建

前言 Elasticsearch(ES)是一个基于Apache Lucene的分布式、高扩展、近实时的搜索引擎,主要用于海量数据快速存储、实时检索、高效分析的场景。通过简单易用的RESTful API,Elasticsearch隐藏了Lucene的复杂性,使得全文搜…

DDT数据驱动测试

简单介绍 ​ DDT(Date Driver Test),所谓数据驱动测试, 简单来说就是由数据的改变从而驱动自动化测试的执行,最终引起测试结果的改变。通过使用数据驱动测试的方法,可以在需要验证多组数据测试场景中&…

齐俊元或转岗至Flow,童遥升任飞书产品负责人;霍启刚赴天津履职 ;广州放开120平方米以上住房限购

今日精选 • 齐俊元或转岗至Flow,童遥升任飞书产品负责人• 霍启刚赴天津履职• 广州放开120平方米以上住房限购 科技动态 • 年轻人的第一个多模态大模型: Vary-toy ,模型大小不到2B,代码和模型均已开源,并有在线demo可试玩。 地址: htt…

Topaz Video AI:无损放大,让你的视频更清晰!

在当今的数字时代,视频内容的重要性越来越受到人们的关注。无论是在社交媒体上分享生活片段,还是在商业领域中制作宣传视频,人们都希望能够展现出更高质量的视频内容。 然而,由于各种原因,我们经常会面临一个问题&…

网络基础---初识网络

前言 作者:小蜗牛向前冲 名言:我可以接受失败,但我不能接受放弃 如果觉的博主的文章还不错的话,还请点赞,收藏,关注👀支持博主。如果发现有问题的地方欢迎❀大家在评论区指正 目录 一、局域网…

springboot 整合 Activiti6

1.添加maven依赖 <dependency><groupId>org.activiti</groupId><artifactId>activiti-spring-boot-starter-basic</artifactId><version>6.0.0</version> </dependency>2.添加配置 spring:activiti:check-process-definitio…

Linux:命名管道及其实现原理

文章目录 命名管道指令级命名管道代码级命名管道 本篇要引入的内容是命名管道 命名管道 前面的总结中已经搞定了匿名管道&#xff0c;但是匿名管道有一个很严重的问题&#xff0c;它只允许具有血缘关系的进程进行通信&#xff0c;那如果是两个不相关的进程进行通信&#xff0…