赞
踩
目录
去github上打包下载,下载地址:
bubbliiiing/yolov7-pytorch: 这是一个yolov7的库,可以用于训练自己的数据集。 (github.com)
如果github打不开可以去这里下载:项目目录预览 - yolov7-pytorch - GitCode
也可以使用git clone命令克隆项目。
git clone https://github.com/bubbliiiing/yolov7-pytorch
在readme文件里找到百度网盘下载地址下载:
下载好之后直接放在yolov7源码的model_data文件夹里就行了:
项目根目录已有如下所示的文件目录:
首先将自己的图片文件放到JPEGImages文件夹中,将xml文件放到Annotations文件夹中,
然后在model_data目录下创建一个txt文件(我把它命名为cla_classes.txt)以存放类别标签名
接着使用脚本voc_annotation.py(在根目录)进行数据集的划分以及格式的转换,
我们需要修改classes_path来找到我们上一把制作的txt文件:
然后运行脚本,会生成如下几个文件:
VOCdevkit/VOC2007/ImageSets里面的4个txt文件存放的是图片的文件名:
2007_train.txt、2007_val.txt存放的是图片路径以及对应的标注信息:
脚本voc_annotation.py代码如下:
- import os
- import random
- import xml.etree.ElementTree as ET
-
- import numpy as np
-
- from utils.utils import get_classes
-
- #--------------------------------------------------------------------------------------------------------------------------------#
- # annotation_mode用于指定该文件运行时计算的内容
- # annotation_mode为0代表整个标签处理过程,包括获得VOCdevkit/VOC2007/ImageSets里面的txt以及训练用的2007_train.txt、2007_val.txt
- # annotation_mode为1代表获得VOCdevkit/VOC2007/ImageSets里面的txt
- # annotation_mode为2代表获得训练用的2007_train.txt、2007_val.txt
- #--------------------------------------------------------------------------------------------------------------------------------#
- annotation_mode = 0
- #-------------------------------------------------------------------#
- # 必须要修改,用于生成2007_train.txt、2007_val.txt的目标信息
- # 与训练和预测所用的classes_path一致即可
- # 如果生成的2007_train.txt里面没有目标信息
- # 那么就是因为classes没有设定正确
- # 仅在annotation_mode为0和2的时候有效
- #-------------------------------------------------------------------#
- classes_path = 'model_data/cls_classes.txt'
- #--------------------------------------------------------------------------------------------------------------------------------#
- # trainval_percent用于指定(训练集+验证集)与测试集的比例,默认情况下 (训练集+验证集):测试集 = 9:1
- # train_percent用于指定(训练集+验证集)中训练集与验证集的比例,默认情况下 训练集:验证集 = 9:1
- # 仅在annotation_mode为0和1的时候有效
- #--------------------------------------------------------------------------------------------------------------------------------#
- trainval_percent = 0.9
- train_percent = 0.9
- #-------------------------------------------------------#
- # 指向VOC数据集所在的文件夹
- # 默认指向根目录下的VOC数据集
- #-------------------------------------------------------#
- VOCdevkit_path = 'VOCdevkit'
-
- VOCdevkit_sets = [('2007', 'train'), ('2007', 'val')]
- classes, _ = get_classes(classes_path)
-
- #-------------------------------------------------------#
- # 统计目标数量
- #-------------------------------------------------------#
- photo_nums = np.zeros(len(VOCdevkit_sets))
- nums = np.zeros(len(classes))
- def convert_annotation(year, image_id, list_file):
- in_file = open(os.path.join(VOCdevkit_path, 'VOC%s/Annotations/%s.xml'%(year, image_id)), encoding='utf-8')
- tree=ET.parse(in_file)
- root = tree.getroot()
-
- for obj in root.iter('object'):
- difficult = 0
- if obj.find('difficult')!=None:
- difficult = obj.find('difficult').text
- cls = obj.find('name').text
- if cls not in classes or int(difficult)==1:
- continue
- cls_id = classes.index(cls)
- xmlbox = obj.find('bndbox')
- b = (int(float(xmlbox.find('xmin').text)), int(float(xmlbox.find('ymin').text)), int(float(xmlbox.find('xmax').text)), int(float(xmlbox.find('ymax').text)))
- list_file.write(" " + ",".join([str(a) for a in b]) + ',' + str(cls_id))
-
- nums[classes.index(cls)] = nums[classes.index(cls)] + 1
-
- if __name__ == "__main__":
- random.seed(0)
- if " " in os.path.abspath(VOCdevkit_path):
- raise ValueError("数据集存放的文件夹路径与图片名称中不可以存在空格,否则会影响正常的模型训练,请注意修改。")
-
- if annotation_mode == 0 or annotation_mode == 1:
- print("Generate txt in ImageSets.")
- xmlfilepath = os.path.join(VOCdevkit_path, 'VOC2007/Annotations')
- saveBasePath = os.path.join(VOCdevkit_path, 'VOC2007/ImageSets/Main')
- temp_xml = os.listdir(xmlfilepath)
- total_xml = []
- for xml in temp_xml:
- if xml.endswith(".xml"):
- total_xml.append(xml)
-
- num = len(total_xml)
- list = range(num)
- tv = int(num*trainval_percent)
- tr = int(tv*train_percent)
- trainval= random.sample(list,tv)
- train = random.sample(trainval,tr)
-
- print("train and val size",tv)
- print("train size",tr)
- ftrainval = open(os.path.join(saveBasePath,'trainval.txt'), 'w')
- ftest = open(os.path.join(saveBasePath,'test.txt'), 'w')
- ftrain = open(os.path.join(saveBasePath,'train.txt'), 'w')
- fval = open(os.path.join(saveBasePath,'val.txt'), 'w')
-
- for i in list:
- name=total_xml[i][:-4]+'\n'
- if i in trainval:
- ftrainval.write(name)
- if i in train:
- ftrain.write(name)
- else:
- fval.write(name)
- else:
- ftest.write(name)
-
- ftrainval.close()
- ftrain.close()
- fval.close()
- ftest.close()
- print("Generate txt in ImageSets done.")
-
- if annotation_mode == 0 or annotation_mode == 2:
- print("Generate 2007_train.txt and 2007_val.txt for train.")
- type_index = 0
- for year, image_set in VOCdevkit_sets:
- image_ids = open(os.path.join(VOCdevkit_path, 'VOC%s/ImageSets/Main/%s.txt'%(year, image_set)), encoding='utf-8').read().strip().split()
- list_file = open('%s_%s.txt'%(year, image_set), 'w', encoding='utf-8')
- for image_id in image_ids:
- list_file.write('%s/VOC%s/JPEGImages/%s.jpg'%(os.path.abspath(VOCdevkit_path), year, image_id))
-
- convert_annotation(year, image_id, list_file)
- list_file.write('\n')
- photo_nums[type_index] = len(image_ids)
- type_index += 1
- list_file.close()
- print("Generate 2007_train.txt and 2007_val.txt for train done.")
-
- def printTable(List1, List2):
- for i in range(len(List1[0])):
- print("|", end=' ')
- for j in range(len(List1)):
- print(List1[j][i].rjust(int(List2[j])), end=' ')
- print("|", end=' ')
- print()
-
- str_nums = [str(int(x)) for x in nums]
- tableData = [
- classes, str_nums
- ]
- colWidths = [0]*len(tableData)
- len1 = 0
- for i in range(len(tableData)):
- for j in range(len(tableData[i])):
- if len(tableData[i][j]) > colWidths[i]:
- colWidths[i] = len(tableData[i][j])
- printTable(tableData, colWidths)
-
- if photo_nums[0] <= 500:
- print("训练集数量小于500,属于较小的数据量,请注意设置较大的训练世代(Epoch)以满足足够的梯度下降次数(Step)。")
-
- if np.sum(nums) == 0:
- print("在数据集中并未获得任何目标,请注意修改classes_path对应自己的数据集,并且保证标签名字正确,否则训练将会没有任何效果!")
- print("在数据集中并未获得任何目标,请注意修改classes_path对应自己的数据集,并且保证标签名字正确,否则训练将会没有任何效果!")
- print("在数据集中并未获得任何目标,请注意修改classes_path对应自己的数据集,并且保证标签名字正确,否则训练将会没有任何效果!")
- print("(重要的事情说三遍)。")
这里有一点需要说明,就是脚本voc_annotation.py里的annotation_mode参数,如果你没有上图的文件,即VOCdevkit/VOC2007/ImageSets里面的4个txt文件以及2007_train.txt、2007_val.txt,那么就使annotation_mode=0;如果只有2007_train.txt、2007_val.txt,那么就使annotation_mode=1;如果只有VOCdevkit/VOC2007/ImageSets里面的4个txt文件,那么就使annotation_mode=2。
在train.py里有一个需要修改的地方,还是类别文件的路径:
其他的参数可以根据自己的需要修改。然后运行train.py即可。
训练结束后,可以进行。训练结束后会生成最好权重文件命名为best_epoch_weights.pth:
我们使用best_epoch_weights.pth进行测试,
首先需要修改yolo.py:
接着在运行predict.py,输入待检测的图片路径即可检测:
如果出现报错:
AttributeError: 'ImageDraw' object has no attribute 'textsize'
主要原因就是最新的Pillow 10.0.0 版本已经删除了这个属性
解决方法是降低Pillow版本:
先卸载 Pillow:
pip uninstall Pillow
再安装旧版本:
pip install Pillow==9.5.0
测试结果如下:
Pytorch 搭建自己的YoloV7目标检测平台(Bubbliiiing 源码详解 训练 预测)_哔哩哔哩_bilibili
赞
踩
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。