darknet运用模型预测分类时如何读取内存中的图片进行预测

更多darknet预测分类动态库文章参考:自己动手实现darknet预测分类动态库

1.darknet分类预测流程说明

Darknet分类预测时需要输入cmd指令:

darknet classifier test metal.data 19448.txt backup/19448_last.weights

该指令在darknet源代码主要调用test_classifier()完成。下面是test_classifier()中现有涉及需要修改的流程:

1.1读取meta.data中test对应的图片路径列表paths

1.2 load_data_in_thread()中调用pthread库创建线程load_thread()

1.3 load_thread()线程中调用load_image()加载图片,每个线程每次加载net.batch张图片,没有加载完的图片重新创建线程加载。

1.4 load_image()主要工作包括:a).使用stb_image库读取文件流的形式获得image(stb_image库的格式)格式图片;b).将图片转换成darknet支持格式martrix,大小转换为深度学习模型文件(19448.cfg)配置的图片大小。

2.如何修改流程

查看代码时发现stb_image库中同时有函数stbi_load_image_from_memory和stbi_load_image_from_file(),现阶段(见1.4)load_image()中使用的是stbi_load_image_form_file(),可以将stbi_load_image_from_file改成stbi_load_image_from_memory()。

对比两个函数的参数,除了第一个参数不同外,其他三个参数都相同:

Stbi_load_image_from_file()第一个参数为文件路径

Stbi_load_image_from_memory()第一个参数为unsigned char,

也就是说可以直接传入内存地址给stbi_load_image_from_memory()

 

所以需要做的修改包括:从test_classifier()开始修改,把原来传入文件的地方修改为:传入内存首地址、图片大小、图片宽高。

darknet预测分类时,直接从内存中读取图片。

3.darknet分类预测详细流程

运行darknet模型预测一组图片指令如下:

darknet classifier test metal.data 19448.txt backup/19448_last.weights

darknet.c文件里面main()函数,是整个darknet程序的入口函数,该函数第493行和494行如下:

  } else if (0 == strcmp(argv[1], "classifier")){
        run_classifier(argc, argv);

如果第一个参数为“classifier”时,调用run_classifier函数,其中参数argv就是我们输入的指令。

run_classifier()函数:

  char *data = argv[3];
  char *cfg = argv[4];
  char *weights = (argc > 5) ? argv[5] : 0;    
  char *layer_s = (argc > 7) ? argv[7]: 0;
  int layer = layer_s ? atoi(layer_s) : -1;
else if(0==strcmp(argv[2], "test")) test_classifier(data, cfg, weights, layer);

如果第二个参数为‘test’时,调用test_classifier()。其中参数,data=meta.data,cfg=19448.txt,weights=backup/19448_last.weights,layer=-1

test_classifier()源代码:

void test_classifier(char *datacfg, char *cfgfile, char *weightfile, int target_layer)
{
    int curr = 0;
    network net = parse_network_cfg(cfgfile);
    if(weightfile){
        load_weights(&net, weightfile);
    }
    srand(time(0));
    fuse_conv_batchnorm(net);
    calculate_binary_weights(net);

    list *options = read_data_cfg(datacfg);

    char *test_list = option_find_str(options, "test", "data/test.list");
    int classes = option_find_int(options, "classes", 2);

    list *plist = get_paths(test_list);

    char **paths = (char **)list_to_array(plist);
    int m = plist->size;
    free_list(plist);

    clock_t time;

    data val, buffer;

    load_args args = {0};
    args.w = net.w;
    args.h = net.h;
    args.paths = paths;
    args.classes = classes;
    args.n = net.batch;
    args.m = 0;
    args.labels = 0;
    args.d = &buffer;
    args.type = OLD_CLASSIFICATION_DATA;

    pthread_t load_thread = load_data_in_thread(args);
    for(curr = net.batch; curr < m; curr += net.batch){
        time=clock();

        pthread_join(load_thread, 0);
        val = buffer;

        if(curr < m){
            args.paths = paths + curr;
            if (curr + net.batch > m) args.n = m - curr;
            load_thread = load_data_in_thread(args);
        }
        fprintf(stderr, "Loaded: %d images in %lf seconds\n", val.X.rows, sec(clock()-time));

        time=clock();
        matrix pred = network_predict_data(net, val);

        int i, j;
        if (target_layer >= 0){
            //layer l = net.layers[target_layer];
        }

        for(i = 0; i < pred.rows; ++i){
            printf("%s", paths[curr-net.batch+i]);
            for(j = 0; j < pred.cols; ++j){
                printf("\t%g", pred.vals[i][j]);
            }
            printf("\n");
        }

        free_matrix(pred);

        fprintf(stderr, "%lf seconds, %d images, %d total\n", sec(clock()-time), val.X.rows, curr);
        free_data(val);
    }
}

想要darknet预测分类时,直接从内存中读取图片,那么就需要改造test_classifier代码。

darknet分类预测加载图片函数:load_data_in_thread

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

haimianjie2012

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值