Yolov3+VisDrone2020训练数据集

在前期准备的时候可以对比一下我文章中的修改的地方

前期准备参考:

参考1

参考2

 

改动的地方:

参考1, 在linux环境下转换:

1.路径都修改成绝对路径

rename.py

 1 # -*- coding: utf-8 -*-
 2 """
 3 Created on Thu May  9 18:02:02 2019
 4 
 5 @author: qnh12
 6 """
 7 
 8 
 9 # -*- coding: utf-8 -*-
10 
11 import os
12 
13 #path = "C:\\Users\\syx\\Desktop\\train\\images"  #根据自己需要修改,转化完image转化annotations
14 path = "/home/lhw/Gradute/VirDrone/VisDrone2019-DET-train/annotations"
15 
16 filelist = os.listdir(path) #该文件夹下所有的文件(包括文件夹)
17 
18 count=1
19 
20 for file in filelist:
21 
22     print(file)
23 
24 for file in filelist:   #遍历所有文件
25 
26     Olddir=os.path.join(path,file)   #原来的文件路径
27 
28     if os.path.isdir(Olddir):   #如果是文件夹则跳过
29 
30         continue
31 
32     filename=os.path.splitext(file)[0]   #文件名
33 
34     filetype=os.path.splitext(file)[1]   #文件扩展名
35 
36     Newdir=os.path.join(path,str(count).zfill(6)+filetype)  #os.path.join路径拼接,并用字符串函数zfill 以0补全所需位数
37 
38     os.rename(Olddir,Newdir)#重命名
39 
40     count+=1
View Code

main.py

import os
from PIL import Image

#root_dir = "train/"
root_dir = "/home/lhw/Gradute/VirDrone/VisDrone2019-DET-train/"
annotations_dir = root_dir+"annotations/"
image_dir = root_dir + "images/"
xml_dir = root_dir+"annotations_/"  #注意新建文件夹。后续改一下名字,运行完成之后annotations这个文件夹就不需要了。把annotations_命名为annotations
class_name = ['ignored regions','pedestrian','people','bicycle','car','van','truck','tricycle','awning-tricycle','bus','motor','others']

for filename in os.listdir(annotations_dir):
    fin = open(annotations_dir+filename, 'r')
    image_name = filename.split('.')[0]
    img = Image.open(image_dir+image_name+".jpg")
    xml_name = xml_dir+image_name+'.xml'
    with open(xml_name, 'w') as fout:
        fout.write('<annotation>'+'\n')
        
        fout.write('\t'+'<folder>VOC2007</folder>'+'\n')
        fout.write('\t'+'<filename>'+image_name+'.jpg'+'</filename>'+'\n')
        
        fout.write('\t'+'<source>'+'\n')
        fout.write('\t\t'+'<database>'+'VisDrone2018 Database'+'</database>'+'\n')
        fout.write('\t\t'+'<annotation>'+'VisDrone2018'+'</annotation>'+'\n')
        fout.write('\t\t'+'<image>'+'flickr'+'</image>'+'\n')
        fout.write('\t\t'+'<flickrid>'+'Unspecified'+'</flickrid>'+'\n')
        fout.write('\t'+'</source>'+'\n')
        
        fout.write('\t'+'<owner>'+'\n')
        fout.write('\t\t'+'<flickrid>'+'Haipeng Zhang'+'</flickrid>'+'\n')
        fout.write('\t\t'+'<name>'+'Haipeng Zhang'+'</name>'+'\n')
        fout.write('\t'+'</owner>'+'\n')
        
        fout.write('\t'+'<size>'+'\n')
        fout.write('\t\t'+'<width>'+str(img.size[0])+'</width>'+'\n')
        fout.write('\t\t'+'<height>'+str(img.size[1])+'</height>'+'\n')
        fout.write('\t\t'+'<depth>'+'3'+'</depth>'+'\n')
        fout.write('\t'+'</size>'+'\n')
        
        fout.write('\t'+'<segmented>'+'0'+'</segmented>'+'\n')

        for line in fin.readlines():
            line = line.split(',')
            fout.write('\t'+'<object>'+'\n')
            fout.write('\t\t'+'<name>'+class_name[int(line[5])]+'</name>'+'\n')
            fout.write('\t\t'+'<pose>'+'Unspecified'+'</pose>'+'\n')
            fout.write('\t\t'+'<truncated>'+line[6]+'</truncated>'+'\n')
            fout.write('\t\t'+'<difficult>'+str(int(line[7]))+'</difficult>'+'\n')
            fout.write('\t\t'+'<bndbox>'+'\n')
            fout.write('\t\t\t'+'<xmin>'+line[0]+'</xmin>'+'\n')
            fout.write('\t\t\t'+'<ymin>'+line[1]+'</ymin>'+'\n')
            # pay attention to this point!(0-based)
            fout.write('\t\t\t'+'<xmax>'+str(int(line[0])+int(line[2])-1)+'</xmax>'+'\n')
            fout.write('\t\t\t'+'<ymax>'+str(int(line[1])+int(line[3])-1)+'</ymax>'+'\n')
            fout.write('\t\t'+'</bndbox>'+'\n')
            fout.write('\t'+'</object>'+'\n')
             
        fin.close()
        fout.write('</annotation>')
