OpenCV从入门到精通实战(六)——多目标追踪

基于原生的追踪

使用OpenCV库实现基于视频的对象追踪。通过以下步骤和Python代码,您将能够选择不同的追踪器,并对视频中的对象进行实时追踪。

步骤 1: 导入必要的库

首先,我们需要导入一些必要的Python库,包括argparsetimecv2 (OpenCV) 和 numpy

import argparse
import time
import cv2
import numpy as np

步骤 2: 设置参数解析

使用argparse库来解析命令行参数。我们将指定输入视频文件的路径以及选择的追踪器类型。

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

步骤 3: 定义支持的追踪器

在OpenCV中,有多种对象追踪器可用。我们将它们存储在一个字典中,便于后续使用。

OPENCV_OBJECT_TRACKERS = {
    "csrt": cv2.TrackerCSRT_create,
    "kcf": cv2.TrackerKCF_create,
    "boosting": cv2.TrackerBoosting_create,
    "mil": cv2.TrackerMIL_create,
    "tld": cv2.TrackerTLD_create,
    "medianflow": cv2.TrackerMedianFlow_create,
    "mosse": cv2.TrackerMOSSE_create
}

步骤 4: 初始化追踪器和视频流

我们初始化一个多对象追踪器并打开视频文件。

trackers = cv2.MultiTracker_create()
vs = cv2.VideoCapture(args["video"])

步骤 5: 处理视频帧

接下来,我们读取视频中的每一帧,并对其进行缩放处理,然后使用追踪器更新追踪状态,并绘制追踪的边框。

while True:
    frame = vs.read()
    frame = frame[1]
    if frame is None:
        break
    (h, w) = frame.shape[:2]
    width = 600
    r = width / float(w)
    dim = (width, int(h * r))
    frame = cv2.resize(frame, dim, interpolation=cv2.INTER_AREA)
    (success, boxes) = trackers.update(frame)
    for box in boxes:
        (x, y, w, h) = [int(v) for v in box]
        cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2)
    cv2.imshow("Frame", frame)
    key = cv2.waitKey(100) & 0xFF
    if key == ord("s"):
        box = cv2.selectROI("Frame", frame, fromCenter=False, showCrosshair=True)
        tracker = OPENCV_OBJECT_TRACKERS[args["tracker"]]()
        trackers.add(tracker, frame, box)
    elif key == 27:
        break
vs.release()
cv2.destroyAllWindows()

总结

import argparse
import time
import cv2
import numpy as np

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

# opencv已经实现了的追踪算法

OPENCV_OBJECT_TRACKERS = {

	"csrt": cv2.TrackerCSRT_create,
	"kcf": cv2.TrackerKCF_create,
	"boosting": cv2.TrackerBoosting_create,
	"mil": cv2.TrackerMIL_create,
	"tld": cv2.TrackerTLD_create,
	"medianflow": cv2.TrackerMedianFlow_create,
	"mosse": cv2.TrackerMOSSE_create
}

# 实例化OpenCV's multi-object tracker
trackers = cv2.MultiTracker_create()
vs = cv2.VideoCapture(args["video"])

# 视频流
while True:
	# 取当前帧
	frame = vs.read()
	# (true, data)
	frame = frame[1]
	# 到头了就结束
	if frame is None:
		break

	# resize每一帧
	(h, w) = frame.shape[:2]
	width=600
	r = width / float(w)
	dim = (width, int(h * r))
	frame = cv2.resize(frame, dim, interpolation=cv2.INTER_AREA)

	# 追踪结果
	(success, boxes) = trackers.update(frame)

	# 绘制区域
	for box in boxes:
		(x, y, w, h) = [int(v) for v in box]
		cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2)

	# 显示
	cv2.imshow("Frame", frame)
	key = cv2.waitKey(100) & 0xFF

	if key == ord("s"):
		# 选择一个区域,按s
		box = cv2.selectROI("Frame", frame, fromCenter=False,
			showCrosshair=True)

		# 创建一个新的追踪器
		tracker = OPENCV_OBJECT_TRACKERS[args["tracker"]]()
		trackers.add(tracker, frame, box)

	# 退出
	elif key == 27:
		break
vs.release()
cv2.destroyAllWindows()

通过上述步骤和代码,可以实现一个简单的视频对象追踪应用,该应用支持多种追踪算法,并允许用户实时选择和追踪视频中的对象。这种技术在许多领域都有广泛的应用,包括安全监控、人机交互和自动驾驶车辆等。

检测模型的跟踪

检测模型 使用Python、OpenCV、dlib和多进程处理视频中的实时对象跟踪。以下是具体步骤及相关代码片段:

1. 设置和参数解析

  • 导入必要的库,并设置参数解析,处理输入如视频文件路径和模型配置。
