YoloV9实战:从Labelme到训练、验证、测试、模块解析

模型实战

训练COCO数据集

本次使用2017版本的COCO数据集作为例子,演示如何使用YoloV8训练和预测。

下载数据集

Images:

  • 2017 Train images [118K/18GB] :http://images.cocodataset.org/zips/train2017.zip
  • 2017 Val images [5K/1GB]:http://images.cocodataset.org/zips/val2017.zip
  • 2017 Test images [41K/6GB]:http://images.cocodataset.org/zips/unlabeled2017.zip

Annotations:

  • 2017 annotations_trainval2017 [241MB]:http://images.cocodataset.org/annotations/annotations_trainval2017.zip

COCO转yolo格式数据集(适用V4,V5,V6,V7,V8)

最初的研究论文中,COCO中有91个对象类别。然而,在2014年的第一次发布中,仅发布了80个标记和分割图像的对象类别。2014年发布之后,2017年发布了后续版本。详细的类别如下:

IDOBJECT (PAPER)OBJECT (2014 REL.)OBJECT (2017 REL.)SUPER CATEGORY
1personpersonpersonperson
2bicyclebicyclebicyclevehicle
3carcarcarvehicle
4motorcyclemotorcyclemotorcyclevehicle
5airplaneairplaneairplanevehicle
6busbusbusvehicle
7traintraintrainvehicle
8trucktrucktruckvehicle
9boatboatboatvehicle
10trafficlighttraffic lighttraffic lightoutdoor
11fire hydrantfire hydrantfire hydrantoutdoor
12streetsign--
13stop signstop signstop signoutdoor
14parking meterparking meterparking meteroutdoor
15benchbenchbenchoutdoor
16birdbirdbirdanimal
17catcatcatanimal
18dogdogdoganimal
19horsehorsehorseanimal
20sheepsheepsheepanimal
21cowcowcowanimal
22elephantelephantelephantanimal
23bearbearbearanimal
24zebrazebrazebraanimal
25giraffegiraffegiraffeanimal
26hat--accessory
27backpackbackpackbackpackaccessory
28umbrellaumbrellaumbrellaaccessory
29shoe--accessory
30eye glasses--accessory
31handbaghandbaghandbagaccessory
32tietietieaccessory
33suitcasesuitcasesuitcaseaccessory
34frisbeefrisbeefrisbeesports
35skisskisskissports
36snowboardsnowboardsnowboardsports
37sports ballsports ballsports ballsports
38kitekitekitesports
39baseball batbaseball batbaseball batsports
40baseball glovebaseball glovebaseball glovesports
41skateboardskateboardskateboardsports
42surfboardsurfboardsurfboardsports
43tennis rackettennis rackettennis racketsports
44bottlebottlebottlekitchen
45plate--kitchen
46wine glasswine glasswine glasskitchen
47cupcupcupkitchen
48forkforkforkkitchen
49knifeknifeknifekitchen
50spoonspoonspoonkitchen
51bowlbowlbowlkitchen
52bananabananabananafood
53appleappleapplefood
54sandwichsandwichsandwichfood
55orangeorangeorangefood
56broccolibroccolibroccolifood
57carrotcarrotcarrotfood
58hot doghot doghot dogfood
59pizzapizzapizzafood
60donutdonutdonutfood
61cakecakecakefood
62chairchairchairfurniture
63couchcouchcouchfurniture
64potted plantpotted plantpotted plantfurniture
65bedbedbedfurniture
66mirror--furniture
67dining tabledining tabledining tablefurniture
68window--furniture
69desk--furniture
70toilettoilettoiletfurniture
71door--furniture
72tvtvtvelectronic
73laptoplaptoplaptopelectronic
74mousemousemouseelectronic
75remoteremoteremoteelectronic
76keyboardkeyboardkeyboardelectronic
77cell phonecell phonecell phoneelectronic
78microwavemicrowavemicrowaveappliance
79ovenovenovenappliance
80toastertoastertoasterappliance
81sinksinksinkappliance
82refrigeratorrefrigeratorrefrigeratorappliance
83blender--appliance
84bookbookbookindoor
85clockclockclockindoor
86vasevasevaseindoor
87scissorsscissorsscissorsindoor
88teddy bearteddy bearteddy bearindoor
89hair drierhair drierhair drierindoor
90toothbrushtoothbrushtoothbrushindoor
91hair brush--indoor

可以看到,2014年和2017年发布的对象列表是相同的,它们是论文中最初91个对象类别中的80个对象。所以在转换的时候,要重新对类别做映射,映射函数如下:

