好了,多的也不说,直接开始吧!

1.下载预训练的好权重文件 yolov4.conv.137,放在build/darknet/x64/下

2.创建配置文件:在darknet-master/cfg/下,创建yolo-obj_fre.cfg:

这个文件里面的内容跟cfg/yolov4-custom.cfg类似,只是有几个地方需要修改

1) batch=8                     #依据你电脑的显存大小而定,尽量设大一点
2) subdivisions=64             # 这里最好设为64,不然训练的时候会报错
3) max_batches=8000            #classes*2000   
4) steps=6400,7200             #max_batches*0.8,max_batches*0.9
5) 修改3个[yolo]下classes=4     #你要训练的类别数
6) 修改3个[yolo]上面filters=27  #filters=(classes + 5)x3,注意只修改每个[yolo]上面最后一个conv的filters

3.在build\darknet\x64\data\下,创建fre.names文件,其中每一行写上一个你要训练的一个类别,eg:

apple
bickly
cell
bag

4.在build\darknet\x64\data\下,创建fre.data文件:

classes= 4
train  = build/darknet/x64/data/train.txt    #  这个下面说,train.txt里面存放着训练图片的存放路径
valid  = build/darknet/x64/data/test.txt     # 
names =  build/darknet/x64/data/fre.names    #  步骤3创建的fre.names
backup = backup/

注:下面步骤5,6均用代码完成

5.为每一张训练图片创建一个.txt文件。 例如 img1.jpg,那么你就创建img1.txt,这个文件里面包含:

1 0.716797 0.395833 0.216406 0.147222
0 0.687109 0.379167 0.255469 0.158333
1 0.420312 0.395833 0.140625 0.166667
注意,这个创建的img1.txt与训练图片img1.jpg在同一个文件夹里,eg:build/darknet/x64/data/obj
class_id、x_center 、y_center、width、height

注意上面的x_center y_center width height的数值都是相对图片的尺度而言的,即:
x_center = x / image_width
y_center = y / image_height
width = gt_width / image_width
height = gt_height / image_height

那么问题来了,如何将labelimg的标签(xml文件)转换为yolov4的标签格式,我们通过代码来实现,但是先不急,先把步骤6讲完,再用代码一起实现步骤5、6。

6.在build/darknet/x64/data/下,创建train.txt文件,里面保存训练图片文件的路径:

data/obj/img1.jpg
data/obj/img2.jpg
data/obj/img3.jpg

好了,下面奉上代码:xml_to_txt.py

# -*- coding: utf-8 -*-
# ——author—— = “调得一手好参”
# Email : 928343544@qq.com
# time  : 2020.5.12
# function: 将xml文件转为yolo的标签

import os
import argparse
import xml.etree.ElementTree as ET
import glob

def xml_to_txt(data_path,anno_path,path,use_difficult_bbox=False):

    classes = ['am','fm','gsm','qpsk']
    image_inds = file_name(data_path+"train_label/") #遍历xml文件

    with open(anno_path, 'a') as f:
        for image_ind in image_inds:
            
            img_txt = data_path + 'obj/'+ image_ind + '.txt'
            img_txt_file = open(img_txt, 'w')

            image_path = os.path.join(data_path, 'obj/', image_ind + '.jpg')  
            

            label_path = os.path.join(data_path, 'train_label', image_ind +'.xml')
            root = ET.parse(label_path).getroot()
            objects_size = root.findall('size')
            image_width = int(objects_size[0].find('width').text)
            image_height = int(objects_size[0].find('height').text)

            objects = root.findall('object')
            for obj in objects:
                difficult = obj.find('difficult').text.strip()
                if (not use_difficult_bbox) and(int(difficult) == 1):
                    continue
                bbox = obj.find('bndbox')
                class_ind = str(classes.index(obj.find('name').text.lower().strip()))
                xmin = int(bbox.find('xmin').text.strip())
                xmax = int(bbox.find('xmax').text.strip())
                ymin = int(bbox.find('ymin').text.strip())
                ymax = int(bbox.find('ymax').text.strip())

                x_center = str((xmin + xmax)/(2*image_width))
                y_center = str((ymin + ymax)/(2*image_height))
                width_   = str((xmax - xmin)/(image_width))
                height_  = str((ymax - ymin)/(image_height))
               
                class_ind += ' ' + ','.join([x_center+' '+y_center+' '+width_+' '+height_])
                img_txt_file.write(class_ind + "\n")
                
            f.write(image_path + "\n")


