单目标跟踪 (五)cv2.Tracker

from imutils.video import VideoStream
from imutils.video import FPS
import argparse
import imutils
import time
import cv2

ap = argparse.ArgumentParser()
ap.add_argument("-v", "--video", type=str,
                help="path to input video file")
ap.add_argument("-t", "--tracker", type=str, default="mil",
                help="OpenCV object tracker type")
args = vars(ap.parse_args())

(major, minor) = cv2.__version__.split(".")[:2]

if int(major) == 3 and int(minor) < 3:
    tracker = cv2.Tracker_create(args["tracker"].upper())
else:
    OPENCV_OBJECT_TRACKERS = {
        "boosting": cv2.TrackerBoosting_create,#慢 无尺度 效果差 抖动
        "mil": cv2.TrackerMIL_create,#慢 无尺度
        "tld": cv2.TrackerTLD_create,  # 慢 应对大尺度变换,运行以及遮挡  容易无跟踪位置跳变
        "medianflow": cv2.TrackerMedianFlow_create,  # 较快 对追踪失败反馈敏锐  快速移动效果较差
        "kcf": cv2.TrackerKCF_create,  # 较快 无尺度  完全遮挡难以恢复
        "mosse": cv2.TrackerMOSSE_create,  # 较快 无尺度  鲁棒性较好,可以应对光线变换,尺度变换,姿势变动以及非网格化的变形  可以在目标消失时暂停并在目标出现时重启
        "csrt": cv2.TrackerCSRT_create,  # 慢 无尺度
    }


    tracker = OPENCV_OBJECT_TRACKERS[args["tracker"]]()   ###

#写
#tracker.save(args["tracker"]+'_params.json')
#读
#fs = cv2.FileStorage(args["tracker"]+'_params.json', cv2.FileStorage_READ)
#tracker.read(fs.getFirstTopLevelNode())


initBB = None

if not args.get("video", False):
    print("[INFO] starting video stream...")
    vs = VideoStream(src=0).start()
    time.sleep(1.0)
else:
    vs = cv2.VideoCapture(args["video"])

fps = None

while True:
    frame = vs.read()
    frame = frame[1] if args.get("video", False) else frame
    if frame is None:
        break
    frame = imutils.resize(frame, width=720)
    (H, W) = frame.shape[:2]

    if initBB is not None:
        (success, box) = tracker.update(frame)   ###
        if success:
            (x, y, w, h) = [int(v) for v in box]
            cv2.rectangle(frame, (x, y), (x + w, y + h),
                          (0, 255, 0), 2)
        fps.update()
        fps.stop()

        info = [
            ("Tracker", args["tracker"]),
            ("Success", "Yes" if success else "No"),
            ("FPS", "{:.2f}".format(fps.fps())),
        ]

        for (i, (k, v)) in enumerate(info):
            text = "{}: {}".format(k, v)
            cv2.putText(frame, text, (10, H - ((i * 20) + 20)),
                        cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 0, 255), 2)
    cv2.imshow("Frame", frame)
    key = cv2.waitKey(1) & 0xFF

    if key == ord("s"):
        initBB = cv2.selectROI("Frame", frame, fromCenter=False,showCrosshair=False)
        tracker.init(frame, initBB)  ###
        fps = FPS().start()

    elif key == ord("q"):
        break
if not args.get("video", False):
    vs.stop()

else:
    vs.release()

cv2.destroyAllWindows()
###光流
now_gray=cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
now_landmarks=np.array(results[0,15:]).reshape(-1,2).astype('float32')
lk_params=dict(winSize  = (5,5),maxLevel = 2,
               criteria = (cv2.TERM_CRITERIA_EPS | cv2.TERM_CRITERIA_COUNT, 10, 0.03))

# 前一帧的角点和当前帧的图像作为输入来得到角点在当前帧的位置
now_landmarks_1, match, err = cv2.calcOpticalFlowPyrLK(last_gray, now_gray, last_landmarks, None, **lk_params)
# 当前帧跟踪到的角点及图像和前一帧的图像作为输入来找到前一帧的角点位置
now_landmarks_2, match, err = cv2.calcOpticalFlowPyrLK(now_gray, last_gray,now_landmarks_1, None,**lk_params)  

# 得到角点回溯与前一帧实际角点的位置变化关系
d = abs(last_landmarks - now_landmarks_2).reshape(-1, 2).max(-1)  
#判断d内的值是否小于1,大于1跟踪被认为是错误的跟踪点
good = d < 0.1

