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

因为项目中的需要,本篇博文实现输出(保存)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; i0];
    for(j =0;jif(probs[i][j] > rawmax[i]){
          rawmax[i] = probs[i][j];                                     }
    }
    }
    for( i =0;iif(rawmax[i] > 0)
       printf("rawmax[ %d]:%f\n",i,rawmax[i]);
    }
   float b[num];
   int c[num];

   for(i =0; i1+ i++){
      b[i] = rawmax[i];
   }
   int x;
   for(i =0;ifor(x = i,j = x+1; jif(b[x]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++;
    }
}

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

你可能感兴趣的:(深度学习,教程,目标检测,box,yolo,测试结果)