OpenCV3 KCF跟踪算法的应用(用鼠标框选视频中待跟踪区域)

废话不说,看代码注释即可。

需要:OpenCV 3+contrib、Python 3

# 引入所需模块
import cv2
import sys

# 鼠标框选区域,用于显示鼠标轨迹
selection = None
# 框选开始
drag_start = None
# 框选完成区域即跟踪目标
track_window = None
# 跟踪开始标志
track_start = False
# 创建KCF跟踪器
tracker = cv2.TrackerKCF_create()


# 鼠标响应函数
def onmouse(event, x, y, flags, param):
    global selection, drag_start, track_window, track_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
        selection = None
        track_window = (xmin, ymin, xmax - xmin, ymax - ymin)
        if track_window and track_window[2] > 0 and track_window[3] > 0:
            track_start = True
            # 跟踪器以鼠标左键弹起时所在帧和框选区域为参数初始化
            tracker.init(frame, track_window)


# 读取视频/摄像头
video = cv2.VideoCapture(0)
# video = cv2.VideoCapture("test2.mp4")
# 命名窗口,第二个参数表示窗口可缩放
cv2.namedWindow('KCFTracker', cv2.WINDOW_NORMAL)
# 为窗口绑定鼠标响应函数onmouse
cv2.setMouseCallback('KCFTracker', onmouse)

# 摄像头未正确打开则退出
if not video.isOpened():
    print('Could not open video')
    sys.exit()

while True:
    # 读取当前帧
    ok, frame = video.read()
    if not ok:
        break
    # 以矩形标记鼠标框选区域
    if selection:
        x0, y0, x1, y1 = selection
        cv2.rectangle(frame, (x0, y0), (x1, y1), (255, 0, 0), 2, 1)

    # 函数执行开始时间
    timer = cv2.getTickCount()

    # 更新跟踪器得到最新目标区域
    track_ok = None
    if track_start:
        track_ok, bbox = tracker.update(frame)

    # 计算fps
    fps = cv2.getTickFrequency() / (cv2.getTickCount() - timer)

    # 画出目标最西边边界区域
    # 如果跟踪成功
    if track_ok:
        p1 = (int(bbox[0]), int(bbox[1]))
        p2 = (int(bbox[0] + bbox[2]), int(bbox[1] + bbox[3]))
        cv2.rectangle(frame, p1, p2, (255, 0, 0), 2, 1)
    elif not track_start:
        cv2.putText(frame, "No tracking target selected", (100, 80), cv2.FONT_HERSHEY_SIMPLEX, 0.75, (0, 0, 255), 2)
    elif not track_ok:
        cv2.putText(frame, "Tracking failure detected", (100, 80), cv2.FONT_HERSHEY_SIMPLEX, 0.75, (0, 0, 255), 2)

    # 显示提示信息
    cv2.putText(frame, "KCF Tracker", (100, 20), cv2.FONT_HERSHEY_SIMPLEX, 0.75, (50, 170, 50), 2)
    cv2.putText(frame, "FPS : " + str(int(fps)), (100, 50), cv2.FONT_HERSHEY_SIMPLEX, 0.75, (50, 170, 50), 2)

    # 显示结果
    cv2.imshow("KCFTracker", frame)

    # 按ESC退出
    k = cv2.waitKey(1) & 0xff
    if k == 27:
        break

video.release()
cv2.destroyAllWindows()