目标追踪概述

目标追踪

1 目标追踪概述

  • 目前追踪算法
    • **BOOSTING:**算法原理类似于Haar cascades (AdaBoost),是一种很老的算法。这个算法速度慢并且不是很准。
    • MIL:BOOSTING准一点。
    • KCF:速度比BOOSTINGMIL更快,与BOOSTINGMIL一样不能很好地处理遮挡问题。
    • CSRT:KCF更准一些,但是速度比KCF稍慢。
    • **MedianFlow:**对于快速移动的目标和外形变化迅速的目标效果不好。
    • **TLD:**会产生较多的false-positives。
    • MOSSE:算法速度非常快,但是准确率比不上KCF和**CSRT。**在一些追求算法速度的场合很适用。
    • **GOTURN:**OpenCV中自带的唯一一个基于深度学习的算法。运行算法需要提前下载好模型文件。

综合算法速度和准确率考虑,个人觉得CSRT、KCF、MOSSE这三个目标跟踪算法较好。

  • CF

    正负样本选择,变换矩阵,得到更多样本训练分类器

  • KCF算法原理

    KCF将待跟踪的目标表示为一个矩形框,然后在每一帧图像中通过计算目标区域与全局图像中所有可能的位置之间的相似度,找到最接近目标的位置。该相似度值通过傅里叶变换和核函数计算得出,然后通过最大化相似度值来更新目标区域的位置和大小

    KCF算法的关键在于采用了核技巧,这意味着可以使用非线性函数对输入数据进行映射,从而使得滤波器更加灵活。因此,KCF算法比其他相关滤波器算法更加适合处理复杂场景下的目标追踪任务,例如光照变化和旋转等。

    较于CF提速

2 多目标追踪

追踪算法涉及到一些遮蔽现象之后效果会变差

一些深度学习算法或许可以解决

3 深度学习检测框架加载

  1. 看2015年论文Faster-RCNN比较有价值的论文,这是后面的很多框架的基础

    • 简介

      Faster-RCNN是一个目标检测算法,它采用了两阶段的检测框架。首先,将输入图像通过卷积神经网络提取特征,然后在这些特征上使用区域建议网络(RPN)生成一些候选框。接下来,对这些候选框进行进一步的分类和回归,得到最终的目标检测结果。相比于其他单阶段的目标检测算法,如YOLO和SSD,Faster-RCNN有着更高的准确率和更低的误检率。但是,由于需要两个网络模型,因此其速度较慢。

  2. SSD

    • 简介

      Opencv SSD是一种目标检测算法,它基于深度神经网络,可以在图像或视频中检测出特定物体的位置和类别。SSD代表“Single Shot MultiBox Detector”,它可以快速地检测出多个不同大小和形状的物体。在使用Opencv SSD时,需要首先训练一个模型来识别所需的物体类别,然后将该模型应用于输入的图像或视频中。当检测到物体时,SSD会返回一个包含物体位置和类别的边界框,这些信息可以用于进一步处理和分析图像或视频数据

  3. YOLO

    • 简介

      YOLO是一种单阶段的目标检测算法,它可以实现实时目标检测。它将输入图像分成网格,并在每个网格中预测目标的位置和类别。与Faster-RCNN等两阶段方法不同,YOLO直接从原始图像中回归目标框,因此速度更快。但是由于网络结构相对简单,所以其检测精度可能会受到一些限制,而且对于小物体的检测效果可能不如其他算法。同时,YOLO也有不同版本,如YOLOv3、YOLOv4等,它们在网络结构和训练策略上都有所改进,提高了检测性能。

  4. MASK-RCNN

    • 简介

      MASK-RCNN是一个多任务学习算法,它在Faster-RCNN的基础上增加了一个分割头来实现物体实例分割。与单纯的目标检测不同,物体实例分割需要同时得到每个目标的位置和像素级的语义分割结果。MASK-RCNN通过在ROI池化操作后增加一个子网络,来预测每个RoI中物体的掩模信息,从而实现物体实例分割。MASK-RCNN可以同时进行目标检测和物体实例分割,在一些应用场景下具有很高的实用价值。但是由于增加了掩模预测子网络,所以其计算复杂度相较于Faster-RCNN也会有所提升。