def coco91_to_coco80_class():  # converts 80-index (val2014) to 91-index (paper)# https://tech.amikelive.com/node-718/what-object-categories-labels-are-in-coco-dataset/# a = np.loadtxt('data/coco.names', dtype='str', delimiter='\n')# b = np.loadtxt('data/coco_paper.names', dtype='str', delimiter='\n')# x1 = [list(a[i] == b).index(True) + 1 for i in range(80)]  # darknet to coco# x2 = [list(b[i] == a).index(True) if any(b[i] == a) else None for i in range(91)]  # coco to darknetx = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, None, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, None, 24, 25, None,None, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, None, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50,51, 52, 53, 54, 55, 56, 57, 58, 59, None, 60, None, None, 61, None, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72,None, 73, 74, 75, 76, 77, 78, 79, None]return x

接下来,开始格式转换,工程的目录如下:
在这里插入图片描述

  • coco:存放解压后的数据集。
    -out:保存输出结果。
    -coco2yolo.py:转换脚本。

转换代码如下:

import json
import glob
import os
import shutil
from pathlib import Path
import numpy as np
from tqdm import tqdmdef make_folders(path='../out/'):# Create foldersif os.path.exists(path):shutil.rmtree(path)  # delete output folderos.makedirs(path)  # make new output folderos.makedirs(path + os.sep + 'labels')  # make new labels folderos.makedirs(path + os.sep + 'images')  # make new labels folderreturn pathdef convert_coco_json(json_dir='./coco/annotations_trainval2017/annotations/'):jsons = glob.glob(json_dir + '*.json')coco80 = coco91_to_coco80_class()# Import jsonfor json_file in sorted(jsons):fn = 'out/labels/%s/' % Path(json_file).stem.replace('instances_', '')  # folder namefn_images = 'out/images/%s/' % Path(json_file).stem.replace('instances_', '')  # folder nameos.makedirs(fn,exist_ok=True)os.makedirs(fn_images,exist_ok=True)with open(json_file) as f:data = json.load(f)print(fn)# Create image dictimages = {'%g' % x['id']: x for x in data['images']}# Write labels filefor x in tqdm(data['annotations'], desc='Annotations %s' % json_file):if x['iscrowd']:continueimg = images['%g' % x['image_id']]h, w, f = img['height'], img['width'], img['file_name']file_path='coco/'+fn.split('/')[-2]+"/"+f# The Labelbox bounding box format is [top left x, top left y, width, height]box = np.array(x['bbox'], dtype=np.float64)box[:2] += box[2:] / 2  # xy top-left corner to centerbox[[0, 2]] /= w  # normalize xbox[[1, 3]] /= h  # normalize yif (box[2] > 0.) and (box[3] > 0.):  # if w > 0 and h > 0with open(fn + Path(f).stem + '.txt', 'a') as file:file.write('%g %.6f %.6f %.6f %.6f\n' % (coco80[x['category_id'] - 1], *box))file_path_t=fn_images+fprint(file_path,file_path_t)shutil.copy(file_path,file_path_t)def coco91_to_coco80_class():  # converts 80-index (val2014) to 91-index (paper)# https://tech.amikelive.com/node-718/what-object-categories-labels-are-in-coco-dataset/# a = np.loadtxt('data/coco.names', dtype='str', delimiter='\n')# b = np.loadtxt('data/coco_paper.names', dtype='str', delimiter='\n')# x1 = [list(a[i] == b).index(True) + 1 for i in range(80)]  # darknet to coco# x2 = [list(b[i] == a).index(True) if any(b[i] == a) else None for i in range(91)]  # coco to darknetx = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, None, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, None, 24, 25, None,None, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, None, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50,51, 52, 53, 54, 55, 56, 57, 58, 59, None, 60, None, None, 61, None, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72,None, 73, 74, 75, 76, 77, 78, 79, None]return xconvert_coco_json()

开始运行:
在这里插入图片描述

转换完成后,验证转换的结果:

