软件环境:WIN10,CUDA10.1,CUDNN8.0.3,python3.7,VS2017,OpenCV4.4.0
硬件环境:GTX1060 6G
CUDA:https://developer.nvidia.com/cuda-toolkit-archive
只安装CUDA
CUDNN:https://developer.nvidia.com/rdp/cudnn-archive
解压后,将三个文件夹里的内容放到对应C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v10.1目录下bin,include,lib/x64
OpenCV:https://opencv.org/releases/
添加环境变量:
C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v10.1
C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v10.1\bin
C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v10.1\lib\x64
C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v10.1\libnvvp
C:\Program Files\NVIDIA Corporation\NVSMI
E:\opencv\build\x64\vc14\bin
下载darknet
进入darknet/build/darknet,编辑文件darknet.vcxproj,替换55行和293行的CUDA版本号;
打开darknet.sln,设置解决方案配置为Release,解决方案平台为x64;重定向的时候,平台工具集选择:无升级。
进入项目属性页,修改配置属性->VC++ Directories->General->Include Directories为E:\opencv\build\include,->Library Directories为E:\opencv\build\x64\vc14\lib,修改配置属性->Linker->Input->Additional Dependencies在4个默认lib文件名后添加opencv_world440.lib,并将opencv\build\x64\vc15\bin下的opencv_videoio_ffmpeg440_64.dll和opencv_world440.dll放到darknet\build\darknet\x64目录下;
编译生成darknet。
测试:
darknet.exe detector test cfg/coco.data cfg/yolov4.cfg yolov4.weights dog.jpg
以下内容根据自己实际情况修改
在x64\data目录下创建VOCdevkit\VOC2020,在创建4个目录分别是Annotations,ImageSets,JPEGImages,labels,Annotations存放xml文件,JPEGImages存放所有图像,在ImageSets下创建Main目录,创建train.txt和test.txt,创建脚本文件generate_train_and_test.py
import os
from os import listdir, getcwd
from os.path import join
if __name__ == '__main__':
source_folder = '.../VOCdevkit/VOC2020/JPEGImages'
dest = '.../VOCdevkit/VOC2020/ImageSets/Main/train.txt'
dest2 = '.../VOCdevkit/VOC2020/ImageSets/Main/test.txt'
file_list = os.listdir(source_folder)
train_file = open(dest, 'a')
test_file = open(dest2, 'a')
count = 0
for file_obj in file_list:
count += 1
file_name, file_extend = os.path.splitext(file_obj)
# 总848 训练678 测试170
if (count<678):
train_file.write(file_name + '\n')
else:
test_file.write(file_name + '\n')
train_file.close()
test_file.close()
在x64\data\voc\voc_label.py,修改如下,修改后执行python voc_label.py:
import xml.etree.ElementTree as ET
import pickle
import os
from os import listdir, getcwd
from os.path import join
#sets=[('2012', 'train'), ('2012', 'val'), ('2007', 'train'), ('2007', 'val'), ('2007', 'test')]
sets=[('2020', 'train'), ('2020', 'test')]
#classes = ["aeroplane", "bicycle", "bird", "boat", "bottle", "bus", "car", "cat", "chair", "cow", "diningtable", "dog", "horse", "motorbike", "person", "pottedplant", "sheep", "sofa", "train", "tvmonitor"]
classes = [要识别的类别,参考上面的格式写]
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(year, image_id):
in_file = open('。。。此处改为自己的路径/data/VOCdevkit/VOC%s/Annotations/%s.xml'%(year, image_id))
out_file = open('。。。此处改为自己的路径/data/VOCdevkit/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:
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('。。。此处改为自己的路径/data/VOCdevkit/VOC%s/labels/'%(year)):
os.makedirs('。。。此处改为自己的路径/data/VOCdevkit/VOC%s/labels/'%(year))
image_ids = open('。。。此处改为自己的路径/data/VOCdevkit/VOC%s/ImageSets/Main/%s.txt'%(year, image_set)).read().strip().split()
list_file = open('。。。此处改为自己的路径/data/%s_%s.txt'%(year, image_set), 'w')
for image_id in image_ids:
list_file.write('。。。此处改为自己的路径/data/VOCdevkit/VOC%s/JPEGImages/%s.jpg\n'%(year, image_id))
convert_annotation(year, image_id)
list_file.close()
在x64\data目录创建obj.data和obj.names
obj.data内容如下
classes = 7
train = data/2020_train.txt
valid = data/2020_test.txt
names = data/obj.names
backup = backup/
obj.names 内容如下
class_name_1
class_name_2
class_name_3
class_name_4
class_name_5
修改yolov4.cfg文件
修改其中的max_batches、steps、classes、filters
max_batches = classes * 2000
steps = max_batches * 0.8, max_batches * 0.9
修改[yolo[中的classes为识别类别数
修改[yolo]层之前的[convolutional]层中的filters=(classes + 5) * 3
训练执行
darknet.exe detector train data\obj.data cfg\yolov4-obj.cfg yolov4.conv.137 -map