YOLOv3測試時python接口分析

調用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

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章