4 基于dlib与ssd的追踪

  • dlib库

    dlib是一个用于机器学习和图像处理的C++库,它提供了一系列计算机视觉和机器学习算法的实现,并且能够在Python中进行使用。其主要功能包括:

    1. 人脸检测:使用HOG特征和级联分类器(cascade classifier)对图像中的人脸进行检测。

    2. 关键点检测:对人脸图像进行关键点检测,例如眼睛、鼻子、嘴巴等部位。

    3. 人脸识别:使用深度学习技术实现人脸识别,可以用于验证身份或者对人脸进行分类。

    4. 姿态估计:对人脸图像进行姿态估计,可以判断人脸的朝向和角度。

    5. 目标跟踪:对视频中的目标进行跟踪,可以用于自动驾驶、人员监控等领域。

    6. 图像变形:对图像进行变形,例如拉伸、扭曲等操作。

    7. 其他机器学习算法:dlib还包含了一些其他的机器学习算法,例如支持向量机(SVM)、线性回归等。

总步骤

  1. 检测阶段:使用SSD网络对图像中的物体进行检测,得到其位置和类别信息。

  2. 特征提取阶段:利用dlib库中的人脸检测器或者目标检测器来获取检测到的物体的特征向量,并将其保存。

  3. 匹配阶段:通过比较当前帧和上一帧中物体的特征向量,来匹配相同物体。可以使用各种方法如卡尔曼滤波、最近邻搜索等来实现匹配。

  4. 更新阶段:根据匹配结果,更新每个物体的位置和其他状态信息,例如速度、加速度等。

  5. 输出阶段:输出更新后的物体位置以及其它状态信息。

import cv2 as cv
import numpy as np
import dlib
print(dlib.DLIB_USE_CUDA)

video_file = 'videos/v2.mp4'
output = "output2.mp4"
CONFIDENCE_LIMIT = 0.4

# SSD标签
CLASSES = ["backgroud","aeroplane","bicycle","bird","boat",
           "bottle","bus","car","cat","chair","cow","diningtalble",
           "dog","horse","motorbike","person","pottedplant","sheep",
           "sofa","train","tvmoitor"]

# 读取网络模型
print('loading model...')
net = cv.dnn.readNetFromCaffe('dnn/MobileNetSSD_deploy.prototxt', 'dnn/MobileNetSSD_deploy.caffemodel')

# 初始化
print("[INFO] starting video stream...")
vs = cv.VideoCapture(video_file)
writer = None
trackers = []
labels = []

while True:
    ret, frame = vs.read()
    if not ret:
        break

    h, w = frame.shape[:2]
    width = 600
    r = width / float(w)
    dim = (width,int(h*r))
    frame = cv.resize(frame, dim, interpolation=cv.INTER_AREA)
    rgb = cv.cvtColor(frame, cv.COLOR_BGR2RGB)

    if output is not None and writer is None:
        fourcc = cv.VideoWriter_fourcc(*"MP4V")
        writer = cv.VideoWriter(output, fourcc,25,(frame.shape[1],frame.shape[0]),True)

    # 先检测,在追踪
    if len(trackers) == 0:
        (h, w) = frame.shape[:2]
        # 归一化,输出 = (原始-127.5) * factor
        blob = cv.dnn.blobFromImage(frame, 0.007843, (w,h), 127.5)

        # 得到检测结果
        net.setInput(blob)
        detections = net.forward()

        # 遍历得到的检测结果
        for i in np.arange(0, detections.shape[2]):
            # 检测多个物体,保留概率高的
            confidence = detections[0, 0, i ,2]

            # 过滤
            if confidence > CONFIDENCE_LIMIT:
                # 提取
                idx = int(detections[0, 0, i, 1])
                label = CLASSES[idx]

                # 只保留人的
                if CLASSES[idx] != "person":
                    continue

                # 得到BBOX
                print(detections[0, 0, i, 3:7])
                # 检测出来的是一个相对的值,比如0.2w,0.2h这样
                box = detections[0, 0, i, 3:7] * np.array([w, h, w, h])
                (startX, startY, endX, endY) = box.astype(int)

                # 用dlib进行目标追踪
                t = dlib.correlation_tracker()
                rect = dlib.rectangle(int(startX), int(startY), int(endX), int(endY))
                t.start_track(rgb, rect)  # 追踪的帧,框

                # 保存结果
                labels.append(label)
                trackers.append(t)

                # 绘测
                cv.rectangle(frame, (startX, startY), (endX, endY), (0,0,255), 2)
                cv.putText(frame, label, (startX, startY-15), cv.FONT_HERSHEY_SIMPLEX, 0.45,
                           (255, 0, 0), 2)
    else:
        # 更新参数
        for (t, l) in zip(trackers, labels):
            t.update(rgb)
            pos = t.get_position()  # 得到新的追踪的位置

            # 得到位置
            startX = int(pos.left())
            startY = int(pos.top())
            endX = int(pos.right())
            endY = int(pos.bottom())
            cv.rectangle(frame, (startX, startY), (endX, endY), (0, 0, 255), 2)
            cv.putText(frame, l, (startX, startY - 15), cv.FONT_HERSHEY_SIMPLEX, 0.45,
                       (255, 0, 0), 2)

    # 可以保存下结果
    # if writer is not None:
    #     writer.write(frame)
    # 显示
    cv.imshow("frame", frame)
    key = cv.waitKey(10) & 0xff

    if key == 27:
        break

