目標檢測數據庫 PASCAL 格式的 Ground Truth 的解析函數

最近在作一個目標檢測算法,訓練時用到了 bootstrap 策略,因而我將 PASCAL 的 Ground Truth 格式的讀取函數從 Matlab 改寫爲 C++。PASCAL 的標註格式爲:html

# 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] = '\0';
}

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] = '\0';
}

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, "\n\" ");
            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 文件,在算法開發的過程當中要多利用這樣的工具。數據庫

相關文章
相關標籤/搜索