调用darknet python接口需使用darknet/python/darknet.py,而其中核心为detect()函数,该参数主要参数为:
def detect(net, meta, image, thresh=.5, hier_thresh=.5, nms=.45)
而detect()函数中的核心为dets = get_network_boxes(net, im.w, im.h, thresh, hier_thresh, 0, 1, &nboxes),那么get_network_boxes()函数在哪里呢?位于darknet/src下的network.c,那么network.c中的c#函数如何传到python里的呢?通过darknet/example/darknet.c编译生成的libdarknet.so包被加载到python中最后被darknet.py调用。那么get_network_boxes()的主要内容如下:
detection *get_network_boxes(network *net, int w, int h, float thresh, float hier, int *map, int relative, int *num)
{
detection *dets = make_network_boxes(net, thresh, num);
fill_network_boxes(net, w, h, thresh, hier, map, relative, dets);
return dets;
}
可知,首先通过make_network_boxes()生成检测(dets)信息,然后以fill_network_boxes()过滤boxes。
make_networks_boxes()函数如下:
detection *make_network_boxes(network *net, float thresh, int *num)
{
layer l = net->layers[net->n - 1];
int i;
int nboxes = num_detections(net, thresh);
if(num) *num = nboxes;
detection *dets = calloc(nboxes, sizeof(detection));
for(i = 0; i < nboxes; ++i){
dets[i].prob = calloc(l.classes, sizeof(float));
if(l.coords > 4){
dets[i].mask = calloc(l.coords-4, sizeof(float));
}
}
return dets;
}
核心得到框nboxes为函数num_detections(),然后由calloc()函数为其分配内存空间,具体为:
int num_detections(network *net, float thresh)
{
int i;
int s = 0;
for(i = 0; i < net->n; ++i){
layer l = net->layers[i];
if(l.type == YOLO){
s += yolo_num_detections(l, thresh);
}
if(l.type == DETECTION || l.type == REGION){
s += l.w*l.h*l.n;
}
}
return s;
}
通过YOLO或DETECTION或REGION分别对应yolov3、v1和v2的检测层得到boxes。
往回看get_network_boxes()函数中的过滤函数fill_networ_boxes(),具体code为:
void fill_network_boxes(network *net, int w, int h, float thresh, float hier, int *map, int relative, detection *dets)
{
int j;
for(j = 0; j < net->n; ++j){
layer l = net->layers[j];
if(l.type == YOLO){
int count = get_yolo_detections(l, w, h, net->w, net->h, thresh, map, relative, dets);
dets += count;
}
if(l.type == REGION){
get_region_detections(l, w, h, net->w, net->h, thresh, map, hier, relative, dets);
dets += l.w*l.h*l.n;
}
if(l.type == DETECTION){
get_detection_detections(l, w, h, thresh, dets);
dets += l.w*l.h*l.n;
}
}
其中通过get_yolo_detections或get_region_detections或get_detection_detections三个函数分别对应yolov3、v2、v1三个版本的检测层,三者的实现分别位于yolo_layer.c、region_layer.c和detection_layer.c中实现。其中的hier_thresh最终传递到region_layer.c中实现,如需了解hier_thresh的具体作用,可参考博主博文:https://blog.csdn.net/xunan003/article/details/96150121