Median-Flow追踪算法

 作者假设一个“好”的追踪算法应该具有正反向连续性(forward-backward consistency),即无论是按照时间上的正序追踪还是反序追踪,产生的轨迹应该是一样的。

作者根据这个性质规定了任意一个追踪器的FB误差(forward-backward error):从时间t的初始位置x(t)开始追踪产生时间t+p的位置x(t+p),再从位置x(t+p)反向追踪产生时间t的预测位置x`(t),初始位置和预测位置之间的欧氏距离就作为追踪器在t时间的FB误差。

Median-Flow追踪算法采用的是Lucas-Kanade追踪器,也就是光流法追踪器。

首先在上一帧t的物体包围框里均匀地产生一些点,然后用Lucas-Kanade追踪器正向追踪这些点到t+1帧,再反向追踪到t帧,计算FB误差,筛选出FB误差最小的一半点作为最佳追踪点。最后根据这些点的坐标变化和距离的变化计算t+1帧包围框的位置和大小(平移的尺度取中值,缩放的尺度取中值)。

《Forward-Backward Error: Automatic Detection of Tracking Failures》

还可以用NCC(Normalized Cross Correlation,归一化互相关)和SSD(Sum-of-Squared Differences,差值平方和)作为筛选追踪点的衡量标准。

NCC:ncc

SSD:ssd

Lucas-Kanade追踪器(LKT)cv.calcOpticalFlowPyrLK()

假设条件:

(1)亮度恒定:同一点随着时间的变化,其亮度不会发生改变;

(2)小运动:短时间的变化不会引起位置的剧烈变化,这样灰度才能对位置求偏导(用前后帧之间单位位置变化引起的灰度变化去近似灰度对位置的偏导数);

(3)空间一致:一个场景上邻近的点投影到图像上也是邻近点,且邻近点速度一致。这是Lucas-Kanade光流法特有的假定。

设在短时间内前一帧图像块A与后一帧图像块B的值(图像的内容)不变,那么就是图像块在图像坐标系下的的速度。

 

  • 2
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
好的,我们可以使用特征点检测算法来实现获取机头坐标。在跟踪目标后,可以使用SIFT、SURF、ORB等算法来检测目标的特征点,并绘制出特征点的位置。代码如下: ``` import cv2 # 创建跟踪器对象 tracker = cv2.TrackerCSRT_create() # 打开视频文件 video = cv2.VideoCapture('plane.mp4') # 读取第一帧 ok, frame = video.read() # 选择要跟踪的目标区域 bbox = cv2.selectROI(frame, False) # 初始化跟踪器 ok = tracker.init(frame, bbox) while True: # 读取当前帧 ok, frame = video.read() if not ok: break # 跟踪目标 ok, bbox = tracker.update(frame) # 如果跟踪成功,绘制跟踪框和中心点 if ok: # 获取跟踪框坐标 x, y, w, h = [int(i) for i in bbox] # 绘制跟踪框 cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2) # 计算中心点坐标 center_x = x + w/2 center_y = y + h/2 # 绘制中心点 cv2.circle(frame, (int(center_x), int(center_y)), 5, (0, 0, 255), -1) # 显示中心点坐标 text = 'Center: ({:.1f}, {:.1f})'.format(center_x, center_y) cv2.putText(frame, text, (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 0.8, (0, 0, 255), 2) # 特征点检测 gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) detector = cv2.ORB_create() keypoints = detector.detect(gray, None) for kp in keypoints: x, y = kp.pt cv2.circle(frame, (int(x), int(y)), 3, (255, 0, 0), -1) cv2.putText(frame, 'Head', (int(x)-10, int(y)-10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 0, 0), 2) cv2.putText(frame, '({:.1f}, {:.1f})'.format(x, y), (int(x)-50, int(y)-30), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 0, 0), 2) # 显示视频帧 cv2.imshow('Airplane Tracking', frame) # 等待按下 ESC 键退出 if cv2.waitKey(1) == 27: break # 释放资源 video.release() cv2.destroyAllWindows() ``` 在这段代码中,我们使用ORB算法来检测特征点,并在特征点位置上绘制红色的圆形和文字。同时,在文字中显示特征点的坐标值。你可以根据需要选择其他的特征点检测算法来实现相同的功能。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值