【代码阅读】darknet源码阅读(三):option_list.h 和 option_list.c

参考文献依然是放前面:https://blog.csdn.net/caicaiatnbu/category_9096319.html

darknet版本: https://github.com/AlexeyAB/darknet,与原始的版本还是有一点区别的。

进入代码:

1.option_list.h:定义了一个结构体和11个函数

#ifndef OPTION_LIST_H
#define OPTION_LIST_H
#include "darknet.h"
#include "list.h"//解析一中的list.h文件

typedef struct{
    char *key;
    char *val;
    int used;
} kvp;//定义了一个结构体kvp,包含了两个char型指针,一个int型指针

#ifdef __cplusplus
extern "C" {
#endif

list *read_data_cfg(char *filename);
int read_option(char *s, list *options);
void option_insert(list *l, char *key, char *val);
char *option_find(list *l, char *key);
char *option_find_str(list *l, char *key, char *def);
char *option_find_str_quiet(list *l, char *key, char *def);
int option_find_int(list *l, char *key, int def);
int option_find_int_quiet(list *l, char *key, int def);
float option_find_float(list *l, char *key, float def);
float option_find_float_quiet(list *l, char *key, float def);
void option_unused(list *l);

//typedef struct {
//	int classes;
//	char **names;
//} metadata;

//LIB_API metadata get_metadata(char *file);

#ifdef __cplusplus
}
#endif
#endif

2. option_list.c

整体操作就是对.data和.cfg文件做读取。

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "option_list.h"
#include "utils.h"
#include "data.h"//新的头文件,先放一边,有需要去查看

//读文件,主要是.data和.cfg文件
list *read_data_cfg(char *filename)
{
    FILE *file = fopen(filename, "r");//打开文件
    if(file == 0) file_error(filename);
    char *line;
    int nu = 0;
    list *options = make_list();//list.h中的初始化链表
    while((line=fgetl(file)) != 0){//读取文件中的一行数据
        ++nu;
        strip(line);//过滤掉字符数组中的' ' 和 '\t' 以及 '\n' 三种字符
        switch(line[0]){
            case '\0':
            case '#':
            case ';':
                free(line);
                break;
            //以上代码段,是跳过那些没有有效信息的数据行
            //下面是对有效信息做处理
            default:
                //读数据,并且将有效的复制信息放入链表中
                if(!read_option(line, options)){
                    //如果没有有效信息,输出提示
                    fprintf(stderr, "Config file error line %d, could parse: %s\n", nu, line);
                    free(line);
                }
                break;
        }
    }
    fclose(file);
    return options;//返回数据信息
}

/*
metadata 是元数据,关于数据的数据或者叫做用来描述数据的数据或者叫做信息的信息。
比如,有一条学生信息记录,其中包括字段姓名(name)、年龄(age)、性别(male)、班级(class)等,那么name、age、male、class就是元数据。通过它们的描述,一条关于学生信息的数据记录就产生;

这里是读取.data文件,构建数据的相关元数据,比如名称,标签等
*/
metadata get_metadata(char *file)
{
    metadata m = { 0 };
    list *options = read_data_cfg(file);//获得有效的赋值信息
    //data文件中names = data/bicycle.names
    char *name_list = option_find_str(options, "names", 0);//找到key=="name"的对应值
    if (!name_list) name_list = option_find_str(options, "labels", 0);//找到key=="labels"的对应值
    if (!name_list) {
        fprintf(stderr, "No names or labels found\n");
    }//如果找不到信息,就报错提醒
    else {
        m.names = get_labels(name_list);
    }//找到信息就放到元数据中
    //data文件中classes= 21,获得类别数,放入元数据
    m.classes = option_find_int(options, "classes", 2);

    free_list(options);//释放临时空间
    if(name_list) {
        printf("Loaded - names_list: %s, classes = %d \n", name_list, m.classes);
    }//输出读取的信息
    return m;
}

//读取某一字符数组,若满足条件,插入到链表options中
int read_option(char *s, list *options)//read_data_cfg中用到的函数
{
    size_t i;
    size_t len = strlen(s);//字符串长度,做循环
    char *val = 0;
    for(i = 0; i < len; ++i){
        if(s[i] == '='){//遇到等于号,就是data和cfg文件中的赋值语句
            s[i] = '\0';//以等于号为分割线
            val = s+i+1;//val为等于号右边的字符串
            break;
        }
    }
    if(i == len-1) return 0;//如果循环到最后也没有赋值信息,就返回0 
    char *key = s;//key为等于号左边的字符串
    option_insert(options, key, val);//利用函数将内容插入到链表中
    return 1;
}

