欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

YOLO 批量检测 TUM 数据集保存检测结果

程序员文章站 2022-04-16 20:30:06
...

YOLO 批量检测 TUM 数据集保存检测结果


YOLO 批量检测 TUM 数据集保存检测结果

0. 主要工作:

1. 指令与效果

  • TUM 数据集
    指令:
./darknet detect_tum_batch [path_of_cfg] [path_of_weight] [path_of_dataset] [output_folder] [-thresh thresh]

  例如:

./darknet detect_tum_batch cfg/yolov3.cfg yolov3.weights /home/wu/data/dataset/rgbd_dataset_freiburg1_desk/ /home/wu/data/ -thresh 0.4

  注意:请在 [output_folder] 下创建 yolo_imgsyolo_txts 文件夹来存放绘制了检测框的图片和检测框 txt 信息。

  • 其他数据集:可仿照下面的函数写,后续用到的时候再添加其他数据集命令。

2. 在 darknet.c 中添加指令参数

  • 具体代码:darknet.c
  • 在 main 函数中添加输入的第二个参数 detect_tum_batch
else if (0 == strcmp(argv[1], "detect_tum_batch"))
{
     // 读取阈值,默认为 0.5.
     float thresh = find_float_arg(argc, argv, "-thresh", .5);
     // @PARAM    input_folder   输入数据集路径.
     char *input_folder = (argc > 4) ? argv[4]: 0;
     // @PARAM    output_folder  输出结果存放路径.
     char *output_folder = (argc > 5) ? argv[5]: 0;
     // 开始处理.
     test_detector_tum_batch(   "cfg/coco.data", 
                                argv[2],            /* 网络模型 */
                                argv[3],            /* 权重文件 */
                                input_folder,       /* 输入数据集路径 */
                                output_folder,      /* 输出的结果路径 */
                                thresh, 
                                .5);
}

3. 在 detector.c 中添加读取图片函数

  • 具体代码:detector.c
  • 在 detector.c 中添加上一步中用到的函数
void test_detector_tum_batch(   char *datacfg,      /* cfg/coco.data */
                                char *cfgfile,      /* 网络模型 */
                                char *weightfile,   /* 权重文件 */
                                char *input_folder, /* 输入数据集路径 */
                                char *output_folder,/* 输出结果保存路径 */
                                float thresh,       /* 置信度阈值 */
                                float hier_thresh)
{……}
  • 下面是处理的主要步骤。

3.1 读取数据集路径下的 rgb.txt 文件

  • 由于给出的路径是 ~/dataset/rgbd_dataset_freiburg1_desk/ ,数据集图片存放在 ~/dataset/rgbd_dataset_freiburg1_desk/rgb,图片名存放在 ~/dataset/rgbd_dataset_freiburg1_desk/rgb.txt 中,首先读取 rgb.txt 文件:
// NOTE 读取图像文件列表 rgb.txt. rgb_txt_path = ~/dataset/rgbd_dataset_freiburg1_desk/rgb.txt
char buff[256];
char *rgb_txt_path = buff;
strncpy(rgb_txt_path, input_folder, 256); // input_folder 还是 ~/dataset/rgbd_dataset_freiburg3_long_office_household/
FILE *fp_rgb_txt = fopen(strcat(rgb_txt_path,"rgb.txt"), "r");

3.2 读取图片文件名

  • rgb.txt 存储的内容形式如下,不考虑前三行,后面每行分别为时间戳和文件名:
# color images
# file: 'rgbd_dataset_freiburg1_desk.bag'
# timestamp filename
1305031452.791720 rgb/1305031452.791720.png
1305031452.823674 rgb/1305031452.823674.png
1305031452.859642 rgb/1305031452.859642.png
1305031452.891726 rgb/1305031452.891726.png
1305031452.923715 rgb/1305031452.923715.png
1305031452.959701 rgb/1305031452.959701.png
1305031452.991647 rgb/1305031452.991647.png
1305031453.023650 rgb/1305031453.023650.png
1305031453.059754 rgb/1305031453.059754.png
1305031453.091704 rgb/1305031453.091704.png
  • 读取 19-43 列的图片文件名 img_name,再添加路径得到 input_img_name
    • 另外需注意 txt 文件的前三行无效,需要跳过
while(!feof(fp_rgb_txt))
{
    img_counter++;

    memset(szTest, 0, sizeof(szTest));
    fgets(szTest, sizeof(szTest) - 1, fp_rgb_txt); // 包含了换行符
        
    // 前三行无效不存储,但得遍历读取,所以这个判断在上两行后面.
    if( img_counter < 0)
        continue;

    strncpy(img_name, szTest+18, 25);               // 每行前面 18位为时间戳,后面是文件名.
    sprintf(input_img_name, "%s%s", input_folder, img_name);
}
fclose(fp_rgb_txt);
  • 输出检测的图片结果,输出在 output_folder/yolo_imgs
// NOTE 输出图片.
strncpy(output_file, output_folder, 256);
char frame_index_c3[256];
sprintf(frame_index_c3,"/yolo_imgs/%04d_yolo_%.2f",img_counter,thresh);  // format into 6 digit
char * result_img = strcat(output_file,frame_index_c3);

4. 在 image.c 中添加保存结果函数

  • 具体代码:image.c
  • 此函数仿写的 draw_detections(),具体详见:
void draw_save_detections(  image im, 
                            detection *dets, 
                            int num, 
                            float thresh, 
                            char **names, 
                            image **alphabet, 
                            int classes,
                            FILE *save_txt)
{……}
  • 分别保存 类别、左上角坐标 + 宽 + 长、置信度,也可以修改为类别在 coco.name 中的编号,左上角和右下角坐标
// NOTE 左上角坐标和右下脚坐标
int left  = (b.x-b.w/2.)*im.w;
int top   = (b.y-b.h/2.)*im.h;
int right = (b.x+b.w/2.)*im.w;
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;
            
// NOTE 分别写入类别和坐标
fprintf(save_txt,"%s\t%d\t%d\t%d\t%d\t%.2f\n", names[class], left, top, right-left, bot-top, dets[i].prob[class]);
  • 输出 txt 结果
    book	450	110	189	253	0.50
keyboard	70	294	260	185	0.79
    mouse	255	258	63	38	0.81
    laptop	3	46	238	310	0.41
tvmonitor	224	0	243	234	0.61

2019.03.11
[email protected]