//20190406@New
//清明小长假,除了和同事聚个餐,看场电影,还是宅在所里,不过王婆大虾蛮不错的;风中有雨做的云,整体赶脚可以,只是这名字。。。好在唐奕杰的一句话点了题。不废话了,最近在用yolov3做目标检测,先看下darknet的代码,果然是大神,把C代码写的这么优美~~
//detector.c/
//datacfg默认为coco.data,将data/coco.names加载到names中(存放训练集,测试集图片绝对路径)
void test_detector(char *datacfg, char *cfgfile, char *weightfile, char *filename, float thresh, float hier_thresh, char *outfile, int fullscreen)
{
list *options = read_data_cfg(datacfg);//解析datacfg
char *name_list = option_find_str(options, "names", "data/names.list");//判断options里面是否含有names信息,若没有默认为data/names.list
char **names = get_labels(name_list);//获取类别名称:person\car..
image **alphabet = load_alphabet();//将data/label的图像加载到images数组里result以label形式展示“alphabet是后面在检测结 果图片上能显示文字信息 ”
network *net = load_network(cfgfile, weightfile, 0);//加载cfg和参数构建darknet network“读取网络结构,并分配权重net包含了 整个网络的信息
set_batch_network(net, 1);//nework里layer的"将batch数目强制为1,不同训练过程,这里一次检测一张图片
srand(2222222);
double time;
char buff[256];
char *input = buff;
float nms=.45;//f非极大值抑制参数,不懂的可以google,无论在检测或者跟踪中有很重要的作用
while(1){
if(filename){
strncpy(input, filename, 256);//分析见detector_test.c
} else {
printf("Enter Image Path: ");
fflush(stdout);
input = fgets(input, 256, stdin);
if(!input) return;
strtok(input, "\n");//去掉input中的\n符号
}
image im = load_image_color(input,0,0);//读取图片,函数被封装?
image sized = letterbox_image(im, net->w, net->h);//resize成网格输入大小
//image sized = resize_image(im, net->w, net->h);
//image sized2 = resize_max(im, net->w);
//image sized = crop_image(sized2, -((net->w - sized2.w)/2), -((net->h - sized2.h)/2), net->w, net->h);
//resize_network(net, sized.w, sized.h);
layer l = net->layers[net->n-1];//0407:获取类别信息"@0406获取网络最后一层 在cfg文件中 最后一层包含了classes类别数目
float *X = sized.data;//喂给网络的数据
time=what_time_is_it_now();
network_predict(net, X);//网络前馈, 并没有直接run出最后检测结果,还需要对网络出来的结果进行解析
printf("%s: Predicted in %f seconds.\n", input, what_time_is_it_now()-time);
int nboxes = 0;
detection *dets = get_network_boxes(net, im.w, im.h, thresh, hier_thresh, 0, 1, &nboxes);//完成前面网络结果的解析
//printf("%d\n", nboxes);
//if (nms) do_nms_obj(boxes, probs, l.w*l.h*l.n, l.classes, nms);
if (nms) do_nms_sort(dets, nboxes, l.classes, nms);//非极大抑制
draw_detections(im, dets, nboxes, thresh, names, alphabet, l.classes);//在原始图片上画出检测结果
free_detections(dets, nboxes);
if(outfile){
save_image(im, outfile);
}
else{
save_image(im, "predictions");
#ifdef OPENCV
make_window("predictions", 512, 512, 0);
show_image(im, "predictions", 0);
#endif
}
free_image(im);
free_image(sized);
if (filename) break;
}
}
//network.c
network *load_network(char *cfg, char *weights, int clear)
{
network *net = parse_network_cfg(cfg);//将网络的cfg文件参数化,即解析cfg文件 ,函数被封装?
if(weights && weights[0] != 0){
load_weights(net, weights);//根据cfg构建的network按照layer顺序加载对一个layer参数权重 ,函数被封装?
}
if(clear) (*net->seen) = 0;//*net->seen代表目前网络已经处理的图片数量batch_num=net->batch * net->subdividions
return net;
}
简要分析,未完待续~~