赞
踩
使用Yolov7做目标检测是常见的选择,目前YOLO系列已有yolov8,是一种即为流行的目标检测算法,相较于传统的目标检测算法,YOLO系列算法具有实时性,同时具有更快的检测速度和较高的精度。YOLOv7的主要创新如下:1. 单阶段检测:YOLOv7采用单个神经网络模型,直接在整个图像上进行目标检测,无需使用候选区域提取或多级分类器。2. 实时性能:YOLOv7能够以非常快的速度进行目标检测,适用于实时应用场景。3. 多尺度特征融合:YOLOv7通过使用不同尺度的特征图进行目标检测,能够更好地捕捉不同尺度的目标。4. Anchor Boxes:YOLOv7使用Anchor Boxes来预测目标的边界框,可以更好地适应不同形状和尺寸的目标。5. 高精度检测:YOLOv7在保持实时性能的同时,也具备较高的目标检测精度。
接下来是使用YOLOv7训练自己的数据集的全流程:1、下载源码 2、数据准备 3、修改配置文件参数 4、模型训练 5、模型预测。我会一步步为大家介绍。
官方源码github地址如下: https://github.com/WongKinYiu/yolov7 下载好压缩包后再用pycharm创建好工程,解压缩,这样就得到我们的源码。接下来,你需要仔细地根据requirements.txt配置好环境。我的做法是:用anaconda先创建一个虚拟环境,例如我想创建一个python3.6的虚拟环境,就可以在工程目录下打开cmd,然后输入conda create -n myenv python=3.6,这样就创建完成一个名为myenv的虚拟环境。我们每次需要激活它才能使用:conda activate myenv。
然后,输入conda install --file requirements.txt,这样就可以安装所有依赖项。当然,你可能会遇到安装超时问题,这时需要你把不能正常安装的依赖项用whl的方法安装,打开download.pytorch.org/whl/torch_stable.html网站,查找需要的依赖项下载到本地,在cmd中输入pip install 文件名.whl可以安装。需要注意的是,有些依赖项的不同版本可能会相互冲突,这样会产生一些常见的问题:
1、cuda,pytorch,torchvision版本之间相互不兼容,怎么办?:第一、你需要在pytorch官方或其他方法确认你的cuda所兼容的pytorch,torchvision版本,手动下载纠正。第二、pytorch,torchvision会存在cpu版本和gpu版本,我们一般需要下载的是前缀有cu+数字的版本。第三、你也可以通过换源的方法加速你的下载速度。
2、cuda需要提前安装,查看适合的cuda版本:cmd,然后nvidia-smi,这样可以查看兼容的CUDA版本,访问以下链接:https://developer.nvidia.com/cuda-gpus,在CUDA-GPUs部分的搜索框中,输入您的GPU型号,并从下拉列表中选择相应的型号。在结果页面中,找到与你的GPU型号兼容的CUDA版本,下载。
YOLOv7需要的数据集结构:
- --Annotations
- --00001.xml
- --00002.xml
- .....
- --JPEGImages
- --00001.jpg
- --00002.jpg
需要准备一定数量的各类别的图片,还需要安装labelimg,你只需在终端输入pip install labelimg即可安装,之后输入labelimg打开,长下面这样的:
点击open dir是寻找要打标签的文件夹,即JPEGImages,然后选择生成xml的文件夹,即Annotations,再选择view ->Auto save mode开启自动保存。按w键拖动框柱要框柱的类别,这个相当于标签,即模型学习的答案,所以标签的质量会影响到模型的效果。全部标注好之后可以查看Annotations是否生成所有的xml。打标签环节结束。
打开data文件夹,这里有官方的voc.yaml文件,你需要自己创建一个类似的.yaml文件,按情况修改以下参数:nc(类别数),names(类别名),然后根据JPEGImages和Annotations的信息进行voc_to_yolo的转换,创建一个python脚本,具体代码:
- import xml.etree.ElementTree as ET
- import pickle
- import os
- from os import listdir, getcwd
- from os.path import join
- import random
- from shutil import copyfile
-
- classes = ["one","two",]
-
- TRAIN_RATIO = 50
-
-
- def clear_hidden_files(path):
- dir_list = os.listdir(path)
- for i in dir_list:
- abspath = os.path.join(os.path.abspath(path), i)
- if os.path.isfile(abspath):
- if i.startswith("._"):
- os.remove(abspath)
- else:
- clear_hidden_files(abspath)
-
-
- def convert(size, box):
- dw = 1. / size[0]
- dh = 1. / size[1]
- x = (box[0] + box[1]) / 2.0
- y = (box[2] + box[3]) / 2.0
- w = box[1] - box[0]
- h = box[3] - box[2]
- x = x * dw
- w = w * dw
- y = y * dh
- h = h * dh
- return (x, y, w, h)
-
-
- def convert_annotation(image_id):
- in_file = open('VOCdevkit/VOC2007/Annotations/%s.xml' % image_id)
- out_file = open('VOCdevkit/VOC2007/YOLOLabels/%s.txt' % image_id, 'w')
- tree = ET.parse(in_file)
- root = tree.getroot()
- size = root.find('size')
- w = int(size.find('width').text)
- h = int(size.find('height').text)
-
- for obj in root.iter('object'):
- # difficult = obj.find('difficult').text
- cls = obj.find('name').text
- if cls not in classes:
- continue
- cls_id = classes.index(cls)
- xmlbox = obj.find('bndbox')
- b = (float(xmlbox.find('xmin').text), float(xmlbox.find('xmax').text), float(xmlbox.find('ymin').text),
- float(xmlbox.find('ymax').text))
- bb = convert((w, h), b)
- out_file.write(str(cls_id) + " " + " ".join([str(a) for a in bb]) + '\n')
- in_file.close()
- out_file.close()
-
-
- wd = os.getcwd()
- wd = os.getcwd()
- data_base_dir = os.path.join(wd, "VOCdevkit/")
- if not os.path.isdir(data_base_dir):
- os.mkdir(data_base_dir)
- work_sapce_dir = os.path.join(data_base_dir, "VOC2007/")
- if not os.path.isdir(work_sapce_dir):
- os.mkdir(work_sapce_dir)
- annotation_dir = os.path.join(work_sapce_dir, "Annotations/")
- if not os.path.isdir(annotation_dir):
- os.mkdir(annotation_dir)
- clear_hidden_files(annotation_dir)
- image_dir = os.path.join(work_sapce_dir, "JPEGImages/")
- if not os.path.isdir(image_dir):
- os.mkdir(image_dir)
- clear_hidden_files(image_dir)
- yolo_labels_dir = os.path.join(work_sapce_dir, "YOLOLabels/")
- if not os.path.isdir(yolo_labels_dir):
- os.mkdir(yolo_labels_dir)
- clear_hidden_files(yolo_labels_dir)
- yolov5_images_dir = os.path.join(data_base_dir, "images/")
- if not os.path.isdir(yolov5_images_dir):
- os.mkdir(yolov5_images_dir)
- clear_hidden_files(yolov5_images_dir)
- yolov5_labels_dir = os.path.join(data_base_dir, "labels/")
- if not os.path.isdir(yolov5_labels_dir):
- os.mkdir(yolov5_labels_dir)
- clear_hidden_files(yolov5_labels_dir)
- yolov5_images_train_dir = os.path.join(yolov5_images_dir, "train/")
- if not os.path.isdir(yolov5_images_train_dir):
- os.mkdir(yolov5_images_train_dir)
- clear_hidden_files(yolov5_images_train_dir)
- yolov5_images_test_dir = os.path.join(yolov5_images_dir, "val/")
- if not os.path.isdir(yolov5_images_test_dir):
- os.mkdir(yolov5_images_test_dir)
- clear_hidden_files(yolov5_images_test_dir)
- yolov5_labels_train_dir = os.path.join(yolov5_labels_dir, "train/")
- if not os.path.isdir(yolov5_labels_train_dir):
- os.mkdir(yolov5_labels_train_dir)
- clear_hidden_files(yolov5_labels_train_dir)
- yolov5_labels_test_dir = os.path.join(yolov5_labels_dir, "val/")
- if not os.path.isdir(yolov5_labels_test_dir):
- os.mkdir(yolov5_labels_test_dir)
- clear_hidden_files(yolov5_labels_test_dir)
-
- train_file = open(os.path.join(wd, "yolov7_train.txt"), 'w')
- test_file = open(os.path.join(wd, "yolov7_val.txt"), 'w')
- train_file.close()
- test_file.close()
- train_file = open(os.path.join(wd, "yolov7_train.txt"), 'a')
- test_file = open(os.path.join(wd, "yolov7_val.txt"), 'a')
- list_imgs = os.listdir(image_dir) # list image files
- prob = random.randint(1, 100)
- print("Probability: %d" % prob)
- for i in range(0, len(list_imgs)):
- path = os.path.join(image_dir, list_imgs[i])
- if os.path.isfile(path):
- image_path = image_dir + list_imgs[i]
- voc_path = list_imgs[i]
- (nameWithoutExtention, extention) = os.path.splitext(os.path.basename(image_path))
- (voc_nameWithoutExtention, voc_extention) = os.path.splitext(os.path.basename(voc_path))
- annotation_name = nameWithoutExtention + '.xml'
- annotation_path = os.path.join(annotation_dir, annotation_name)
- label_name = nameWithoutExtention + '.txt'
- label_path = os.path.join(yolo_labels_dir, label_name)
- prob = random.randint(1, 100)
- print("Probability: %d" % prob)
- if (prob < TRAIN_RATIO): # train dataset
- if os.path.exists(annotation_path):
- train_file.write(image_path + '\n')
- convert_annotation(nameWithoutExtention) # convert label
- copyfile(image_path, yolov5_images_train_dir + voc_path)
- copyfile(label_path, yolov5_labels_train_dir + label_name)
- else: # test dataset
- if os.path.exists(annotation_path):
- test_file.write(image_path + '\n')
- convert_annotation(nameWithoutExtention) # convert label
- copyfile(image_path, yolov5_images_test_dir + voc_path)
- copyfile(label_path, yolov5_labels_test_dir + label_name)
- train_file.close()
- test_file.close()
你只需要修改类别数即可。运行之后会在VOCdevkit里生成images和labels文件夹。这时你要找到之前创建的.yaml文件,修改train和val的路径,改成images里的train和val。此环节结束。
接下来看看train,py,从522行(左右)起是主程序,修改weights为‘yolov7.pt’,如果你没有这个文件,可以到github去下载(上述),修改data为你的.yaml文件,修改epochs,batchsize,img-size,device,workers为你想要参数(不改也可以),然后运行。训练好的模型在runs/train
打开detect.py,将训练好的.pth文件放到weights,souce选择预测模式(图片、视频、摄像头),其他的不用改。
这样,你就能用自己的数据集得到需要的目标检测模型!!!
以上为全部内容。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。