View Code

trainnamelist.py

# -*- coding: utf-8 -*-
"""
Created on Fri May 10 10:36:36 2019

@author: qnh12
"""

import os
import random


def _main():
    trainval_percent = 0.2
    train_percent = 0.9
    xmlfilepath = '/home/lhw/Gradute/VirDrone/VisDrone2019-DET-train/annotations/'
    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('/home/lhw/Gradute/VirDrone/VisDrone2019-DET-train/ImageSets/Main/trainval.txt', 'w')
    ftest = open('/home/lhw/Gradute/VirDrone/VisDrone2019-DET-train/ImageSets/Main/test.txt', 'w')
    ftrain = open('/home/lhw/Gradute/VirDrone/VisDrone2019-DET-train/ImageSets/Main/train.txt', 'w')
    fval = open('/home/lhw/Gradute/VirDrone/VisDrone2019-DET-train/ImageSets/Main/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()


if __name__ == '__main__':
    _main()
View Code

label.py

import xml.etree.ElementTree as ET
import pickle
import os
from os import listdir, getcwd
from os.path import join
 
sets = ['train', 'test','val']
 
classes = ['ignored regions','pedestrian','people','bicycle','car','van','truck','tricycle','awning-tricycle','bus','motor','others'] # each category's name
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('/home/lhw/Gradute/VirDrone/VisDrone2019-DET-train/annotations/%s.xml' % (image_id))
    out_file = open('/home/lhw/Gradute/VirDrone/VisDrone2019-DET-train/labels/%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 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)
        if cls_id != 0 :  #忽略掉0类
            if cls_id != 11 :   #忽略掉11类
                out_file.write(str(cls_id-1) + " " + " ".join([str(a) for a in bb]) + '\n')   #其他类id-1。可以根据自己需要修改代码
        
 
wd = getcwd()
print(wd)
for image_set in sets:
    if not os.path.exists('/home/lhw/Gradute/VirDrone/VisDrone2019-DET-train/labels/'):
        os.makedirs('/home/lhw/Gradute/VirDrone/VisDrone2019-DET-train/labels/')
    image_ids = open('/home/lhw/Gradute/VirDrone/VisDrone2019-DET-train/ImageSets/Main/%s.txt' % (image_set)).read().strip().split()
    list_file = open('%s.txt' % (image_set), 'w')
    for image_id in image_ids:
        list_file.write('/home/lhw/Gradute/VirDrone/VisDrone2019-DET-train/images/%s.jpg\n' % (image_id))
        convert_annotation(image_id)
    list_file.close()
View Code

 

参考2:

1.更改下载源

git clone https://github.com/AlexeyAB/darknet.git
cd darknet

2. 更改Makefile文件

GPU=1 
CUDNN=1  
OPENCV=1     #增加opencv模块,显示图片,需系统安装opencv4
OPENMP=0  
DEBUG=0 

3.复制cfg/yolov3-voc.cfg文件并重命名为cfg/yolov3-voc-visdrone.cfg     (可不做)

 yolov4需要更改cfg/yolov4.cfg,将分辨率设置为416*416,max_batches=20000(class的2000倍,class=10), steps= 16000,18000(max_batches的80%和90%)

其他与参考2更改一致

cfg文件参数详解参考

yolov4操作

 4.训练,加上日志消息,可方便后期绘图

./darknet detector train cfg/voc.data cfg/yolov3-voc-visdrone.cfg scripts/darknet53.conv.74 2>&1 | tee visualization/train_yolov3.log

 

暂停后(ctrl+c)继续训练(将backup中保存的模型复制到script下)

./darknet detector train cfg/voc.data cfg/yolov3-voc-visdrone.cfg scripts/yolov3-voc-visdrone_last.weights 2>&1 | tee visualization/train_yolov3.log

验证

./darknet detector map cfg/voc.data cfg/yolov3-voc-visdrone.cfg scripts/yolov3-voc-visdrone_last.weights

计算验证集ACC

./darknet detector recall cfg/voc.data cfg/yolov3-voc-visdrone.cfg scripts/yolov3-voc-visdrone_last.weights

 

 

 

 

测试

注:我这里是yolov3-voc-visdrone_last.weights文件,根据实际文件名修改 

./darknet detector test cfg/voc.data cfg/yolov3-voc-visdrone.cfg backup/yolov3-voc-visdrone_last.weights test/002007.jpg

新建test文件夹,将待测试的图片放到文件夹下

错误:

1. Can't open label file. (This can be normal only if you use MSCOCO

一般是.txt文件夹中的路径错误 

 

posted @ 2021-01-24 00:00  小小灰迪  阅读(1073)  评论(0编辑  收藏  举报