前置:下载最新版本darknet并编译,编译opencv
一、数据准备
在darknet-master下建立自己的数据twodata,将自己的数据弄成这种形式:
图片放JPRGImages,xml放Annotations,ImageSets是空文件夹。
其中makeTxt.py
import os
import random
trainval_percent = 0.1
train_percent = 0.9
xmlfilepath = './VOC2008/Annotations'
txtsavepath = './VOC2008/ImageSets'
total_xml = os.listdir(xmlfilepath)
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)
ftrainval = open('./VOC2008/ImageSets/trainval.txt', 'w')
ftest = open('./VOC2008/ImageSets/test.txt', 'w')
ftrain = open('./VOC2008/ImageSets/train.txt', 'w')
fval = open('./VOC2008/ImageSets/val.txt', 'w')
for i in list:
name = total_xml[i][:-4] + '\n'
if i in trainval:
ftrainval.write(name)
if i in train:
ftest.write(name)
else:
fval.write(name)
else:
ftrain.write(name)
ftrainval.close()
ftrain.close()
fval.close()
ftest.close()
其中,voc_label.py: 注:如果训练自己的类,就将classes改成对应的类,这里是Coco的80类。
import xml.etree.ElementTree as ET
import pickle
import os
from os import listdir, getcwd
from os.path import join
sets=[('2008', 'train'), ('2008', 'test'),('2008', 'val')]
classes = ["person","bicycle","car","ebike","aeroplane","bus","train","truck","boat",
"traffic light",
"fire hydrant",
"stop sign",
"parking meter",
"bench",
"bird",
"cat",
"dog",
"horse",
"sheep",
"cow",
"elephant",
"bear",
"zebra",
"giraffe",
"backpack",
"umbrella",
"handbag",
"tie",
"suitcase",
"frisbee",
"skis",
"snowboard",
"sports ball",
"kite",
"baseball bat",
"baseball glove",
"skateboard",
"surfboard",
"tennis racket",
"bottle",
"wine glass",
"cup",
"fork",
"knife",
"spoon",
"bowl",
"banana",
"apple",
"sandwich",
"orange",
"broccoli",
"carrot",
"hot dog",
"pizza",
"donut",
"cake","chair",
"sofa","pottedplant","bed","diningtable","toilet","tvmonitor","laptop","mouse","remote","keyboard","cell phone","microwave","oven","toaster","sink","refrigerator","book","clock","vase","scissors","teddy bear","hair drier","toothbrush"]
def convert(size, box):
dw = 1./(size[0])
dh = 1./(size[1])
x = (box[0] + box[1])/2.0 - 1
y = (box[2] + box[3])/2.0 - 1
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(year, image_id):
in_file = open('VOC%s/Annotations/%s.xml'%(year, image_id))
out_file = open('VOC%s/labels/%s.txt'%(year, 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 or int(difficult)==1:
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')
wd = getcwd()
for year, image_set in sets:
if not os.path.exists('VOC%s/labels/'%(year)):
os.makedirs('VOC%s/labels/'%(year))
image_ids = open('VOC%s/ImageSets/%s.txt'%(year, image_set)).read().strip().split()
list_file = open('%s_%s.txt'%(year, image_set), 'w')
for image_id in image_ids:
list_file.write('%s/VOC%s/JPEGImages/%s.jpg\n'%(wd, year, image_id))
convert_annotation(year, image_id)
list_file.close()
#os.system("cat 2008_train.txt 2008_val.txt > train.txt")
os.system("cat 2008_train.txt 2008_val.txt 2008_test.txt> train.txt")
#os.system("cat 2014_train.txt 2014_val.txt 2012_train.txt 2012_val.txt > train.txt")
#os.system("cat 2007_train.txt 2007_val.txt 2007_test.txt 2012_train.txt 2012_val.txt > train.all.txt")
先后执行,即可。
至此,数据准备就完成了。
二、yolov4训练和测试:
将cfg文件夹中的yolov4.cfg,coco.data,coco.names 复制到twodata下。
1.yolov4.cfg修改(调参规则):classes多少类就改多少,filters是(类数+5)*3后的值,只训练单类就是18,一共三处都要改。
然后就是max_batches,根据一个类至少训2000次的规则,自行调整。steps是max_batches的80%,90%。
lr一般是降为基础的0.1倍。
2.coco.data修改:
classes= 80
train = ./twodata/train.txt
valid = ./twodata/2008_val.txt
names = ./twodata/coco.names
backup = backup
3.coco.names修改:改成自己的类名即可。
(darknet预训练模型开始训练)./darknet detector train twodata/coco.data twodata/yolov4.cfg yolov4.conv.137 -map
(在Coco80类基础上继续训练)./darknet detector train twodata/coco.data twodata/yolov4.cfg yolov4.weights -clear -map
(yolov4视频测试并保存)./darknet detector demo twodata/coco.data twodata/yolov4.cfg backup/yolov4_4000.weights 10.ts -out_filename res1.avi
原文链接:https://blog.csdn.net/qq_34717531/article/details/108355384