darknet分类预测时加载图片函数:load_data_in_thread

load_data_in_thread()线程中,启动load_thread线程,加载图片,加载图片流程图如下:

1.load_data_in_thread():

test_classifier()函数38行调用load_data_in_thread():

    load_args args = { 0 };
	args.w = 448/*net.w*/;
	args.h = 448 /*net.h*/;
	args.paths = paths;
	args.classes = classes;
	args.n = 64/*net.batch*/;
	args.m = 0;
	args.labels = 0;
	args.d = &buffer;
	args.type = OLD_CLASSIFICATION_DATA;

	pthread_t load_thread = load_data_in_thread(args);

load_data_in_thread()函数:

pthread_t load_data_in_thread(load_args args)
{
    pthread_t thread;
    struct load_args* ptr = (load_args*)calloc(1, sizeof(struct load_args));
    *ptr = args;
    if(pthread_create(&thread, 0, load_thread, ptr)) error("Thread creation failed");
    return thread;
}

load_data_in_thread()函数创建线程load_thread(),load_thread()函数如下:

void *load_thread(void *ptr)
{
    //srand(time(0));
    //printf("Loading data: %d\n", random_gen());
    load_args a = *(struct load_args*)ptr;
    if(a.exposure == 0) a.exposure = 1;
    if(a.saturation == 0) a.saturation = 1;
    if(a.aspect == 0) a.aspect = 1;

    if (a.type == OLD_CLASSIFICATION_DATA){
        *a.d = load_data_old(a.paths, a.n, a.m, a.labels, a.classes, a.w, a.h);
    } else if (a.type == CLASSIFICATION_DATA){

2.load_data_old()

在test_classifier()中type为OLD_CLASSIFICATION_DATA,所以调用load_data_old():

其中参数:

args.w = 448/*net.w*/;
    args.h = 448 /*net.h*/;
    args.paths = paths;
    args.classes = classes;
    args.n = 64/*net.batch*/;
    args.m = 0;
    args.labels = 0;

data load_data_old(char **paths, int n, int m, char **labels, int k, int w, int h)
{
    if(m) paths = get_random_paths(paths, n, m);
    data d = {0};
    d.shallow = 0;
    d.X = load_image_paths(paths, n, w, h);
    d.y = load_labels_paths(paths, n, labels, k, 0);
    if(m) free(paths);
    return d;
}

data定义如下:

// matrix.h
typedef struct matrix {
    int rows, cols;
    float **vals;
} matrix;

// data.h
typedef struct data {
    int w, h;
    matrix X;
    matrix y;
    int shallow;
    int *num_boxes;
    box **boxes;
} data;

1.解读load_data_old(),get_random_paths():图片乱序

char **get_random_paths(char **paths, int n, int m)
{
    char** random_paths = (char**)calloc(n, sizeof(char*));
    int i;
    pthread_mutex_lock(&mutex);
    //printf("n = %d \n", n);
    for(i = 0; i < n; ++i){
        do {
            int index = random_gen() % m;
            random_paths[i] = paths[index];
            //if(i == 0) printf("%s\n", paths[index]);
            //printf("grp: %s\n", paths[index]);
            if (strlen(random_paths[i]) <= 4) printf(" Very small path to the image: %s \n", random_paths[i]);
        } while (strlen(random_paths[i]) == 0);
    }
    pthread_mutex_unlock(&mutex);
    return random_paths;
}

n为网络配置文件中19884.txt中的batch=64,m=0.

该函数的功能是对这64张图片路径乱序。

2.解读load_data_old(),load_image_paths:加载图片

load_image_paths()加载图片

matrix load_image_paths(char **paths, int n, int w, int h)
{
    int i;
    matrix X;
    X.rows = n;
    X.vals = (float**)calloc(X.rows, sizeof(float*));
    X.cols = 0;

    for(i = 0; i < n; ++i){
        image im = load_image_color(paths[i], w, h);
        X.vals[i] = im.data;
        X.cols = im.h*im.w*im.c;
    }
    return X;
}

matrix定义如下:

// matrix.h
typedef struct matrix {
    int rows, cols;
    float **vals;
} matrix;

其中rows:保存图片张数;

cols:保存每张图片的数据总数,宽*高*通道

vals保存图片数据,

load_image_color()代码:

image load_image_color(char *filename, int w, int h)
{
    return load_image(filename, w, h, 3);
}

load_image()代码:

image load_image(char *filename, int w, int h, int c)
{
#ifdef OPENCV
    //image out = load_image_stb(filename, c);
    image out = load_image_cv(filename, c);
#else
    image out = load_image_stb(filename, c);    // without OpenCV
#endif  // OPENCV

    if((h && w) && (h != out.h || w != out.w)){
        image resized = resize_image(out, w, h);
        free_image(out);
        out = resized;
    }
    return out;
}

如果定义了OPENCV采用opencv读取图片,否则,采用std_image读取图片。

结构体image定义如下:

// image.h
typedef struct image {
    int w;
    int h;
    int c;
    float *data;
} image;

关于load_image(),独立写了一篇博客:darknet加载图片函数:load_image()

3.解读load_data_old(),load_labels_paths:

load_labels_paths对应的调用参数:

 *a.d = load_data_old(a.paths, a.n, a.m, a.labels, a.classes, a.w, a.h);

a.paths:图片的路径列表

a.n:对应net.batch的cfg文件配置参数,此处为64

a.m=0      a.labels=0     a.classes =2    

a.w = net.width,cfg文件配置的图片宽度

a.w = net.height,cfg文件配置的图片高度。

data load_data_old(char **paths, int n, int m, char **labels, int k, int w, int h)
{
    if(m) paths = get_random_paths(paths, n, m);
    data d = {0};
    d.shallow = 0;
    d.X = load_image_paths(paths, n, w, h);
    d.y = load_labels_paths(paths, n, labels, k, 0);
    if(m) free(paths);
    return d;
}

此处:n=64,k=2,labels=2

load_labels_paths源代码:

matrix load_labels_paths(char **paths, int n, char **labels, int k, tree *hierarchy)
{
    matrix y = make_matrix(n, k);
    int i;
    for(i = 0; i < n && labels; ++i){
        fill_truth(paths[i], labels, k, y.vals[i]);
        if(hierarchy){
            fill_hierarchy(y.vals[i], k, hierarchy);
        }
    }
    return y;
}

make_matrix():创建matrix对象。

matrix make_matrix(int rows, int cols)
{
    int i;
    matrix m;
    m.rows = rows;
    m.cols = cols;
    m.vals = (float**)calloc(m.rows, sizeof(float*));
    for(i = 0; i < m.rows; ++i){
        m.vals[i] = (float*)calloc(m.cols, sizeof(float));
    }
    return m;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

haimianjie2012

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值