from utils import FPS
import multiprocessing
import numpy as np
import argparse
import dlib
import cv2

2. 初始化深度学习模型

  • 加载预训练的Caffe模型进行对象检测。
net = cv2.dnn.readNetFromCaffe(args["prototxt"], args["model"])

3. 视频流处理

  • 从指定的文件开始视频捕捉,并准备处理帧。
vs = cv2.VideoCapture(args["video"])

4. 帧处理

  • 调整帧大小并转换为RGB格式进行处理。
  • 如果检测到的对象置信度高于阈值,则初始化对象跟踪。
rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)

5. 对象检测和跟踪

  • 对初次检测到的对象创建跟踪器,并使用多进程处理。
p = multiprocessing.Process(target=start_tracker, args=(bb, label, rgb, iq, oq))
p.daemon = True
p.start()

6. 追踪器更新和结果输出

  • 每个跟踪器获取新的帧,更新位置并输出跟踪结果。
outputQueue.put((label, (startX, startY, endX, endY)))

7. 视频输出和显示

  • 如果指定了输出文件,将处理后的帧写入视频文件。
  • 显示处理后的帧并在用户按下ESC键时停止。
writer.write(frame)
key = cv2.waitKey(1) & 0xFF
if key == 27:
    break

8. 清理和资源释放

  • 停止FPS计时,释放视频文件和窗口资源。
fps.stop()
writer.release()
cv2.destroyAllWindows()
vs.release()

完整代码:
utils.py

import datetime

class FPS:
    def __init__(self):
        # store the start time, end time, and total number of frames
        # that were examined between the start and end intervals
        self._start = None
        self._end = None
        self._numFrames = 0

    def start(self):
        # start the timer
        self._start = datetime.datetime.now()
        return self

    def stop(self):
        # stop the timer
        self._end = datetime.datetime.now()

    def update(self):
        # increment the total number of frames examined during the
        # start and end intervals
        self._numFrames += 1

    def elapsed(self):
        # return the total number of seconds between the start and
        # end interval
        return (self._end - self._start).total_seconds()

    def fps(self):
        # compute the (approximate) frames per second
        return self._numFrames / self.elapsed()

multi_object_tracking_fast.py

import datetime

class FPS:
    def __init__(self):
        # store the start time, end time, and total number of frames
        # that were examined between the start and end intervals
        self._start = None
        self._end = None
        self._numFrames = 0

    def start(self):
        # start the timer
        self._start = datetime.datetime.now()
        return self

    def stop(self):
        # stop the timer
        self._end = datetime.datetime.now()

    def update(self):
        # increment the total number of frames examined during the
        # start and end intervals
        self._numFrames += 1

    def elapsed(self):
        # return the total number of seconds between the start and
        # end interval
        return (self._end - self._start).total_seconds()

    def fps(self):
        # compute the (approximate) frames per second
        return self._numFrames / self.elapsed()

multi_object_tracking_slow.py

#导入工具包
from utils import FPS
import numpy as np
import argparse
import dlib
import cv2
"""
--prototxt mobilenet_ssd/MobileNetSSD_deploy.prototxt 
--model mobilenet_ssd/MobileNetSSD_deploy.caffemodel 
--video race.mp4
"""
# 参数
ap = argparse.ArgumentParser()
ap.add_argument("-p", "--prototxt", default="mobilenet_ssd/MobileNetSSD_deploy.prototxt",
	help="path to Caffe 'deploy' prototxt file")
ap.add_argument("-m", "--model", default="mobilenet_ssd/MobileNetSSD_deploy.caffemodel",
	help="path to Caffe pre-trained model")
ap.add_argument("-v", "--video",default="race.mp4",
	help="path to input video file")
ap.add_argument("-o", "--output", type=str,
	help="path to optional output video file")
ap.add_argument("-c", "--confidence", type=float, default=0.2,
	help="minimum probability to filter weak detections")
args = vars(ap.parse_args())


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

# 读取网络模型
print("[INFO] loading model...")
net = cv2.dnn.readNetFromCaffe(args["prototxt"], args["model"])

# 初始化
print("[INFO] starting video stream...")
vs = cv2.VideoCapture(args["video"])
writer = None

# 一会要追踪多个目标
trackers = []
labels = []

# 计算FPS
fps = FPS().start()