# 就是说第一帧先检测出哪些是人,然后后面那些帧直接用dlb追踪的框架来去追踪

cv.destroyAllWindows()
vs.release()

5 多进程目标追踪

处理函数,输入输出队列

import cv2 as cv
import numpy as np
import dlib
import multiprocessing


def start_tracker(box, label, rgb, inputQueue, outputQueue):
    t = dlib.correlation_tracker()
    rect = dlib.rectangle(int(box[0]), int(box[1]), int(box[2]), int(box[3]))
    t.start_track(rgb, rect)

    while True:
        # 获取下一帧
        rgb = inputQueue.get()

        if rgb is not None:
            t.update(rgb)
            pos = t.get_position()  # 得到新的追踪的位置

            # 得到位置
            startX = int(pos.left())
            startY = int(pos.top())
            endX = int(pos.right())
            endY = int(pos.bottom())

            # 把结果放到输出Q,因为多进程没办法返回
            outputQueue.put((label, (startX, startY, endX, endY)))


inputQueues = []
outputQueues = []
video_file = 'videos/v2.mp4'
output = r"C:\Users\86189\Desktop\opencv\output2.avi"
CONFIDENCE_LIMIT = 0.4

# SSD标签
CLASSES = ["backgroud", "aeroplane", "bicycle", "bird", "boat",
           "bottle", "bus", "car", "cat", "chair", "cow", "diningtalble",
           "dog", "horse", "motorbike", "person", "pottedplant", "sheep",
           "sofa", "train", "tvmoitor"]

# 读取网络模型
print('[INFO] loading model...')
net = cv.dnn.readNetFromCaffe('dnn/MobileNetSSD_deploy.prototxt', 'dnn/MobileNetSSD_deploy.caffemodel')

# 初始化
print("[INFO] starting video stream...")
vs = cv.VideoCapture(video_file)
writer = None
trackers = []
labels = []