import cv2
import osdef draw_box_in_single_image(image_path, txt_path):# 读取图像image = cv2.imread(image_path)# 读取txt文件信息def read_list(txt_path):pos = []with open(txt_path, 'r') as file_to_read:while True:lines = file_to_read.readline()  # 整行读取数据if not lines:break# 将整行数据分割处理,如果分割符是空格,括号里就不用传入参数,如果是逗号, 则传入‘,'字符。p_tmp = [float(i) for i in lines.split(' ')]pos.append(p_tmp)  # 添加新读取的数据# Efield.append(E_tmp)passreturn pos# txt转换为boxdef convert(size, box):xmin = (box[1]-box[3]/2.)*size[1]xmax = (box[1]+box[3]/2.)*size[1]ymin = (box[2]-box[4]/2.)*size[0]ymax = (box[2]+box[4]/2.)*size[0]box = (int(xmin), int(ymin), int(xmax), int(ymax))return boxpos = read_list(txt_path)print(pos)tl = int((image.shape[0]+image.shape[1])/2)lf = max(tl-1,1)for i in range(len(pos)):label = str(int(pos[i][0]))print('label is '+label)box = convert(image.shape, pos[i])image = cv2.rectangle(image,(box[0], box[1]),(box[2],box[3]),(0,0,255),2)cv2.putText(image,label,(box[0],box[1]-2), 0, 1, [0,0,255], thickness=2, lineType=cv2.LINE_AA)passif pos:cv2.imwrite('./Data/see_images/{}.png'.format(image_path.split('\\')[-1][:-4]), image)else:print('None')img_folder = "./out/images/val2017"
img_list = os.listdir(img_folder)
img_list.sort()label_folder = "./out/labels/val2017"
label_list = os.listdir(label_folder)
label_list.sort()
if not os.path.exists('./Data/see_images'):os.makedirs('./Data/see_images')
for i in range(len(img_list)):image_path = img_folder + "\\" + img_list[i]txt_path = label_folder + "\\" + label_list[i]draw_box_in_single_image(image_path, txt_path)

结果展示:
在这里插入图片描述

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

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

相关文章

【电控笔记2.2】电流回路+延迟效应

延迟效应的来源以及影响 数字控制系统的delay: 5.4节有介绍T0=0.5TS 低通滤波器的时间常数? 滤波器的传递函数与性能参数

【多线程】阻塞队列 | put()方法 | take()方法 | 生产者-消费者模式 |实现阻塞队列

文章目录 阻塞队列1.生产者-消费者模式生产者消费者模型的意义:1.解耦合2.削峰填谷: 2.阻塞队列的使用BlockingQueue 3.实现阻塞队列唤醒:使用阻塞队列实现生产者消费者模型 阻塞队列 阻塞队列是一种特殊的队列: 1.是线程安全的。…

Vue 阶段练习:记事本

将 Vue快速入门 和 Vue 指令的学习成果应用到实际场景中(如该练习 记事本),我们能够解决实际问题并提升对 Vue 的技能掌握。 目录 功能展示 需求分析 我的代码 案例代码 知识点总结 功能展示 需求分析 列表渲染删除功能添加功能底部统计…

网络—DAY4

思维导图 多进程并发服务器 #include<myhead.h> #define SER_IP "192.168.122.56" #define SER_PORT 8888 void handler(int signo) {if(signoSIGCHLD){while(waitpid(-1,NULL,WNOHANG)>0);} } int main(int argc, char *argv[]) {//将SIGCHLD信号与处理…

项目中,如何写 readme.md 文件 | 写项目总结

tips&#xff1a;注意写 1. readme文件&#xff1a;①项目文档&#xff08;项目需求和设计文档、项目系统架构和技术文档、接口文档&#xff09;、②项目结构、③启动项目。具体结构见下文。 2. 项目总结&#xff1a;技术栈、描述、主要工作&#xff01;&#xff01;需求及功…

MySQL常见故障现象分析及解决办法

一、背景 MySQL作为广泛使用的关系型数据库管理系统&#xff0c;在日常使用中难免会遇到各种故障。本文将通过一个具体的案例&#xff0c;分析MySQL常见的故障现象&#xff0c;并提供相应的解决办法和代码示例。 二、故障现象 某企业使用的MySQL数据库服务器近期出现以下问题…

FastAPI 是干啥的

FastAPI 是一个现代、快速&#xff08;高性能&#xff09;的 Web 框架&#xff0c;用于构建 API&#xff0c;与 Python 3.6 类型提示一起使用。它基于标准 Python 类型提示&#xff0c;使用 Python 3.6 的类型注解来声明请求参数和返回值的类型&#xff0c;这使得代码既简洁又易…

递归、搜索与回溯算法——递归

T04BF &#x1f44b;专栏: 算法|JAVA|MySQL|C语言 &#x1faf5; 小比特 大梦想 此篇文章与大家分享递归,搜索与回溯算法关于递归的专题 如果有不足的或者错误的请您指出! 目录 1.什么时候使用递归2.汉诺塔2.1解析2.2题解 3.合并两个有序链表3.1解析3.2题解 4.翻转链表4.1解析4…

