运行yolo_v3之路

一 准备-编译darknet

  • 下载工程:
git clone https://github.com/pjreddie/darknet
cd darknet
  • 修改Makefile配置文件:
GPU=1
CUDNN=1       #我是用了gpu和cudnn
...
NVCC=/home/user/cuda_9.0/bin/nvcc      #修改为自己的路径
...
ifeq ($(GPU), 1) 
COMMON+= -DGPU -I/usr/local/cuda-9.0/include/     #修改为自己的路径  
CFLAGS+= -DGPU
LDFLAGS+= -L/usr/local/cuda-9.0/lib64 -lcuda -lcudart -lcublas -lcurand     #修改为自己的路径
endif 
  • 修改完Makefile文件,在darknet文件夹下,终端make命令。
    运行yolo_v3之路_第1张图片

二 测试是否安装成功

  • 下载训练好的权重(预训练权重)
wget https://pjreddie.com/media/files/darknet53.conv.74 

运行yolo_v3之路_第2张图片

  • 测试
./darknet detect cfg/yolov3.cfg yolov3.weights data/dog.jpg

在darknet文件夹下会出现predictions.jpg
三 准备自己的数据

  • 在darknet文件夹下拷贝自己的数据命名为myData
    myData
    …JEPGImage #存放原图像
    …Annotations #存放xml
    …ImageSets
    …-----Main #ImageSets 的子文件,存放训练,验证图像的名字val.txt,运行get_filename_to_txt.py得到
    运行yolo_v3之路_第3张图片
#get_filename_to_txt.py
import os
from os import listdir, getcwd
from os.path import join
if __name__ == '__main__':
    source_folder='/media/ubuntu/storage/LXD/yolov3/darknet/myData/JPEGImages/'
    dest2='/media/ubuntu/storage/LXD/yolov3/darknet/myData/ImageSets/Main/val.txt'
    file_list=os.listdir(source_folder)                    
    val_file=open(dest2,'a')                  
    for file_obj in file_list:                
        file_path=os.path.join(source_folder,file_obj) 
        file_name,file_extend=os.path.splitext(file_obj)
        file_num=int(file_name)                  
        val_file.write(file_name+'\n')  
val_file.close()
  • 将数据集转换为darknet支持的数据格式
    在scripts/voc_label.py,在darknet文件夹下新建my_label.py,修改内容如下:
