python API:http://dlib.net/python/index.html#dlib.correlation_tracker

dlib 可实现单目标跟踪 和 多目标跟踪,实现流程如下

 对应方法如下

correlation_tracker()  创建一个跟踪类;

start_track()       设置图片中的要跟踪物体的框;

update()          实时跟踪下一帧;

get_position()       得到跟踪到的目标的位置

 

demo

import cv2
import dlib
import time

tracker = dlib.correlation_tracker()
win = dlib.image_window()

cap = cv2.VideoCapture(0)
i = 1
while i:
    ret, img = cap.read()
    # 第一帧,指定一个区域
    if i == 1:
        # tracker.start_track(img, dlib.rectangle(74, 67, 112, 153))
        tracker.start_track(img, dlib.centered_rect(dlib.point(int(img.shape[0]/2),
                                                               int(img.shape[1]/2)), 50, 50))
    # 后续帧,自动追踪
    else:
        tracker.update(img)

    win.clear_overlay()
    win.set_image(img)
    win.add_overlay(tracker.get_position())
    i += 1
    # dlib.hit_enter_to_continue()

 

单目标跟踪

import cv2
import dlib

tracker = dlib.correlation_tracker()  # 导入correlation_tracker()类
cap = cv2.VideoCapture(0)  # opencv打开摄像头,参数为设备索引号,笔记本电脑,0表示使用其内置摄像头

selection = None     # 实时跟踪鼠标的跟踪区域
track_window = None  # 要检测的物体所在区域
drag_start = None    # 标记,是否开始拖动鼠标


# 鼠标点击事件回调函数
def onmouse(event, x, y, flags, param):
    global selection, track_window, drag_start  # 定义全局变量
    if event == cv2.EVENT_LBUTTONDOWN:  # 鼠标左键按下
        drag_start = (x, y)  # 鼠标起始位置
        track_window = None
    if drag_start:  # 是否开始拖动鼠标,记录鼠标位置
        xmin = min(x, drag_start[0])
        ymin = min(y, drag_start[1])
        xmax = max(x, drag_start[0])
        ymax = max(y, drag_start[1])
        selection = (xmin, ymin, xmax, ymax)
    if event == cv2.EVENT_LBUTTONUP:  # 鼠标左键松开
        drag_start = None
        track_window = selection
        selection = None


def main():
    # 创建图像与窗口,并将窗口与回调函数绑定
    cv2.namedWindow('image', 1)
    cv2.setMouseCallback('image', onmouse)

    k = 0
    while (1):
        ret, frame = cap.read()  # 从摄像头读入1帧,ret表明成功与否
        img_raw = frame  # 初始帧
        image = img_raw.copy()  # 不改变初始帧,拷贝新的帧

        # 初始化第一帧
        if k == 0:
            # 用鼠标拖拽一个框来指定区域
            while True:
                img_first = image.copy()  # 不改变原来的帧,拷贝一个新的
                if track_window:  # 跟踪目标的窗口画出后,实时标出跟踪目标
                    print('track_window')
                    cv2.rectangle(img_first, (track_window[0], track_window[1]), (track_window[2], track_window[3]),
                                  (0, 0, 255), 1)
                elif selection:  # 跟踪目标的窗口随鼠标拖动实时显示
                    print('selection')
                    cv2.rectangle(img_first, (selection[0], selection[1]), (selection[2], selection[3]), (0, 0, 255), 1)
                cv2.imshow('image', img_first)
                if cv2.waitKey(5) == 27:  # 等待时间为5ms,用户按下按下ESC(ASCII码为27),退出循环
                    break

            tracker.start_track(image,
                                dlib.rectangle(track_window[0], track_window[1], track_window[2], track_window[3]))
        else:
            # 不是第一帧了
            tracker.update(image)  # 更新,实时跟踪
            # time.sleep(3)

        box_predict = tracker.get_position()  # 得到目标的位置
        cv2.rectangle(image, (int(box_predict.left()), int(box_predict.top())),
                      (int(box_predict.right()), int(box_predict.bottom())), (0, 255, 255), 1)
        cv2.imshow('image', image)

        c = cv2.waitKey(5)
        if c == 27: break  # 如果按下ESC,则退出
        k += 1
    cv2.destroyAllWindows()


if __name__ == '__main__':
    main()

 

多目标跟踪

import cv2
import dlib

cap = cv2.VideoCapture(0)