mysql SQL必知语法

文章目录 概要技术细节小结 概要 mysql SQL必知语法 SQL必知语法包括SELECT、FROM、WHERE、GROUP BY、HAVING、ORDER BY等关键字&#xff0c;用于查询和操作数据库中的数据。SELECT用于选择需要查询的列&#xff0c;FROM用于指定数据表&#xff0c;WHERE用于设置查询条件&…

下载软件时的Ubuntu x86_64-v2、skylake、aarch64版本分别代表什么?

Ubuntu-x86_64-v2、Ubuntu-x86_64-skylake和Ubuntu-aarch64都是Ubuntu的不同版本或变种&#xff0c;它们之间的主要区别在于所支持的硬件架构和针对特定硬件的优化。 Ubuntu-x86_64-v2&#xff1a; 这是基于x86_64&#xff08;也称为AMD64或Intel 64&#xff09;架构的Ubuntu版…

Ubuntu上根据关键字模糊查找指定文件夹或文件

在Ubuntu上根据关键字模糊查找指定文件夹或文件&#xff0c;可以使用以下方法&#xff1a; GNOME 桌面搜索&#xff1a; 使用GNOME桌面的Spotlight式搜索功能&#xff0c;通过按下Super键&#xff08;通常是Windows键&#xff09;并输入关键字&#xff0c;可以搜索文件和文件夹…

人类连接的桥梁:探索Facebook如何连接世界

随着技术的发展和全球化的进程&#xff0c;我们的世界正在变得越来越紧密相连。在这个过程中&#xff0c;社交媒体平台扮演了一个至关重要的角色&#xff0c;为人们提供了一个跨越国界、文化和语言的交流平台。其中&#xff0c;Facebook作为全球最大的社交媒体平台&#xff0c;…

rancher踩坑日志:prometheus访问kubelet 10250端口提示鉴权失败

该原因是因为kubectl禁止了非授权用户访问10250端口来获取node的数据。 解决思路&#xff1a; 添加prometheus访问kubelet时带上证书进行验证匹配 --> 由于我的prometheus是rancher安装的&#xff0c;不知道要怎么修改所以研究了一会没研究明白就放弃了。设置prometheus访问…

Rockchip Android13 Vold(二):Framework层

目录 前言 1、接收VolumeInfo状态 2、通知VolumeInfo状态变化 3、创建StorageVolume

Create2024百度AI开发者大会记录

去年2023.3.16日百度文心大模型发布&#xff0c;今天2024.4.16日 代码智能体&#xff1a;思考模型代码解释器 思考模型整合提示&#xff0c;输入给代码解释器 代码解释器出结果&#xff0c;返回给思考模型&#xff0c;然后迭代 智能代码助手 baidu Comate 多模型推理 种子模型…

JavaScript入门--循环

JavaScript入门--循环 一、for循环二、for in语句三、break语句四、continue语句五、while循环六、do-while语句一、for循环 先来看一个循环案例: for (i = 0; i < 5; i++) {

如何批量删除不包含指定关键字的数据行?

一、需求 有一个报名表&#xff0c;包括年龄&#xff0c;地址&#xff0c;特长等数据&#xff0c;现在想删除特长一列中不含“篮球”这个关键字行&#xff0c;可以使用这些办法。 二、删除数据 方法1.自动筛选&#xff0c; 1.1 选中数据后&#xff0c;点击数据选项卡&#…

java 中公有类的产量如何定义

在Java编程语言中,“公有类”和“产量”的概念并不直接相关联。 “公有类”(public class)是指在Java中,可以被任何其他类访问的类。如果你想要定义一个公有类,你将在类声明处使用 public 关键字: // 这是一个公有类的例子 public class MyClass {// 类体部分,包含字段…

微信人脉扩张!多号批量自动加好友,你get到了吗?

微信是我们在拓展社交圈和寻找商业机会时&#xff0c;与更多的人建立联系的重要渠道。但是&#xff0c;手动一个个添加好友显然费时费力&#xff0c;这时候&#xff0c;微信管理系统的批量自动加好友功能就成为了微信人脉扩张的神器。 通过微信管理系统&#xff0c;我们可以轻…

Java中如何提取视频文件的缩略图

在Java中&#xff0c;可以使用FFmpeg库来提取视频文件的缩略图。以下是一种使用FFmpeg的方法来提取视频缩略图的示例代码&#xff1a; import java.io.File; import java.io.IOException;public class VideoThumbnailExtractor {public static void main(String[] args) {Stri…