//字符串的插入操作
void option_insert(list *l, char *key, char *val)
{
    kvp* p = (kvp*)xmalloc(sizeof(kvp));//临时存储空间
    p->key = key;
    p->val = val;
    p->used = 0;//值以结构体kvp的形式存放
    list_insert(l, p);//list.c中的链表插入
}

// 链表遍历操作,打印kvp结构体标志位used 为0的数据,
void option_unused(list *l)
{
    node *n = l->front;
    while(n){
        kvp *p = (kvp *)n->val;
        if(!p->used){
            fprintf(stderr, "Unused field: '%s = %s'\n", p->key, p->val);
        }
        n = n->next;
    }
}

// 查找操作,获取指定key的val,没找到返回null.
char *option_find(list *l, char *key)
{
    node *n = l->front;
    while(n){//循环链表
        // 需要注意结构体node的定义,val是 void类型指针,需要强制转换
        kvp *p = (kvp *)n->val;//取链表值,刚刚read_options中存储的有效赋值信息
        if(strcmp(p->key, key) == 0){//如果存储的key与需要的key相等
            p->used = 1;//将标识符置1
            return p->val;返回查找出来的值
        }
        n = n->next;
    }
    return 0;
}

 
// 查找操作,key为字符数组
char *option_find_str(list *l, char *key, char *def)
{
    char *v = option_find(l, key);//查找key相应的值
    if(v) return v;//如果找到了返回值
    if(def) fprintf(stderr, "%s: Using default '%s'\n", key, def);//没找到输出信息提示
    return def;
}

 查找操作,key为字符数组,并且不给输出提醒
char *option_find_str_quiet(list *l, char *key, char *def)
{
    char *v = option_find(l, key);
    if (v) return v;
    return def;
}

// 查找操作,key为可显示转换int类型字符数组
int option_find_int(list *l, char *key, int def)
{
    char *v = option_find(l, key);
    if(v) return atoi(v);
    fprintf(stderr, "%s: Using default '%d'\n", key, def);
    return def;
}

// 查找操作,key为可显示转换int类型字符数组,并且不给输出提醒
int option_find_int_quiet(list *l, char *key, int def)
{
    char *v = option_find(l, key);
    if(v) return atoi(v);
    return def;
}
// 查找操作,key为可显示转换float类型字符数组,并且不给输出提醒
float option_find_float_quiet(list *l, char *key, float def)
{
    char *v = option_find(l, key);
    if(v) return atof(v);
    return def;
}
// 查找操作,key为可显示转换float类型字符数组
float option_find_float(list *l, char *key, float def)
{
    char *v = option_find(l, key);
    if(v) return atof(v);
    fprintf(stderr, "%s: Using default '%lf'\n", key, def);
    return def;
}

 

OSError: libtorch_cuda.so: cannot open shared object file: No such file or directory是一个错误消息,它表示在运行过程中找不到libtorch_cuda.so共享对象文件。该文件是与CUDA相关的Torch库的一部分。根据引用和引用的信息,这个错误可能是由于缺少libtorch_cuda_cu.so或libtorch_cuda_cpp.so这些文件导致的。 为了解决这个问题,你可以尝试以下步骤: 1. 确保你已经正确安装了CUDA和Torch。这些库需要在系统中正确配置,并且路径也需要正确设置。 2. 检查你的系统中是否存在libtorch_cuda_cu.so和libtorch_cuda_cpp.so这两个文件。如果没有,你可能需要重新安装或更新Torch来获取这些文件。 3. 确保你的系统中存在所需的依赖库。有时候缺少其他依赖库也会导致无法找到共享对象文件的错误。你可以通过安装缺失的依赖库来解决这个问题。 4. 检查你的环境变量设置。确保你的LD_LIBRARY_PATH和LD_PRELOAD等环境变量正确设置,以使系统能够正确找到共享对象文件。 5. 如果你使用的是虚拟环境,请确保你在虚拟环境中正确安装了所有必要的库和依赖项。 如果你遵循上述步骤仍然无法解决问题,你可能需要进一步调查和调试。你可以查看更多关于libtorch_cuda.so缺失的信息,并尝试在相关的社区或论坛上查找帮助。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [libtorch_cuda_cu.so: cannot open shared object file](https://blog.csdn.net/wudi_cn/article/details/126737202)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [OSError: libtorch_cuda_cpp.so: cannot open shared object file: No such file or directory(已解决)](https://blog.csdn.net/weixin_42278880/article/details/125770868)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [darknet-ocr文字检测部分单独实现(darknet_ocr)](https://download.csdn.net/download/weixin_38551187/14855354)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值