while True:
	# 读取一帧
	(grabbed, frame) = vs.read()

	# 是否是最后了
	if frame is None:
		break

	# 预处理操作
	(h, w) = frame.shape[:2]
	width=600
	r = width / float(w)
	dim = (width, int(h * r))
	frame = cv2.resize(frame, dim, interpolation=cv2.INTER_AREA)
	rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)

	# 如果要将结果保存的话
	if args["output"] is not None and writer is None:
		fourcc = cv2.VideoWriter_fourcc(*"MJPG")
		writer = cv2.VideoWriter(args["output"], fourcc, 30,
			(frame.shape[1], frame.shape[0]), True)

	# 先检测 再追踪
	if len(trackers) == 0:
		# 获取blob数据
		(h, w) = frame.shape[:2]
		blob = cv2.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 > args["confidence"]:
				# extract the index of the class label from the
				# detections list
				idx = int(detections[0, 0, i, 1])
				label = CLASSES[idx]

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

				# 得到BBOX
				#print (detections[0, 0, i, 3:7])
				box = detections[0, 0, i, 3:7] * np.array([w, h, w, h])
				(startX, startY, endX, endY) = box.astype("int")

				# 使用dlib来进行目标追踪
				#http://dlib.net/python/index.html#dlib.correlation_tracker
				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)

				# 绘图
				cv2.rectangle(frame, (startX, startY), (endX, endY),
					(0, 255, 0), 2)
				cv2.putText(frame, label, (startX, startY - 15),
					cv2.FONT_HERSHEY_SIMPLEX, 0.45, (0, 255, 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())

			# 画出来
			cv2.rectangle(frame, (startX, startY), (endX, endY),
				(0, 255, 0), 2)
			cv2.putText(frame, l, (startX, startY - 15),
				cv2.FONT_HERSHEY_SIMPLEX, 0.45, (0, 255, 0), 2)

	# 也可以把结果保存下来
	if writer is not None:
		writer.write(frame)

	# 显示
	cv2.imshow("Frame", frame)
	key = cv2.waitKey(1) & 0xFF

	# 退出
	if key == 27:
		break

	# 计算FPS
	fps.update()


fps.stop()
print("[INFO] elapsed time: {:.2f}".format(fps.elapsed()))
print("[INFO] approx. FPS: {:.2f}".format(fps.fps()))

if writer is not None:
	writer.release()

cv2.destroyAllWindows()
vs.release()

在这里插入图片描述
在这里插入图片描述

代码地址:多目标追踪

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/554017.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Redis从入门到精通(十四)Redis分布式缓存(二)Redis哨兵集群的搭建和原理分析

文章目录 前言5.3 Redis哨兵5.3.1 哨兵原理5.3.1.1 集群的结构和作用5.3.1.2 集群监控原理5.3.1.3 集群故障恢复原理 5.3.2 搭建哨兵集群5.3.3 RedisTemplate5.3.3.1 搭建测试项目5.3.3.2 场景测试 前言 Redis分布式缓存系列文章: Redis从入门到精通(十三)Redis分…

回文链表题解

题目:回文链表 分析 这道题目标签为简单题,但是如果要实现下面的进阶过程不是很简单。 拿到题目一般来说就是赶时间,没有要求的情况下直接使用一个列表存储所有的数值,然后判断这个列表是否满足回文,这个思路是比较简…

【1524】java投票管理系统Myeclipse开发mysql数据库web结构java编程计算机网页项目

一、源码特点 java 投票管理系统是一套完善的java web信息管理系统,对理解JSP java编程开发语言有帮助,系统具有完整的源代码和数据库,系统主要采用B/S模式开发。开发环境为TOMCAT7.0,Myeclipse8.5开发,数据库为Mysql5.0&…

IO引脚服用和映射

什么是端口复用 STM32F4 有很多的内置外设,这些外设的外部引脚都是与 GPIO 复用的。也就是说,一个 GPIO如果可以复用为内置外设的功能引脚,那么当这个 GPIO 作为内置外设使用的时候,就叫做复用。在芯片数据手册或STM32F4XX参考手…

传感器融合 | 适用于自动驾驶场景的激光雷达传感器融合项目_将激光雷达的高分辨率成像+测量物体速度的能力相结合

项目应用场景 面向自动驾驶场景的激光雷达传感器融合,将激光雷达的高分辨率成像测量物体速度的能力相结合,项目是一个从多个传感器获取数据并将其组合起来的过程,可以更加好地进行环境感知。项目支持 ubuntu、mac 和 windows 平台。 项目效果…

ASP.NET基于TCP协议的简单即时通信软件的设计与实现

摘 要 即时通信(Instant Message),由于其具有实时性、跨平台性、成本低、效率高等优点而受到广泛的使用。设计并实现一个能够处理多用户进行实时、安全的即时通信系统具有较强的现实意义。即时通信的底层通信是通过SOCKET套接字接口实现的。当前的主流UNIX系统和微…

Android --- Activity

官方文档-activity Activity 提供窗口,供应在其中多个界面。此窗口通常会填满屏幕,但也可能小于屏幕并浮动在其他窗口之上。 大多数应用包含多个屏幕,这意味着它们包含多个 Activity。通常,应用中的一个 Activity 会被指定主 Ac…

Linux数据库自动备份 - 定时任务发到百度云盘、坚果云、邮箱附件

前言 1. 坚果云的webdav云盘最好! (免费账号每月1G上传流量) 2. 不建议数据库备份文件发送到SMTP邮箱,因为对方服务器非常容易当做垃圾邮件处理,而且发信的SMTP账号会被封禁(实测163发到QQ邮箱被封&…

lambda捕获列表

lambda是C11新特性之一,优点是: 1.可以直接匿名定义目标函数或函数对象,不需要额外写一个函数 2.lambda是一个匿名的内联函数 捕获列表 总结:【】为值捕获,只读 【&】为引用捕获,可读可写

Midjourney指南 - 生成高分辨率图片(内容已更新至V5)

Midjourney 首先为每个作业生成一个低分辨率图片网格(2x2)。你可以在选择其中任一图片,使用 Midjourney upscaler 来增加尺寸并添加更多细节。有多种可用于放大图像的放大模型。 每个图像网格下方的按钮用于放大所选图像。U1 U2 U3 U4 注:upscaler 以下…

震惊金融界!巴克莱银行报告称去年投资诈骗激增29%

巴克莱银行 (Barclays) 发布的令人担忧的数据显示,在过去一年里,投资诈骗数量激增了 29%,震惊了金融界。这些诈骗给该银行的活期账户客户造成了巨大损失,占欺诈者损失资金的最高比例,平均索赔超过14,000英镑。 投资骗…

如何合理利用多个中国大陆小带宽服务器?

我们知道在中国大陆带宽单价非常昂贵,一个1Mbps 带宽的机子一年就得卖好几百人民币,这是不值当的,当然我们可以去低价漂阿里云、腾讯云的轻量服务器,99包年,但是带宽太小很难崩。 所以,我们必须构建一个能够…

怎么购买GPT api

怎么购买GPT api GPT API是由OpenAI提供的一种应用程序编程接口(API),允许开发者通过编程方式访问OpenAI开发的GPT(Generative Pre-trained Transformer)模型。GPT是一种基于深度学习的自然语言处理技术,主…

刷题之Leetcode19题(超级详细)

19.删除链表的倒数第N个节点 力扣题目链接(opens new window)https://leetcode.cn/problems/remove-nth-node-from-end-of-list/ 给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点。 进阶:你能尝试使用一趟扫描实现吗&#x…

爱普生计时设备AUTOMOTIVE RA8900CE DTCXO RTC

主要特点出场已校准带有DTCXO的RTC,并且内部集成晶体单元高精度: 3.4 ppm 40 to 85 C(9 s/月.)时钟输出:1 Hz.1024 Hz.32.768 kHzI 2 C Interface: Fast mode (400 kHz)The l2C-Bus is a trademark ofNXP Semiconductors供电电压: 2.5-5.5 V(main),1.6-5.5 V(备份电…

软考132-上午题-【软件工程】-沟通路径

一、定义 1-1、沟通路径1 沟通路径 1-2、沟通路径2 沟通路径 n-1 二、真题 真题1: 真题2: 真题3:

国外AI programmer 后来者SWE-agent,Devin不在孤寂

如果你正在寻找一种人工智能(AI)自主软件工程师Devin的替代品,它的强大程度足以与最近宣布的自主AI编码平台竞争。这位新手就是SWE-Agent!它是由普林斯顿大学NLP小组创造的开源人工智能程序员,旨在自主解决GitHub问题并实现最先进的性能,估值目标为20亿美元。SWE Agent在S…

jar包混淆

由于开发需要,不让甲方反编译出源代码。 命令如下: java -jar classfinal-fatjar-1.2.1.jar -file mis-admin.jar -libjars mis-ducg-3.5.0.jar -packages com.mis,cn.edu -pwd 123456 -Y 反编译软件编译的源码如下:直接null,成…

k8s使用harbor私有仓库镜像 —— 筑梦之路

官方文档: Secret | Kubernetes ImagePullSecrets的设置是kubernetes机制的另一亮点,习惯于直接使用Docker Pull来拉取公共镜像,但非所有容器镜像都是公开的。此外,并不是所有的镜像仓库都允许匿名拉取,也就是说需要身份认证&…

回归预测 | Matlab实现GWO-GPR灰狼算法优化高斯过程回归多变量回归预测

回归预测 | Matlab实现GWO-GPR灰狼算法优化高斯过程回归多变量回归预测 目录 回归预测 | Matlab实现GWO-GPR灰狼算法优化高斯过程回归多变量回归预测预测效果基本介绍程序设计参考资料 预测效果 基本介绍 Matlab实现GWO-GPR灰狼算法优化高斯过程回归多变量回归预测 1.Matlab实现…