def file_name(file_dir):
    L = []
    for root, dirs, files in os.walk(file_dir):
        for file in files:
            if os.path.splitext(file)[1] == '.xml':
                L.append(file.split(".")[0])
    return L


if __name__ == '__main__':
    
    num1 = xml_to_txt('./build/darknet/x64/data/','./build/darknet/x64/data/train.txt','train')
    # num2 = convert_voc_annotation('./data/', './data/test.txt', False)
    print('done')

快速使用代码:

1)将xml_to_txt.py放在darknet-master目录下
2)将xml文件放在 ./build/darknet/x64/data/train_label
3)将训练图片文件放在 ./build/darknet/x64/data/obj
4)运行代码

在./build/darknet/x64/data/下生成 train.txt文件
在./build/darknet/x64/data/obj/ 下生成 img.txt

上面是将xml文件转为txt文件,如果你使用labelme软件打.json文件标签,用下面的代码转为txt文件:

import os
import argparse
import json
import glob
import numpy as np



def json_to_txt(data_path,save_path,train_txt_file):

    classes = ['apple','balance','car','person']  #这里填写你要训练的类

    train_txt = train_txt_file
    train_txt_path = open(train_txt, 'w')

    for num,json_file in enumerate(data_path):
        
        with open(json_file,'r') as fp:    
            data = json.load(fp)  # 加载json文件
        

            file_name = ''

            file_name = ''
            for name in data["imagePath"].split('.'):
                if name == 'jpg' or name == 'png':
                    break
                elif name[-1]=='Z':
                    file_name +=name
                elif data["imagePath"].split('.').index(name)<2:
                    file_name += name+'.'
                else:
                    file_name += name


            if file_name[-1] =='.':
                img_txt =    save_path + file_name+ 'txt'
                image_path = save_path + file_name+ 'jpg'
            else:
                img_txt =    save_path + file_name+ '.txt'
                image_path = save_path + file_name+ '.jpg'


            with open(img_txt,'w') as img_txt_file:
        
                
                img_height = data['imageHeight']
                img_width  = data['imageWidth']

                for obj in data["shapes"]:
                
                    class_id = str(classes.index(obj["label"]))
                    
                    x_zoom = []
                    y_zoom = []
                    for zoom in obj["points"]:
                        x_zoom.append(zoom[0])
                        y_zoom.append(zoom[1])

                    min_x = min(x_zoom)
                    max_x = max(x_zoom)
                    min_y = min(y_zoom)
                    max_y = max(y_zoom)

                    # # convert()
                    # right_low_index = np.argmax(np.sum(np.array(obj["points"]),1))
                    # left_top_index = np.argmin(np.sum(np.array(obj["points"]),1))
                    # right_low = obj["points"][right_low_index]
                    # left_top = obj["points"][left_top_index]

                    x_center = str((min_x + max_x)/(2*img_width))
                    y_center = str((min_y + max_y)/(2*img_height))
                

                    width_   = str(abs(max_x -min_x)/(img_width))
                    height_  = str(abs(max_y - min_y)/(img_height))
                    
                    class_id += ' ' + ','.join([x_center+' '+y_center+' '+width_+' '+height_])
                    img_txt_file.write(class_id + "\n")
                        
            train_txt_path.write(image_path + "\n")
            
if __name__ == '__main__':
	###训练数据生成
	labelme_train_json=glob.glob('存放训练json文件的路径/*.json')
	train_txt_file = 'train.txt'  #文件路径
	save_train_path = '设置生成的训练标签存放的路径'
	json_to_txt(labelme_train_json,save_train_path,train_txt_file)
	
	###测试数据生成
	labelme_test_json=glob.glob('存放测试json文件的路径/*.json')
	test_txt_file = 'test.txt'  #文件路径
	save_test_path = '设置生成的测试标签存放的路径'
	json_to_txt(labelme_test_json,save_test_path ,test_txt_file )

7. 训练:(linux)

./darknet detector train build/darknet/x64/data/fre.data cfg/yolo-obj_fre.cfg build/darknet/x64/yolov4.conv.137

windows下只需要将上面的./darknet改为darknet.exe

java tensorflow训练自己的数据集 tensorflow yolov4训练自己的数据集_神经网络