YOLOv3提供了单张图片处理接口,但并未提供图像的批处理接口,通过修改detector.c 实现从文本读入image list并将结果保存到输出txt文件,代码如下:
在detector.c中添加如下函数:
void batch_process(char *datacfg, char *cfgfile, char *weightfile, char *read_file, float thresh, float hier_thresh, char *save_file) { 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; float nms=.45; int max_len=256; char buf[max_len]; FILE *writer; FILE *fp; int len; if((writer=fopen(save_file,"w"))==NULL){ printf("%s","conld not open output_file\n"); exit(1); } if((fp=fopen(read_file,"r"))==NULL){ printf("%s","could not open image_list file\n"); exit(1); } while(fgets(buf,max_len,fp)!=NULL){ len=strlen(buf); buf[len-1]='\0'; fprintf(writer, "%s\n",buf); char *image_name=buf; image im = load_image_color(image_name,0,0); image sized = letterbox_image(im, net->w, net->h); layer l = net->layers[net->n-1]; float *X = sized.data; network_predict(net, X); printf("Process:%s\n",image_name); 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); int i,j; //printf("%d\n",nboxes); //printf("classes:%d\n",l.classes); if(nboxes!=0){ for(i=0;i<nboxes;i++){ float xmin = (dets[i].bbox.x - dets[i].bbox.w/2.)*im.w; float xmax = (dets[i].bbox.x + dets[i].bbox.w/2.)*im.w; float ymin = (dets[i].bbox.y - dets[i].bbox.h/2.)*im.h; float ymax = (dets[i].bbox.y + dets[i].bbox.h/2.)*im.h; for (j=0;j<l.classes;j++){ if (dets[i].prob[j]){ fprintf(writer, "%f %f %f %f %f %d\n",xmin,ymin,xmax,ymax,dets[i].prob[j],j); } } } } free_detections(dets, nboxes); free(im); free(sized); } }
并修改主函数部分如下:只修改对应的部分即可
if(0==strcmp(argv[2], "test")) test_detector(datacfg, cfg, weights, filename, thresh, hier_thresh, outfile, fullscreen); else if(0==strcmp(argv[2],"batch")){ if(argv<=7){ printf("%s\n","image_list and output_file is required!"); exit(0); } char *image_list= argv[6]; char *save_file= argv[7]; batch_process(datacfg, cfg, weights, image_list, thresh, hier_thresh, save_file); } else if(0==strcmp(argv[2], "train")) train_detector(datacfg, cfg, weights, gpus, ngpus, clear); else if(0==strcmp(argv[2], "valid")) validate_detector(datacfg, cfg, weights, outfile); else if(0==strcmp(argv[2], "valid2")) validate_detector_flip(datacfg, cfg, weights, outfile); else if(0==strcmp(argv[2], "recall")) validate_detector_recall(cfg, weights); else if(0==strcmp(argv[2], "demo")) { list *options = read_data_cfg(datacfg); int classes = option_find_int(options, "classes", 20); char *name_list = option_find_str(options, "names", "data/names.list"); char **names = get_labels(name_list); demo(cfg, weights, thresh, cam_index, filename, names, classes, frame_skip, prefix, avg, hier_thresh, width, height, fps, fullscreen); }
调用命令行接口如下:
./darknet detector batch cfg/coco.data cfg/yolov3.cfg yolov3.weights input_image_list.txt output_results.txt其中input_image_list.txt含有待检测图像的绝对地址,output_results.txt中存储输出结果。类似SSD。