Using Yolov3 for batch testing and custom saving under Windows

Keywords: Windows network

 

1. Open the project file darknet.sln of Darknet with VS

 

2. Find detector.c for modification

1) add header file

#include <sys/stat.h>
#include<stdio.h>
#include<time.h>
#include<sys/types.h>

2) add GetFilename function

char *GetFilename(char *p)
{
    static char name[20] = { "" };
    char *q = strrchr(p, '/') + 1;
    strncpy(name, q, 6);//Note the following 6. If the name character (excluding suffix) of your test set's picture is of other length, please change it to the length you need (the official default length is 6)
    return name;
}

3) find the test detector function and modify it as follows (about line 1200 +)

Create a new test pics folder in.. \ Darknet master \ build \ Darknet \ x64 directory to store the test results

void test_detector(char *datacfg, char *cfgfile, char *weightfile, char *filename, float thresh,
    float hier_thresh, int dont_show, int ext_output, int save_labels, char *outfile)
{
    list *options = read_data_cfg(datacfg);
    char *name_list = option_find_str(options, "names", "data/names.list");
    int names_size = 0;
    char **names = get_labels_custom(name_list, &names_size); //get_labels(name_list);

    image **alphabet = load_alphabet();
    network net = parse_network_cfg_custom(cfgfile, 1, 1); // set batch=1
    if (weightfile) {
        load_weights(&net, weightfile);
    }
    fuse_conv_batchnorm(net);
    calculate_binary_weights(net);
    if (net.layers[net.n - 1].classes != names_size) {
        printf(" Error: in the file %s number of names %d that isn't equal to classes=%d in the file %s \n",
            name_list, names_size, net.layers[net.n - 1].classes, cfgfile);
        if (net.layers[net.n - 1].classes > names_size) getchar();
    }
    srand(2222222);

    double time;
    char buff[256];
    char *input = buff;
    int j, i;
    float nms = .45;    // 0.4F
    if (filename) {
        strncpy(input, filename, 256);
        list *plist = get_paths(input);
        char **paths = (char **)list_to_array(plist);
        printf("Start Testing!\n");
        int m = plist->size;

        for (i = 0; i < m; ++i) {
            char *path = paths[i];
            image im = load_image(path, 0, 0, net.c);
            int letterbox = 0;
            image sized = resize_image(im, net.w, net.h);
            //image sized = letterbox_image(im, net.w, net.h); letterbox = 1;
            layer l = net.layers[net.n - 1];
            float *X = sized.data;
            double time = get_time_point();
            network_predict(net, X);
            printf("%s: Predicted in %lf milli-seconds.\n", input, ((double)get_time_point() - time) / 1000);
            printf("Try Very Hard:");
            printf("%s: Predicted in %lf milli-seconds.\n", path, ((double)get_time_point() - time) / 1000);
            int nboxes = 0;
            detection *dets = get_network_boxes(&net, im.w, im.h, thresh, hier_thresh, 0, 1, &nboxes, letterbox);
            if (nms) do_nms_sort(dets, nboxes, l.classes, nms);
            draw_detections_v3(im, dets, nboxes, thresh, names, alphabet, l.classes, ext_output);

            char b[2048];
            sprintf(b, "test_pics/%s", GetFilename(path)); //The location where the picture is saved, or the absolute path available is "E: \ \ 2-ship \ \ Darknet master \ \ 2types \ \ 504 \ \ build \ \ Darknet \ \ x64 \ \ test \ \ pics"
            save_image(im, b);
            printf("save %s successfully!\n", b);

            if (save_labels)
            {
                char labelpath[4096];
                replace_image_to_label(input, labelpath);
                FILE* fw = fopen(labelpath, "wb");
                int i;
                for (i = 0; i < nboxes; ++i) {
                    char buff[1024];
                    int class_id = -1;
                    float prob = 0;
                    for (j = 0; j < l.classes; ++j) {
                        if (dets[i].prob[j] > thresh && dets[i].prob[j] > prob) {
                            prob = dets[i].prob[j];
                            class_id = j;
                        }
                    }
                    if (class_id >= 0) {
                        sprintf(buff, "%d %2.4f %2.4f %2.4f %2.4f\n", class_id, dets[i].bbox.x, dets[i].bbox.y, dets[i].bbox.w, dets[i].bbox.h);
                        fwrite(buff, sizeof(char), strlen(buff), fw);
                    }
                }
                fclose(fw);
            }

            free_detections(dets, nboxes);
            free_image(im);
            free_image(sized);
            //free(boxes);
            //free_ptrs((void **)probs, l.w*l.h*l.n);
        }
    }

    printf("All Done!\n");
    system("pause");
    exit(0);

    free_ptrs(names, net.layers[net.n - 1].classes);
    free_list_contents_kvp(options);
    free_list(options);

    const int nsize = 8;
    for (j = 0; j < nsize; ++j) {
        for (i = 32; i < 127; ++i) {
            free_image(alphabet[j][i]);
        }
        free(alphabet[j]);
    }

    free(alphabet);
    free_network(net);
    printf("All Done!\n");
    system("pause");

}

4) right click darknet to regenerate

 

3. Test,

Enter the following command in cmd:

darknet.exe detector test data\voc.data yolov3-voc.cfg weights_result\yolov3-voc_10000.weights E:\xxxxxx\build\darknet\VOCdevkit\2007_test.txt

Where "E: \ xxxxx \ build \ Darknet \ vocdevkit \ 2007" is the path of the test file, and 2007 "test.txt" is the absolute path of the test image, as follows:

 

4, result

 

5. Reference:

yolov3+darknet batch image processing in Windows Environment

Batch image detection and batch output of YOLOv3 (under windows)

YOLOv3 batch test pictures and save them in the customized folder 

 

Posted by Micah D on Tue, 05 Nov 2019 11:59:54 -0800