输出yolo的测试结果,根据坐标裁剪原图并保存

来源:互联网 发布:nginx lua 开发环境 编辑:程序博客网 时间:2024/05/21 12:46

因为项目中的需要,本篇博文实现输出(保存)yolo的测试结果,并测试结果的坐标位置切割原图,并不需要知道每个框的类别,保存了top9。
主要对src/image.c文件中的draw_detections函数做了修改。

//添加了 char *filename ,为了得到当前的图片名。void draw_detections(image im, int num, float thresh, box *boxes, float **probs, float **masks, char **names, image **alphabet, int classes, char *filename){    printf("num %d\n", num);      float rawmax[num];    int i,j;    int params[3];    char savePath[100] = "";    //为了得到top19的框,将每个框按照最大概率值进行了排序,取了top19. b,c矩阵都是为了得到top9对应的原框的下标,好得到坐标点。    for(i =0; i<num; i++){    rawmax[i] = probs[i][0];    for(j =0;j<classes;j++){         if(probs[i][j] > rawmax[i]){          rawmax[i] = probs[i][j];                                     }    }    }    for( i =0;i<num;i++){      if(rawmax[i] > 0)       printf("rawmax[ %d]:%f\n",i,rawmax[i]);    }   float b[num];   int c[num];   for(i =0; i<num; c[i]= 1+ i++){      b[i] = rawmax[i];   }   int x;   for(i =0;i<num;i++){      for(x = i,j = x+1; j<num;j++)       if(b[x]<b[j]) x = j;       if(x!=j){        j= b[i];        b[i] = b[x];        b[x] = j;        j = c[i];        c[i] = c[x];        c[x] = j;     }      }  //输出top9的坐标,后面的代码注释掉了,因为我只需要根据坐标切割出子图并保存。    for( i =0;i<9;i++){       box b = boxes[c[i]];       int left  = (b.x-b.w/2.)*im.w;       int right = (b.x+b.w/2.)*im.w;       int top   = (b.y-b.h/2.)*im.h;       int bot   = (b.y+b.h/2.)*im.h;       if(left < 0) left = 0;       if(right > im.w-1) right = im.w-1;       if(top < 0) top = 0;       if(bot > im.h-1) bot = im.h-1;       printf("c[%d]=%d %d %d %d %d\n", i,c[i],left,right,top,bot);       //接下来的操作需要导入opencv,在文件头应该加入       #ifdef OPENCV       #include "opencv2/highgui/highgui_c.h"       #include "opencv2/imgproc/imgproc_c.h"       #endif       CvRect box = cvRect(left, top, right-left, bot-top);           IplImage* src = cvLoadImage(filename, -1);       CvSize size = cvSize(right-left, bot-top);       IplImage* roi = cvCreateImage(size, src->depth,src->nChannels);       cvSetImageROI(src, box);       cvCopy(src,roi,NULL);        char name1[4] = "dog";       char name2[5] = ".jpg";       char newname[100];       sprintf(newname,"%s_%d%s",name1,i,name2 );  //保存的图片名dog_i.jpg       cvSaveImage(newname,roi,0);       cvReleaseImage(&src);       cvReleaseImage(&roi);    }

因为这里讲行数参数加入了 char * filename,所以应该在对应的头文件中修改函数定义。
include/darknet.h ,修改函数定义为:

void draw_detections(image im, int num, float thresh, box *boxes, float **probs, float **masks, char **names, image **alphabet, int classes, char* filename);

examples/detector.c 的函数调用改为:

draw_detections(im, l.w*l.h*l.n, thresh, boxes, probs, masks, names, alphabet, l.classes, filename);

还有一些别的地方,因为加入了这个参数需要改动,根据make的提示,修改即可。

如果需要检测批量图片,只需要修改examples/detector.c 中的test_detector()函数

//加入filelist.读取test.txt,test.txt中每行保存一个图片路径char **filelist = get_labels("../test.txt");

将:

while(1){    if(filename){……    ……    }

改为:

int index = 0;    while(filelist[index] != NULL){            filename = filelist[index];            printf("filename: %s\n", filename);            if(filename){ ……            ……            index++;          }

去掉:

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        }以及   if (filename) break;

修改后的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;    int j;    float nms=.3;    char **filelist = get_labels("/home/wc/YOLO/darknet/data/test.txt");    int index = 0;    while(filelist[index] != NULL){            filename = filelist[index];            printf("filename: %s\n", filename);   // while(1){        if(filename){            strncpy(input, filename, 256);        } else {            printf("Enter Image Path: ");            fflush(stdout);            input = fgets(input, 256, stdin);            if(!input) return;            strtok(input, "\n");        }        image im = load_image_color(input,0,0);        image sized = letterbox_image(im, net->w, net->h);        //image sized = resize_image(im, net->w, net->h);        //image sized2 = resize_max(im, net->w);        //image sized = crop_image(sized2, -((net->w - sized2.w)/2), -((net->h - sized2.h)/2), net->w, net->h);        //resize_network(net, sized.w, sized.h);        layer l = net->layers[net->n-1];        box *boxes = calloc(l.w*l.h*l.n, sizeof(box));        float **probs = calloc(l.w*l.h*l.n, sizeof(float *));        for(j = 0; j < l.w*l.h*l.n; ++j) probs[j] = calloc(l.classes + 1, sizeof(float *));        float **masks = 0;        if (l.coords > 4){            masks = calloc(l.w*l.h*l.n, sizeof(float*));            for(j = 0; j < l.w*l.h*l.n; ++j) masks[j] = calloc(l.coords-4, sizeof(float *));        }        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);        //printf(boxes);        get_region_boxes(l, im.w, im.h, net->w, net->h, thresh, probs, boxes, masks, 0, 0, hier_thresh, 1);        if (nms) do_nms_sort(boxes, probs, l.w*l.h*l.n, l.classes, nms);        //else if (nms) do_nms_sort(boxes, probs, l.w*l.h*l.n, l.classes, nms);        //printf("start draw_detection");        draw_detections(im, l.w*l.h*l.n, thresh, boxes, probs, masks, names, alphabet, l.classes, filename);       /*        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);        free(boxes);        free_ptrs((void **)probs, l.w*l.h*l.n);        // if (filename) break;        index++;    }}

主要的修改就是这些了。满足了基本要求。