1. 程式人生 > >輸出yolo的測試結果,根據座標裁剪原圖並儲存

輸出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; 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++;
    }
}

主要的修改就是這些了。滿足了基本要求。