python,使用opencv的目标追踪,基于KCF或者CSRT

记录第一个目标追踪程序

目前csdn查询到的基于opencv的目标追踪
在框选ROI的时候都是非常反人类的

此代码可以实时框选RIOI区域

我的运行环境python3.7+win10

复制一下代码可以直接运行

运行此代码需要卸载opencv

pip uninstall opencv-python

以及安装 opencv-contrib-python

pip install opencv-contrib-python -i https://pypi.tuna.tsinghua.edu.cn/simple

稍后发布基于此代码的树莓派两轴云台追踪指定物体

2020 09 02修订
增加目标丢失警告,不会自动找回目标,需要手动重新追踪
2020 09 03修订
对每一帧进行高斯处理,修复追踪窗口超出窗口范围报错,代码简洁化

#zoulee24
import cv2
import time
import sys

from click import globals
from skimage.metrics import structural_similarity

def mouse_event(event, x, y, flags, parms):
    global points #全局调用
    if event == cv2.EVENT_LBUTTONDOWN:
        points = [(x, y)]

    #elif event == cv2.EVENT_MOUSEMOVE and flags == cv2.EVENT_FLAG_LBUTTON:
    elif len(points) == 1 and event != cv2.EVENT_LBUTTONUP:
        cv2.rectangle(frame, points[0], (x, y), (0, 255, 0), thickness=2)
    elif event == cv2.EVENT_LBUTTONUP and 0 < len(points) < 2:
        if points[0] != (x, y):
            points.append((x, y))
            #判断是否非正常画框
            if points[0][0] > points[1][0]:
                if points[0][1] > points[1][1]:
                    points = [(points[1][0], points[1][1]), (points[0][0], points[0][1])]
                else:
                    points = [(points[1][0], points[0][1]), (points[0][0], points[1][1])]
            else:
                if points[0][1] > points[1][1]:
                    points = [(points[0][0], points[1][1]), (points[1][0], points[0][1])]
        else:
            points = []

def main(cap):
    global frame, points
    ok = False
    points = []
    cv2.namedWindow('get ROI')
    cv2.setMouseCallback('get ROI', mouse_event)
    while not ok:
        ret, frame = cap.read()
        cv2.putText(frame, 'press Space to choice ROI', (5, 15), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 1)
        cv2.putText(frame, 'press R to rechoie ROI', (5, 30), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 1)
        key = cv2.waitKey(5) & 0xFF
        if len(points) == 2:
            cv2.rectangle(frame, points[0], points[1], (0, 255, 0), thickness=2)
        if key == 27:
            cap.release()
            cv2.destroyAllWindows()
            sys.exit()
        elif key == ord('r'):
            points = []
        elif key == 32 and len(points) == 2:
            locations = (points[0][0], points[0][1], points[1][0] - points[0][0], points[1][1] - points[0][1])
            points = []
            ok = True
            #break
        cv2.imshow('get ROI', frame)

    object_to_track = frame[locations[1]:locations[1] + locations[3], locations[0]:locations[0] + locations[2], :]
    return locations, object_to_track

def judge_tracker(tracker, box):
    global frame
    ok = tracker.init(frame, box)
    if not ok:
        raise Exception("追踪器工作初始化失败")
    else:
        pass

def tracker_start():
    tracker = cv2.TrackerCSRT_create()
    #tracker = cv2.TrackerKCF_create()
    return tracker

def tracker_working(tracker, cap, object):
    object = cv2.cvtColor(object, cv2.COLOR_BGR2GRAY)
    t1 = round(time.time(), 2)
    while cap.isOpened():
        t2 = round(time.time(), 2)
        ret, frame = cap.read()
        frame_blur = frame.copy()
        frame_blur = cv2.GaussianBlur(frame_blur, (5, 5), 0)
        ok, new_location = tracker.update(frame_blur)

        if ok:
            p1 = [int(new_location[0]), int(new_location[1])]
            p2 = [int(new_location[0] + new_location[2]), int(new_location[1] + new_location[3])]
            p1 = tuple(0 if i < 0 else i for i in p1)
            if p2[0] > 640:
                p2[0] = 640
            if p2[1] > 360:
                p2[1] = 360
            p2 = tuple(p2)

            if (t2 - t1) % 1 > 0.9 or (t2 - t1) % 1 < 0.1:
                frame_object = frame[p1[1]:p2[1], p1[0]:p2[0]]
                frame_object = cv2.cvtColor(frame_object, cv2.COLOR_BGR2GRAY)
                frame_object = cv2.resize(frame_object, (object.shape[1], object.shape[0]))
                #print("object:{} object_frame:{}".format(object.shape, frame_object.shape))
                (score, _) = structural_similarity(object, frame_object, full=True)
                if score < 0.3:
                    cv2.putText(frame, "WARNING LOSING TARGET", (50, 45), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255),
                                2)

            cv2.putText(frame, "press Q to rechoice ROI", (5, 15), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 1)
            cv2.putText(frame, "press Esc to choice ROI", (5, 30), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 1)
            # Tracking success
            cv2.rectangle(frame, p1, p2, (255, 0, 0), thickness=2, lineType=1)
            '''
            if (p1[0] + p2[0]) < frame.shape[1]:
                cv2.putText(frame, "need to be left", (100, 200), cv2.FONT_HERSHEY_SIMPLEX, 2, (0, 0, 255), 3)
            else:
                cv2.putText(frame, "need to be right", (100, 200), cv2.FONT_HERSHEY_SIMPLEX, 2, (0, 0, 255), 3)
            '''
        else:
            # Tracking failure
            #frame = np.zeros(frame.shape, np.uint8)
            cv2.putText(frame, "Tracking failure detected", (50, 50), cv2.FONT_HERSHEY_SIMPLEX, 3, (0, 0, 255), 1)
            cv2.imshow("get ROI", frame)
            time.sleep(2)
            break
        cv2.imshow("get ROI", frame)
        key = cv2.waitKey(1) & 0xFF
        if key == 27:
            return False
        elif key == ord('q'):
            break
    return True

if __name__ == '__main__':
    cap = cv2.VideoCapture(0, cv2.CAP_DSHOW)
    ret = True
    while ret:
        location, object_to_track = main(cap)
        tracker = tracker_start()
        judge_tracker(tracker, location)
        ret = tracker_working(tracker, cap, object_to_track)
    cap.release()
    cv2.destroyAllWindows()

有任何问题可以评论区指出

  • 4
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

zoulee24

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值