0


使用yolov5训练自己的数据集(苹果成熟度检测)

先从Github上下载YOLOv5,下载好解压配置好就可以使用,地址:

https://github.com/ultralytics/yolov5

1.训练数据集的准备工作

在yolov5 目录的data文件夹下新建四个文件夹,先说明这四个文件夹分别是用来干什么的,后面会往里面一一加入需要添加的内容。

Annotations文件夹:用来存放使用labelimg给每张图片标注后的xml文件,后面会讲解如何使用labelimg进行标注。

Images文件夹:用来存放原始的需要训练的数据集图片,图片格式为jpg格式。

ImageSets文件夹:用来存放将数据集划分后的用于训练、验证、测试的文件。

Labels文件夹:用来存放将xml格式的标注文件转换后的txt格式的标注文件。

2.准备数据集

我做的是关于苹果成熟度的检测,将苹果根据成熟度划分为3类:高成熟度 High_Ripeness,中成熟度 Medium_Ripeness,低成熟度 Low_Ripeness。下图为数据集的一部分,共准备了60张原始图片,高中低成熟度的图片各有20张,图片都是从百度上一一下载的。此处会用到一个非常高效的重命名方式,就不用一张一张图片的进行重命名。批量重命名的代码如下。60张图片准备好后就放在images文件夹中即可。

  1. import os
  2. class BatchRename():
  3. '''
  4. 批量重命名文件夹中的图片文件
  5. '''
  6. def __init__(self):
  7. self.path = 'E:\GitHub\yolov5-master\yolov5-master\data\images\新建文件夹' #表示需要命名处理的文件夹
  8. self.new_path='E:\GitHub\yolov5-master\yolov5-master\data\images\新建文件夹'
  9. def rename(self):
  10. filelist = os.listdir(self.path) #获取文件夹中文件的所有的文件
  11. total_num = len(filelist) #获取文件长度(个数)
  12. i = 1 #表示文件的命名是从1开始的
  13. for item in filelist:
  14. if 1: #初始的图片的格式为jpg格式的(或者源文件是png格式及其他格式,后面的转换格式就可以调整为自己需要的格式即可)
  15. src = os.path.join(os.path.abspath(self.path), item) #连接两个或更多的路径名组件
  16. # dst = os.path.join(os.path.abspath(self.new_path), ''+str(i) + '.jpg')#处理后的格式也为jpg格式的,当然这里可以改成png格式
  17. dst = os.path.join(os.path.abspath(self.path), 'Low Ripeness0000' + format(str(i), '0>3s') + '.jpg') #这种情况下的命名格式为0000000.jpg形式,可以自主定义想要的格式
  18. try:
  19. os.rename(src, dst) #src – 要修改的目录名 dst – 修改后的目录名
  20. print('converting %s to %s ...' % (src, dst))
  21. i = i + 1
  22. except:
  23. continue
  24. print ('total %d to rename & converted %d jpgs' % (total_num, i))
  25. if __name__ == '__main__':
  26. demo = BatchRename()
  27. demo.rename()

3.使用labelimg进行标注

Labelimg是一个图像标注工具,软件使用非常简单,下载解压后在data文件夹下有一个predefined_classes文件,在里面提前写好要训练的类型,后面标注的效率会快很多。

(1)Open就是打开图片,我们不需要一张一张的打开,太麻烦了,使用下面的Open Dir

(2)Open Dir就是打开需要标注的图片的文件夹,这里就选择images文件夹

(3)change save dir就是标注后保存标记文件的位置,选择需要保存标注信息的文件夹,这里就选择Annotations文件夹

(4)特别注意需要选择好所需要的标注文件的类型。有yolo(txt), pascalVOC (xml)两种类型。yolov5需要txt文件格式的标注文件,但是这里我们选择pascalVOC,后面再将xml格式的标注文件转化为所需的txt格式(黑人问号脸)。

(5)按W键或点击Create\nRectBox开始创建矩形框,把要进行识别训练的区域标记出来就行,选好框后我们选是什么类别(predefined_classes文件,在里面提前写好要训练的类型的原因),整张图片的所有目标都标记好了之后按Ctrl+S或点击Save保存 ,然后切换下一张继续,快捷键为按D键,每一张图片标记后都要保存,这个过程是一个比较繁琐的过程

4.数据集的划分

在yolov5的根目录下创建一个脚本,创建一个split_train_val.py文件,运行文件之后会在imageSets文件夹下将数据集划分为训练集、验证集、测试集,里面存放的就是用于训练、验证、测试的图片名称。代码内容如下:

  1. import os
  2. import random
  3. trainval_percent = 0.9
  4. train_percent = 0.9
  5. xmlfilepath = 'data/Annotations'
  6. txtsavepath = 'data/ImageSets'
  7. total_xml = os.listdir(xmlfilepath)
  8. num = len(total_xml)
  9. list = range(num)
  10. tv = int(num * trainval_percent)
  11. tr = int(tv * train_percent)
  12. trainval = random.sample(list, tv)
  13. train = random.sample(trainval, tr)
  14. ftrainval = open('data/ImageSets/trainval.txt', 'w')
  15. ftest = open('data/ImageSets/test.txt', 'w')
  16. ftrain = open('data/ImageSets/train.txt', 'w')
  17. fval = open('data/ImageSets/val.txt', 'w')
  18. for i in list:
  19. name = total_xml[i][:-4] + '\n'
  20. if i in trainval:
  21. ftrainval.write(name)
  22. if i in train:
  23. ftrain.write(name)
  24. else:
  25. fval.write(name)
  26. else:
  27. ftest.write(name)
  28. ftrainval.close()
  29. ftrain.close()
  30. fval.close()
  31. ftest.close()

