一 Darknet-Yolov3下载与安装

源文件下载地址:https://github.com/pjreddie/darknet
<https://github.com/pjreddie/darknet>

下载解压完后,将darknet-master主文件夹的名字改为darknet

之后修改Makefile,因为是使用GPU版本,将GPU=0改为 GPU=1

然后使用make指令运行Makefile。

模型下载地址:https://pjreddie.com/media/files/darknet53.conv.74
<https://pjreddie.com/media/files/darknet53.conv.74>

下载完放到主目录下(其实哪都可以)

安装结束

二 创建自己的数据集

没有固定的文件存放格式,只是希望规范管理训练集标签等数据。

在我创建的数据集的总目录是_VOCdevkit,其中有各个数据集,就如数据集test0为例



my_yolov3.cfg用于保存超参数

myv3.names保存各个标签的名字(按标签升序排列,标签从0开始)

myv3_det.data为配置文件,用于指明训练集,验证集,names,backup的保存目录

train.txt与val.txt用于保存训练集和验证集图片的路径

train_id.txt与val_id.txt用于保存训练集和验证集图片的名称(无后缀)

test文件夹用于存放测试图片

backups文件夹用于保存训练得到的权重

注:cfg,names,data文件是必须的配置文件

三 生成train.txt等文件

以下代码基于 如上文件夹结构

运行以下文件生成train.txt等文件
import os from os import listdir SUFFIX='.JPEG' def
generate_txt(source_folder,xml_source,train_dest,val_dest,train_id_dest,val_id_dest,train_num,val_num):
if(xml_source!=None): file_list = os.listdir(xml_source) else: file_list =
os.listdir(source_folder) train_file=open(train_dest,'a')
train_id_file=open(train_id_dest,'a') train_file.seek(0) train_file.truncate()
train_id_file.seek(0) train_id_file.truncate() if val_dest != None:
val_file=open(val_dest,'a') val_id_file=open(val_id_dest,'a') val_file.seek(0)
val_file.truncate() val_id_file.seek(0) val_id_file.truncate() num=0 for obj in
file_list: name=obj.split('.')[0] path=os.path.join(source_folder,name+SUFFIX)
num=num+1 if(num<=train_num): train_file.write(path+'\n')
train_id_file.write(name+'\n') else: if(val_dest!=None and
num<train_num+val_num): val_file.write(path+'\n') val_id_file.write(name+'\n')
return source_folder='/home/lthpc/CJX/default_res/n02974003_wheel'
xml_source='/home/lthpc/CJX/default_res/n02974003_wheel/n02974003'
train_dest='/home/lthpc/CJX/darknet/_VOCdevkit/test0/train.txt'
val_dest='/home/lthpc/CJX/darknet/_VOCdevkit/test0/val.txt'
train_id_dest='/home/lthpc/CJX/darknet/_VOCdevkit/test0/train_id.txt'
val_id_dest='/home/lthpc/CJX/darknet/_VOCdevkit/test0/val_id.txt' train_num=200
val_num=40
generate_txt(source_folder,xml_source,train_dest,val_dest,train_id_dest,val_id_dest,train_num,val_num)
参数解释:

SUFFIX:图片格式

source_folder:所有图片存放位置

xml_source:若有xml标签,则其为xml标签存放位置;若无,=None

train_dest:train.txt位置,其它同理

train_num:训练图片数量

val_num:测试图片数量

四 xml格式的label转为txt格式


一般使用LabelImg进行图片标注,生成格式为xml的标注结果,而darknet要求的格式为txt,运行以下文件将xml转为txt格式,txt格式的label保存目录为图片存放位置
import xml.etree.ElementTree as ET import pickle import os from os import
listdir, getcwd from os.path import join sets=['train','val']
classes=['n02974003'] 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(anno_source,demo_name, image_id,img_source):
in_file = open(os.path.join(anno_source,image_id+'.xml')) print(in_file)
out_file = open(img_source+"/"+image_id+'.txt', '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) out_file.seek(0) out_file.truncate() 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: 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') def main_convert(anno_source,demo_name,image_sets,img_source): for
image_set in image_sets: image_ids =
open('/home/lthpc/CJX/darknet/_VOCdevkit/%s/%s_id.txt' %
(demo_name,image_set)).read().strip().split() for image_id in image_ids:
convert_annotation(anno_source,demo_name,image_id,img_source) return
main_convert('/home/lthpc/CJX/default_res/n02974003_wheel/n02974003','test0',sets,
'/home/lthpc/CJX/default_res/n02974003_wheel')
参数说明:

sets不需要更改

classes:类别名称,与xml中的obj的name相同,示例中展示了一类,若为多类请自行扩展数组

anno_source:xml文件存放位置

demo_name:项目名称,即_VOCdevkit下子文件名称

img_source:图片存放位置

至此所有配置文件生成完毕

五 训练与测试数据

通过cd指令进入darknet子文件夹,通过如下命令进行训练:
./darknet detector train data文件位置 cfg文件位置 模型位置 -gpu 使用的gpu
举一实例如下:
./darknet detector train _VOCdevkit/test0/myv3_det.data
_VOCdevkit/test0/my_yolov3.cfg darknet53.conv.74 -gpu 0,1,2,3,4
训练过后再backups中生成权重文件,用最大次迭代的权重进行测试,使用如下命令进行测试:
./darknet detector test data文件位置 cfg文件位置 权重文件位置 测试图片位置
举一示例如下:
./darknet detector test _VOCdevkit/test0/myv3_det.data
_VOCdevkit/test0/my_yolov3.cfg _VOCdevkit/test0/backups/my_yolov3_900.weights
_VOCdevkit/test0/test/n04285008_744.JPEG
最后在命令行生成测试准确度,并在darknet下的predictions.jpg框出结果,实例如下:



六 结语

本篇为darknet-yolov3的基本操作,至于更改超参数,则自行学习,不予赘述