zoukankan      html  css  js  c++  java
  • 目标检测数据库 PASCAL 格式的 Ground Truth 的解析函数

    最近在做一个目标检测算法,训练时用到了 bootstrap 策略,于是我将 PASCAL 的 Ground Truth 格式的读取函数从 Matlab 改写为 C++。PASCAL 的标注格式为:

    # PASCAL Annotation Version 1.00
    Image filename : "对应图片路径"
    Image size (X x Y x C) : 宽 x 高 x 3
    Database : "数据库名称"
    Objects with ground truth : 1 { "PASperson" }
    # Note that there might be other objects in the image
    # for which ground truth data has not been provided.
    # Top left pixel co-ordinates : (0, 0)
    # Details for object 1 ("PASperson")
    # Center point -- not available in other PASCAL databases -- refers
    # to person head center
    Original label for object 1 "PASperson" : "UprightPerson"
    Center point on object 1 "PASperson" (X, Y) : (257, 187)
    Bounding box for object 1 "PASperson" (Xmin, Ymin) - (Xmax, Ymax) : (195, 154) - (297, 468)

     我写的函数如下:

    #include "stdio.h"
    #include "string.h"
    #include "stdlib.h"
    
    // object bounding rect
    struct GtRect {
        int x_min; int y_min;
        int x_max; int y_max; 
    };
    
    // ground truth of one image
    struct GtRecord {
        char* image_name;
        GtRect* objs;
        int obj_num; int height;
        int width; int channels;
    };
    
    // return true if c is in char set s
    int _is_chars(char c, const char* s, int n)
    {
        for (int i = 0; i != n; ++i) {
            if (s[i] == c) {
                return 1;
            }
        }
        return 0;
    }
    
    void _trim_l(char* inout, const char* s)
    {
        int len = strlen(inout);
        int s_len = strlen(s);
        int i = 0;
        for (;i != len; ++i) {
            if (!_is_chars(inout[i], s, s_len)) {
                break;
            }
        }
        int d = i;
        int new_len = len - d;
        for (i = 0; i != new_len; ++i) {
            inout[i] = inout[i + d];
        }
        inout[new_len] = '';
    }
    
    void _trim_r(char* inout, const char* s)
    {
        int len = strlen(inout);
        int s_len = strlen(s);
        int i = len - 1;
        for (;i != -1; --i) {
            if (!_is_chars(inout[i], s, s_len)) {
                break;
            }
        }
        inout[i + 1] = '';
    }
    
    inline void _trim_lr(char* inout, const char* s)
    {
        _trim_l(inout, s);
        _trim_r(inout, s);
    }
    
    // read ground truth (pascal format)
    //************************************
    // Name:  gt_pascal_read
    // Returns:   GtRecord
    // const char * path    :    groundtruth file path
    //************************************
    GtRecord gt_pascal_read(const char* path)
    {
        GtRecord ret = {0, 0, 0, 0, 0, 0};
        FILE* f;
        fopen_s(&f, path, "r");
        int obj_num = 0;
        int len = 0;
        GtRect rct;
        while (fgets(BUF1, 5000, f) != 0) {
            int match_type = _match_attr(BUF1);
            switch (match_type) {
            case 0:
                // read image filename
                sscanf_s(BUF1, _GT_ATTR[0], BUF2, 500);
                _trim_lr(BUF2, "
    " ");
                len = strlen(BUF2);
                ret.image_name = (char*)malloc(len + 1);
                memcpy(ret.image_name, BUF2, len + 1);
                break;
            case 1:
                // read image size, channel
                sscanf_s(BUF1, _GT_ATTR[1], &ret.width, &ret.height,
                    &ret.channels);
                break;
            case 2:
                // ignore database name
                break;
            case 3:
                sscanf_s(BUF1, _GT_ATTR[3], &rct.x_min,
                    &rct.y_min, &rct.x_max, &rct.y_max);
                OBJ_BUF[obj_num++] = rct;
                break;
            case 4:
                // ignore polygon
            case 5:
                // ignore pixel map
            case 6:    
                // ignore label    
                break;
            }
        }
        fclose(f);
        ret.obj_num = obj_num;
        if (obj_num > 0) {
            ret.objs = (GtRect*)malloc(sizeof(GtRect) * obj_num);
            memcpy(ret.objs, OBJ_BUF, obj_num * sizeof(GtRect));
        }
        return ret;
    }
    
    // release pascal ground truth
    //************************************
    // Name:  gt_pascal_release
    // Returns:   void
    // GtRecord * r
    //************************************
    void gt_pascal_release(GtRecord* r)
    {
        free(r->image_name);
        free(r->objs);
        r->image_name = 0;
        r->objs = 0;
        r->width = 0;
        r->height = 0;
        r->channels = 0;
        r->obj_num = 0;
    }

    gt_pascal_read 函数忽略了 groundtruth 文件中的一些属性,例如数据库名称等,如果要加回,可以在函数的几个空的 case 中添加即可。PASCAL 官方提供了几个有用的 Matlab 脚本用于读取和生成这样的 groundtruth 文件,在算法开发的过程中要多利用这样的工具。

  • 相关阅读:
    App提交Appstore审核流程【转】
    程序员必须软件
    Linux的cron和crontab
    Git操作基本命令
    Python编码问题整理【转】
    Python读取ini配置文件
    RF+Jenkins构建持续集成
    RF接口测试本地环境部署
    Python建立SSH连接与使用方法
    永久修改python默认的字符编码为utf-8
  • 原文地址:https://www.cnblogs.com/heleifz/p/3398356.html
Copyright © 2011-2022 走看看