5.转换数据集格式

创建voc_label.py文件,他的作用:(1)就是把Annoctions里面的xml格式的标注文件转换为txt格式的标注文件,每个图像对应一个txt文件,文件每一行为一个目标的信息,包括class, x_center, y_center, width, height。格式如下:

(2)就是运行后除了会生成转换后labels文件夹下的60张图片的txt文件,还会在data文件夹下得到三个包含数据集路径的txt文件,train.tx,tes.txt,val.txt这3个txt文件为划分后图像所在位置的绝对路径,如train.txt就含有所有训练集图像的绝对路径。

  1. import xml.etree.ElementTree as ET
  2. import os
  3. from os import getcwd
  4. sets = ['train', 'val', 'test']
  5. classes = ['High Ripeness','Low Ripeness','Medium Ripeness']
  6. abs_path = os.getcwd()
  7. print(abs_path)
  8. def convert(size, box):
  9. dw = 1. / (size[0])
  10. dh = 1. / (size[1])
  11. x = (box[0] + box[1]) / 2.0 - 1
  12. y = (box[2] + box[3]) / 2.0 - 1
  13. w = box[1] - box[0]
  14. h = box[3] - box[2]
  15. x = x * dw
  16. w = w * dw
  17. y = y * dh
  18. h = h * dh
  19. return x, y, w, h
  20. def convert_annotation(image_id):
  21. in_file = open('data/Annotations/%s.xml' % (image_id), encoding='UTF-8')
  22. out_file = open('data/labels/%s.txt' % (image_id), 'w')
  23. tree = ET.parse(in_file)
  24. root = tree.getroot()
  25. size = root.find('size')
  26. w = int(size.find('width').text)
  27. h = int(size.find('height').text)
  28. for obj in root.iter('object'):
  29. # difficult = obj.find('difficult').text
  30. difficult = obj.find('difficult').text
  31. cls = obj.find('name').text
  32. if cls not in classes or int(difficult) == 1:
  33. continue
  34. cls_id = classes.index(cls)
  35. xmlbox = obj.find('bndbox')
  36. b = (float(xmlbox.find('xmin').text), float(xmlbox.find('xmax').text), float(xmlbox.find('ymin').text),
  37. float(xmlbox.find('ymax').text))
  38. b1, b2, b3, b4 = b
  39. # 标注越界修正
  40. if b2 > w:
  41. b2 = w
  42. if b4 > h:
  43. b4 = h
  44. b = (b1, b2, b3, b4)
  45. bb = convert((w, h), b)
  46. out_file.write(str(cls_id) + " " + " ".join([str(a) for a in bb]) + '\n')
  47. wd = getcwd()
  48. for image_set in sets:
  49. if not os.path.exists('data/labels/'):
  50. os.makedirs('data/labels/')
  51. image_ids = open('data/ImageSets/%s.txt' % (image_set)).read().strip().split()
  52. list_file = open('data/%s.txt' % (image_set), 'w')
  53. for image_id in image_ids:
  54. list_file.write(abs_path + 'data/images/%s.jpg\n' % (image_id))
  55. convert_annotation(image_id)
  56. list_file.close()

6.配置文件(恭喜来到最后一步啦,马上就要成功啦)

(1)数据集方面的yaml文件修改。

在yolov5目录下的data文件夹下新建一个apple.yaml文件,用来存放训练集、验证集、测试集的划分文件,目标的类别数目和具体类别列表。

(2)网络参数方面的yaml文件修改

接着在models目录下的yolov5s.yaml文件进行修改,这里取决于你使用了哪个模型就去修改对于的文件,该项目中使用的是yolov5s模型。需要修改的参数仅有一个,就是具体类别的数目:

(3)train.py****中的参数修改

最后,在根目录中对train.py中的一些参数进行修改,加载的权重文件即yolov5s.pt文件,模型配置文件即修改好的yolov5s.yaml文件,数据集配置文件即第一个apple.yaml文件

7.准备工作全部完成,开始训练

全部配置好后,直接执行train.py文件开始训练

8.训练完成后,实现检测

训练结束,用训练好的权重文件之后,就可以就行目标检测试了。在根目录的detect.py中进行修改

参数,主要用到的只有这几个参数而已:–weights,–source。

选用训练的权重,用runs/train/exp/weights/best.pt,达到了预期的检测效果。

  1. parser.add_argument('--weights', nargs='+', type=str, default=ROOT / r'runs\train\exp14\weights\best.pt', help='model path(s)')
  2. parser.add_argument('--source', type=str, default=ROOT /'data/video/detection_video_Trim_1.mp4', help='file/dir/URL/glob, 0 for webcam')

本文转载自: https://blog.csdn.net/m0_57525262/article/details/122134557
版权归原作者 123xiaohu 所有, 如有侵权,请联系我们删除。

“使用yolov5训练自己的数据集(苹果成熟度检测)”的评论:

还没有评论