YOLO选择出只有某一类的检测框并将框保存在txt中

来源:互联网 发布:淘宝木子禅佛珠怎么样 编辑:程序博客网 时间:2024/04/29 01:57

YOLO是用来检测的。小肚就是来将物体检测出,并用物体进行识别,所以YOLO只是一个预处理过程。安装和命令行运行检测在官网上都有,但是唯一的就是,我想要的只有person这一类,并且我想得到框的坐标,从而能crop下来person。因此小肚又要对一窍不通的C/C++进行改编了


—————–踩坑无数,总结了这篇系统的文章,如果喜欢,欢迎大家浏览—————

一、修改examples/detector.c

//about row 640//void draw_detections(image im, int num, float thresh, box *boxes, float **probs, float **masks, char **names, image **alphabet, int classes);//模仿draw_detections构造的函数,因此把上面注释掉。不同的是,多加了一个char *filename参数,这是因为想将txt的文件名字保存成图片的名字void draw_detections_person(char *filename, image im, int num, float thresh, box *boxes, float **probs, float **masks, char **names, image **alphabet, int classes);draw_detections_person(input, im, l.w*l.h*l.n, thresh, boxes, probs, masks, names, alphabet, l.classes);

二、修改src/image.c

//添加draw_detections_person函数。该函数是在draw_detections的函数基础上修改的void draw_detections_person(char *filename, image im, int num, float thresh, box *boxes, float **probs, float **masks, char **names, image **alphabet, int classes){    int i;    //printf("%s.\n", strcat(filename, ".txt"));    //将filename的文件名提取出来,即去掉.jpg的后缀,加上.txt的后缀    char *output = filename;    int haha = 0;    for (haha = strlen(filename)-1; haha>=0; haha--){        if((filename[haha]!='j')&&(filename[haha]!='p')&&(filename[haha]!='g')&&(filename[haha]!='.')){            break;        }        else{            output[haha] = '\0';        }    }    output = strcat(filename, ".txt");    //新建txt文档,文件名是图片的名字    FILE *fp;        if ( (fp = fopen(output, "w+")) == NULL ){            printf("wrong:\n");        }    for(i = 0; i < num; ++i){        int class = max_index(probs[i], classes);        //如果框的类别不是person,则不运行下面的步骤        if (strcmp(names[class], "person") != 0)         {continue;}        float prob = probs[i][class];        if(prob > thresh){            int width = im.h * .006;            if(0){                width = pow(prob, 1./2.)*10+1;                alphabet = 0;            }            //printf("%d %s: %.0f%%\n", i, names[class], prob*100);            printf("%s: %.0f%%\n", names[class], prob*100);            int offset = class*123457 % classes;            float red = get_color(2,offset,classes);            float green = get_color(1,offset,classes);            float blue = get_color(0,offset,classes);            float rgb[3];            //width = prob*20+2;            rgb[0] = red;            rgb[1] = green;            rgb[2] = blue;            box b = boxes[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;            //printf("box_axis:%f,%f,%f,%f.\n",b.x,b.y,b.w,b.h);            printf("img_box:%d,%d,%d,%d.\n",left,top,right,bot);            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;            //写入txt坐标框              printf("save box:%s \n",output);            fprintf(fp, "%d %d %d %d\n", left, top, right, bot);            draw_box_width(im, left, top, right, bot, width, red, green, blue);            if (alphabet) {                image label = get_label(alphabet, names[class], (im.h*.03)/10);                draw_label(im, top + width, left, label, rgb);                free_image(label);            }            if (masks){                image mask = float_to_image(14, 14, 1, masks[i]);                image resized_mask = resize_image(mask, b.w*im.w, b.h*im.h);                image tmask = threshold_image(resized_mask, .5);                embed_image(tmask, im, left, top);                free_image(mask);                free_image(resized_mask);                free_image(tmask);            }        }    //关闭txt文件    fclose(fp);}

三、脚本文件循环遍历文件夹中的图片

$ vim run.sh#在文件中写入#! /bin/bashsum=0save_path="/home/Yolo_detect_1/"for file in /home/dataset/*.jpgdo    if test -f $file    then        let "sum += 1"        #echo $file if file        name=${file%.*}  #去掉.jpg的后缀 /home/dataset/a        #echo $name        txtname=$name".txt" #加上.txt的后缀 /home/dataset/a.txt        #echo $txtname        onlyname=${name##*/} #图片的名字a.jpg        #echo $onlyname        savename=$save_path$onlyname #图片保存的路径和名字/home/Yolo_detect_1/a.jpg        #echo $savename        ./darknet detect -i 0 cfg/yolo.cfg yolo.weights $file -out $savename  #运行检测代码        mv $txtname $save_path 将/home/dataset/a.txt移动到/home/Yolo_detect_1/a.txt    fiecho "sum=$sum"done$ bash run.sh

大功告成,可以将图片中所有person的图片的box的坐标保存下来了,可以进行识别了。

阅读全文
1 0
原创粉丝点击