tracker1 = dlib.correlation_tracker()
tracker2 = dlib.correlation_tracker()
tracker3 = dlib.correlation_tracker()

selection = None
track_window = None
drag_start = None

# 鼠标选框(做目标跟踪框)
def onmouse(event, x, y, flags, param):
    global selection, track_window, drag_start
    if event == cv2.EVENT_LBUTTONDOWN:
        drag_start = (x, y)
        track_window = None
    if drag_start:
        xmin = min(x, drag_start[0])
        ymin = min(y, drag_start[1])
        xmax = max(x, drag_start[0])
        ymax = max(y, drag_start[1])
        selection = (xmin, ymin, xmax, ymax)
    if event == cv2.EVENT_LBUTTONUP:
        drag_start = None
        track_window = selection
        selection = None

def main():
    track_window1 = ()
    track_window2 = ()
    track_window3 = ()
    cv2.namedWindow('image', 1)
    cv2.setMouseCallback('image', onmouse)

    k = 0
    while (1):
        ret, img = cap.read()
        image = img.copy()
        if k == 0:
            while True:
                img_first = image.copy()
                if track_window:
                    cv2.rectangle(img_first, (track_window[0], track_window[1]), (track_window[2], track_window[3]), (0, 0, 255), 1)
                elif selection:
                    cv2.rectangle(img_first, (selection[0], selection[1]), (selection[2], selection[3]), (0, 0, 255), 1)

                # 选择多个跟踪目标
                if track_window1:
                    print(1)
                    cv2.rectangle(img_first, (track_window1[0], track_window1[1]), (track_window1[2], track_window1[3]),
                                  (0, 255, 255), 1)
                if track_window2:
                    print(2)
                    cv2.rectangle(img_first, (track_window2[0], track_window2[1]), (track_window2[2], track_window2[3]),
                                  (0, 255, 100), 1)
                if track_window3:
                    print(3)
                    cv2.rectangle(img_first, (track_window3[0], track_window3[1]), (track_window3[2], track_window3[3]),
                                  (200, 0, 200), 1)
                cv2.imshow('image', img_first)
                if cv2.waitKey(10) == 27: # 按4次 ESC
                    print('esc')
                    if not track_window1:
                        print(11)
                        track_window1 = track_window
                    elif not track_window2:
                        print(22)
                        track_window2 = track_window
                    elif not track_window3:
                        print(33)
                        track_window3 = track_window
                    else:
                        break

            tracker1.start_track(image,
                                 dlib.rectangle(track_window1[0], track_window1[1], track_window1[2], track_window1[3]))
            tracker2.start_track(image,
                                 dlib.rectangle(track_window2[0], track_window2[1], track_window2[2], track_window2[3]))
            tracker3.start_track(image,
                                 dlib.rectangle(track_window3[0], track_window3[1], track_window3[2], track_window3[3]))
        else:
            # Else we just attempt to track from the previous frame
            tracker1.update(image)
            tracker2.update(image)
            tracker3.update(image)

            # Get previous box and draw on showing image
        box1_predict = tracker1.get_position()
        box2_predict = tracker2.get_position()
        box3_predict = tracker3.get_position()
        cv2.rectangle(image, (int(box1_predict.left()), int(box1_predict.top())),
                      (int(box1_predict.right()), int(box1_predict.bottom())), (0, 255, 255), 1)
        cv2.rectangle(image, (int(box2_predict.left()), int(box2_predict.top())),
                      (int(box2_predict.right()), int(box2_predict.bottom())), (0, 255, 100), 1)
        cv2.rectangle(image, (int(box3_predict.left()), int(box3_predict.top())),
                      (int(box3_predict.right()), int(box3_predict.bottom())), (200, 0, 200), 1)
        cv2.imshow('image', image)
        # cv2.waitKey(10)
        c = cv2.waitKey(10) & 0xff
        if c == 27: break # ESC
        k += 1
    cv2.destroyAllWindows()


if __name__ == '__main__':
    main()

 

以上代码是 手动 创建 跟踪 区域,也可 通过 目标检测 模型,检测到物体得到 bbox 后,进行跟踪,详见 资料3

 

 

参考资料:

https://blog.csdn.net/wc781708249/article/details/78563543  Dlib实现目标跟踪 汇总

https://blog.csdn.net/weixin_40277254/article/details/82188461  dlib 目标跟踪

https://blog.csdn.net/qq_36758914/article/details/104062419    Opencv之多目标追踪(基于Dlib库)    【加上了 目标检测 模型】