僅修改darknet.py對視頻做目標檢測

在Darknet框架中,自帶的darknet.py可以使用weight、cfg、coco.data(或者voc.data)、coco.names(voc.names),以及在darknet路徑下make生成的libdarknet.so(如圖1),利用這些文件即可完成圖片中的目標檢測,並標出檢測框。

圖1

 

圖2 darknet.py的主函數

 

 但是對於檢測視頻來說,darknet.py中的detect函數,第3個參數是“data/dog.jpg”,是圖片帶路徑的文件名,而opencv讀取視頻是這樣操作的:

cap = cv2.VideoCapture("test_video/cars.mp4")
frame_count = 0
while True:
    ret, frame = cap.read()

frame就是讀取到的每一幀,而frame的格式是array數組,因此不能直接應用到detect函數中,需要做一個格式轉換。

(在修改之前查閱了很多資料,大多都是在darknet的源碼中修改,比如,修改image.c文件等,然後再make生一個新的libdarknet.so,但是這樣就有點複雜了,而且我修改源碼之後出錯,所以在darknet.py中修改會很方便)

將這段代碼放在detect函數之前

def array_to_image(arr):
    """
    opencv獲得的frame是array格式,需要將其轉換爲image供yolo檢測
    """
    arr = arr.transpose(2, 0, 1)
    c, h, w = arr.shape[0:3]
    arr = np.ascontiguousarray(arr.flat, dtype=np.float32) / 255.0
    data = arr.ctypes.data_as(POINTER(c_float))
    im = IMAGE(w, h, c, data)
    return im

對detect函數做修改(要改的地方已經標出)

def detect(net, meta, image, thresh=.5, hier_thresh=.5, nms=.45):
    # im = load_image(image, 0, 0)  #####原始

    im = array_to_image(image)#改
    rgbgr_image(im)  #改

    num = c_int(0)
    pnum = pointer(num)
    predict_image(net, im)
    dets = get_network_boxes(net, im.w, im.h, thresh, hier_thresh, None, 0, pnum)
    num = pnum[0]
    if (nms): do_nms_obj(dets, num, meta.classes, nms);

    res = []
    for j in range(num):
        for i in range(meta.classes):
            if dets[j].prob[i] > 0:
                b = dets[j].bbox
                res.append((meta.names[i], dets[j].prob[i], (b.x, b.y, b.w, b.h)))

    res = sorted(res, key=lambda x: -x[1])
    free_image(im)
    free_detections(dets, num)

    return res

這樣,就可以利用frame當作image作檢測了

cap = cv2.VideoCapture("test_video/cars.mp4")
frame_count = 0
while True:
    ret, frame = cap.read()
    boxes = detect(net, meta, frame)

得到檢測的框boxes之後,就可以爲所欲爲啦!

沒有放完整代碼,自己動手實踐一下吧,有更高招的歡迎留言!

 

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