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。