#sets=[('2012', 'train'), ('2012', 'val'), ('2007', 'train'), ('2007', 'val'), ('2007', 'test')]
sets=[('myData', 'val')]
#classes = ["aeroplane", "bicycle", "bird", "boat", "bottle", "bus", "car", "cat", "chair", "cow", "diningtable", "dog", "horse", "motorbike", "person", "pottedplant", "sheep", "sofa", "train", "tvmonitor"]
classes = ["your_classname", "...",]
...
def convert_annotation(year, image_id):
    in_file = open('myData/Annotations/%s.xml'%( image_id))
    out_file = open('myData/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 year, image_set in sets:
    if not os.path.exists('myData/labels/'):
        os.makedirs('myData/labels/')
    image_ids = open('myData/ImageSets/Main/%s.txt'%(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_/myData/JPEGImages/%s.jpg\n'%(wd, image_id))
        convert_annotation(year, image_id)
    list_file.close()
#os.system("cat 2007_train.txt 2007_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")

运行之后会在./myData目录下生成labels,labels文件夹下有一系列的.txt文件,记录了每个.xml文件的类别,四个相对位置坐标。在darknet文件夹下会生成myData_val.txt文件,存储了每张图片所在的绝对路径。如下所示:

/media/ubuntu/storage/LXD/yolov3/darknet_/myData/JPEGImages/1243.jpg
/media/ubuntu/storage/LXD/yolov3/darknet_/myData/JPEGImages/6197.jpg
/media/ubuntu/storage/LXD/yolov3/darknet_/myData/JPEGImages/1345.jpg
/media/ubuntu/storage/LXD/yolov3/darknet_/myData/JPEGImages/6183.jpg
/media/ubuntu/storage/LXD/yolov3/darknet_/myData/JPEGImages/1758.jpg
/media/ubuntu/storage/LXD/yolov3/darknet_/myData/JPEGImages/5136.jpg
/media/ubuntu/storage/LXD/yolov3/darknet_/myData/JPEGImages/2351.jpg
/media/ubuntu/storage/LXD/yolov3/darknet_/myData/JPEGImages/4157.jpg
/media/ubuntu/storage/LXD/yolov3/darknet_/myData/JPEGImages/4200.jpg

四 修改自己的配置文件

  • 修改darknet/cfg 文件下voc.data和yolov3_voc.cfg文件(复制重命名为my_data.data和my_yolo_v3.cfg)。修改如下:
##修改mydata.data,按照自己的文件地址修改
classes= 2    #类别数
train  = /media/ubuntu/storage/LXD/yolov3/darknet/myData/myData_train.txt     #训练.txt文件
valid = /media/ubuntu/storage/LXD/yolov3/darknet/myData/myData_val.txt        #验证.txt文件
names = /media/ubuntu/storage/LXD/yolov3/darknet/myData/voc.names             #类别名称
backup = /media/ubuntu/storage/LXD/yolov3/darknet/myData/weights              #训练权重放置的文件夹
##修改my_yolo_v3.cfg,按照自己的文件地址修改
[net]
# Testing
#batch=1
#subdivisions=1
#Training
batch=64
subdivisions=16
...
[convolutional]
size=1
stride=1
pad=1
filters=21   #修改filters=anchors_num*(classes_num+5),这里anchors_num=3,classes_num=2
activation=linear
[yolo]
mask = 0,1,2
anchors = 10,13,  16,30,  33,23,  30,61,  62,45,  59,119,  116,90,  156,198,  373,326
classes=2    #修改类别数
num=9
jitter=.3
ignore_thresh = .5
truth_thresh = 1
random=1
...
[convolutional]
size=1
stride=1
pad=1
filters=21   #修改filters=anchors_num*(classes_num+5),这里anchors_num=3,classes_num=2
activation=linear
[yolo]
mask = 0,1,2
anchors = 10,13,  16,30,  33,23,  30,61,  62,45,  59,119,  116,90,  156,198,  373,326
classes=2    #修改类别数
num=9
jitter=.3
ignore_thresh = .5
truth_thresh = 1
random=1
...
[convolutional]
size=1
stride=1
pad=1
filters=21   #修改filters=anchors_num*(classes_num+5),这里anchors_num=3,classes_num=2
activation=linear
[yolo]
mask = 0,1,2
anchors = 10,13,  16,30,  33,23,  30,61,  62,45,  59,119,  116,90,  156,198,  373,326
classes=2    #修改类别数
num=9
jitter=.3
ignore_thresh = .5
truth_thresh = 1
random=1
  • 在myData文件夹下新建voc.names文件(仿照./data/voc.name,放置自己的类别名)。

五 训练及测试

  • 使用刚刚下好的预训练权重训练
./darknet detector train cfg/my_data.data cfg/my_yolov3.cfg darknet53.conv.74 >val_yolov3.log 2>&1 -gpu 1
# >val_yolov3.log 2>&1是保存训练日志,名称为:val_yolov3.log
#-gpu 1指定使用‘1’gpu,多gpu可使用-gpus 1,2,3
  • 批量测试模型(须修改./darknet/detector.c文件)

首先修改my_yolo_v3.cfg,

[net]
# Testing
batch=1
subdivisions=1
#Training
#batch=64
#subdivisions=16
%修改dtector.c,重写test_detector函数
void test_detector(char *datacfg, char *cfgfile, char *weightfile, char *filename, float thresh, float hier_thresh, char *outfile, int fullscreen)
{
    list *options = read_data_cfg(datacfg);
    char *name_list = option_find_str(options, "names", "data/names.list");
    char **names = get_labels(name_list);
    image **alphabet = load_alphabet();
    network *net = load_network(cfgfile, weightfile, 0);
    set_batch_network(net, 1);
    srand(2222222);
    double time;
    char buff[256];
    char *input = buff;
    float nms=.45;
    int i=0;
    while(1){
        if(filename){
            strncpy(input, filename, 256);
            image im = load_image_color(input,0,0);
            image sized = letterbox_image(im, net->w, net->h);
            layer l = net->layers[net->n-1];
            float *X = sized.data;
            time=what_time_is_it_now();
            network_predict(net, X);
            printf("%s: Predicted in %f seconds.\n", input, what_time_is_it_now()-time);
            int nboxes = 0;
            detection *dets = get_network_boxes(net, im.w, im.h, thresh, hier_thresh, 0, 1, &nboxes);
            if (nms) do_nms_sort(dets, nboxes, l.classes, nms);
                draw_detections(im, dets, nboxes, thresh, names, alphabet, l.classes);
                free_detections(dets, nboxes);
            if(outfile)
             {
                save_image(im, outfile);
             }
            else{
                save_image(im, "predictions");
#ifdef OPENCV
                cvNamedWindow("predictions", CV_WINDOW_NORMAL); 
                if(fullscreen){
                cvSetWindowProperty("predictions", CV_WND_PROP_FULLSCREEN, CV_WINDOW_FULLSCREEN);
                }
                show_image(im, "predictions");
                cvWaitKey(0);
                cvDestroyAllWindows();
#endif
            }
            free_image(im);
            free_image(sized);
            if (filename) break;
         } 
        else {
            printf("Enter Image Path: ");
            fflush(stdout);
            input = fgets(input, 256, stdin);
            if(!input) return;
            strtok(input, "\n");
            list *plist = get_paths(input);
            char **paths = (char **)list_to_array(plist);
             printf("Start Testing!\n");
            int m = plist->size;
            if(access("/media/ubuntu/storage/LXD/darknet/myData/result",0)==-1)//修改成自己的路径
            {
              if (mkdir("/media/ubuntu/storage/LXD/darknet/myData/result",0777))//修改成自己的路径
               {
                 printf("creat file bag failed!!!");
               }
            }
            for(i = 0; i < m; ++i){
             char *path = paths[i];
             image im = load_image_color(path,0,0);
             image sized = letterbox_image(im, net->w, net->h);
        layer l = net->layers[net->n-1];
        float *X = sized.data;
        time=what_time_is_it_now();
        network_predict(net, X);
        printf("Try Very Hard:");
        printf("%s: Predicted in %f seconds.\n", path, what_time_is_it_now()-time);
        int nboxes = 0;
        detection *dets = get_network_boxes(net, im.w, im.h, thresh, hier_thresh, 0, 1, &nboxes);
        if (nms) do_nms_sort(dets, nboxes, l.classes, nms);
        draw_detections(im, dets, nboxes, thresh, names, alphabet, l.classes);
        free_detections(dets, nboxes);
        if(outfile){
            save_image(im, outfile);
        }
        else{
             char b[2048];
            sprintf(b,"/media/ubuntu/storage/LXD/darknet/myData/result/%s",GetFilename(path));//修改成自己的路径
            save_image(im, b);
            printf("save %s successfully!\n",GetFilename(path));
#ifdef OPENCV
            cvNamedWindow("predictions", CV_WINDOW_NORMAL); 
            if(fullscreen){
                cvSetWindowProperty("predictions", CV_WND_PROP_FULLSCREEN, CV_WINDOW_FULLSCREEN);
            }
            show_image(im, "predictions");
            cvWaitKey(0);
            cvDestroyAllWindows();
#endif
        }
        free_image(im);
        free_image(sized);
        if (filename) break;
        }
      }
    }
}

在darknet文件夹下运行以下命令,查看0305_yolov3.log文件,最后一行为Enter Image Path:后在终端输入测试图片的.txt文件绝对路径如:(/media/ubuntu/storage/LXD/yolov3/darknet/myData/myData_val.txt),会在/darknet/myData/result文件夹下出现测试图片。如果测试结果名称不对,修改./darknet/data/coco.names为自己的类别。

./darknet detector test  cfg/my_data.data cfg/my_yolov3.cfg myData/weights/my_yolov3_final.weights >0305_yolov3.log 2>&1

PS:本博客参考多位博主的博客,网页,作为自己学习总结,时间有点儿长,不能一一列出参考来源,望见谅!!!

你可能感兴趣的:(python)