if __name__ == '__main__':
    while True:
        ret, frame = vs.read()
        if not ret:
            break

        h, w = frame.shape[:2]
        width = 600
        r = width / float(w)
        dim = (width, int(h * r))
        frame = cv.resize(frame, dim, interpolation=cv.INTER_AREA)
        rgb = cv.cvtColor(frame, cv.COLOR_BGR2RGB)

        if output is not None and writer is None:
            fourcc = cv.VideoWriter_fourcc(*"MJPG")
            writer = cv.VideoWriter(output, fourcc, 25, (frame.shape[1], frame.shape[0]), True)

        # 先检测,在追踪
        if len(inputQueues) == 0:
            (h, w) = frame.shape[:2]
            # 归一化,输出 = (原始-127.5) * factor
            blob = cv.dnn.blobFromImage(frame, 0.007843, (w, h), 127.5)

            # 得到检测结果
            net.setInput(blob)
            detections = net.forward()

            # 遍历得到的检测结果
            for i in np.arange(0, detections.shape[2]):
                # 检测多个物体,保留概率高的
                confidence = detections[0, 0, i, 2]

                # 过滤
                if confidence > CONFIDENCE_LIMIT:
                    # 提取
                    idx = int(detections[0, 0, i, 1])
                    label = CLASSES[idx]

                    # 只保留人的
                    if CLASSES[idx] != "person":
                        continue

                    # 得到BBOX
                    # print(detections[0, 0, i, 3:7])
                    # 检测出来的是一个相对的值,比如0.2w,0.2h这样
                    box = detections[0, 0, i, 3:7] * np.array([w, h, w, h])
                    (startX, startY, endX, endY) = box.astype("int")
                    bb = (startX, startY, endX, endY)

                    # 创建输入Q和输出Q
                    # 每个进程都有inputQ跟outputQ
                    iq = multiprocessing.Queue()
                    oq = multiprocessing.Queue()
                    inputQueues.append(iq)
                    outputQueues.append(oq)

                    # 每个进程都传入对应的队列
                    p = multiprocessing.Process(
                        target=start_tracker,
                        args=(bb, label, rgb, iq, oq)
                    )
                    p.daemon = True
                    p.start()

                    # 绘测
                    cv.rectangle(frame, (startX, startY), (endX, endY), (0, 0, 255), 2)
                    cv.putText(frame, label, (startX, startY - 15), cv.FONT_HERSHEY_SIMPLEX, 0.45,
                               (255, 0, 0), 2)
        else:
            # 多个追踪器处理的都是相同输入
            for iq in inputQueues:
                iq.put(rgb)
            for oq in outputQueues:
                # 得到更新结果
                label, (startX, startY, endX, endY) = oq.get()

                cv.rectangle(frame, (startX, startY), (endX, endY), (0, 0, 255), 2)
                cv.putText(frame, label, (startX, startY - 15), cv.FONT_HERSHEY_SIMPLEX, 0.45,
                           (255, 0, 0), 2)

        if writer is not None:
            writer.write(frame)
        # 显示
        cv.imshow("frame", frame)
        key = cv.waitKey(1) & 0xff

        if key == 27:
            break

# 就是说第一帧先检测出哪些是人,然后后面那些帧直接用dlb追踪的框架来去追踪

if writer is not None:
    writer.release()
cv.destroyAllWindows()
vs.release()

速度巨快

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
你好!关于YOLO目标追踪的教程,我可以为你提供一些基本的信息和指导。YOLO(You Only Look Once)是一种流行的目标检测算法,它能够实时准确地识别图像或视频中的多个目标。 以下是一个简单的YOLO目标追踪教程的步骤概述: 1. 数据集准备:首先,你需要准备一个适合你任务的数据集。这个数据集应该包含带有标记框的图像集合,每个框表示图像中的一个目标。 2. 模型训练:使用准备好的数据集,你可以选择使用已经训练好的YOLO模型进行迁移学习,或者从头开始训练一个新的模型。你可以使用YOLO的开源实现,如Darknet或YOLOv5等。 3. 目标追踪:一旦你有了训练好的YOLO模型,你可以将其应用于目标追踪任务。对于视频,你可以逐帧地使用YOLO模型检测目标,并使用一些算法(如卡尔曼滤波器)来跟踪目标在不同帧之间的位置。 4. 评估和优化:完成目标追踪后,你可以对结果进行评估和优化。这可以包括计算目标的准确度、召回率等指标,并根据需要调整模型或追踪算法的参数。 请注意,YOLO目标追踪是一个广泛的领域,具体的实现和细节可能因应用场景而有所不同。因此,我建议你在开始之前先了解一些相关的基础知识,并参考一些开源项目和教程来帮助你更好地理解和实践YOLO目标追踪。 希望这些信息对你有所帮助!如果你有任何进一步的问题,请随时提问。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值