【python】OpenCV—Tracking(10.5)—dlib

在这里插入图片描述

文章目录

  • 1、功能描述
  • 2、代码实现
  • 3、效果展示
  • 4、完整代码
  • 5、涉及到的库函数
    • dlib.correlation_tracker()
  • 6、参考

1、功能描述

基于 dlib 库,实现指定类别的目标检测和单目标跟踪

2、代码实现

caffe 模型

https://github.com/MediosZ/MobileNet-SSD/tree/master/mobilenet

或者

链接: https://pan.baidu.com/s/1fiBz6tEQmcXdw_dtaUuAVw?pwd=pw5n
提取码: pw5n

在这里插入图片描述

输入 1x3x300x300

输出的类别数为 21

在这里插入图片描述

在这里插入图片描述

导入必要的包

from imutils.video import FPS
import numpy as np
import argparse
import imutils
import dlib
import cv2

注意 dlib 的安装

conda 或者 pip 安装,如果 build 失败的话,可以试试下载 whl 安装

https://github.com/Silufer/dlib-python/tree/main

python -V 查看 python 版本,然后找到对应版本的 whl ,pip install xxx.whl


构造参数解析并解析参数

ap = argparse.ArgumentParser()
ap.add_argument("-p", "--prototxt", required=True,help="path to Caffe 'deploy' prototxt file")
ap.add_argument("-m", "--model", required=True,help="path to Caffe pre-trained model")
ap.add_argument("-v", "--video", required=True,help="path to input video file")
ap.add_argument("-l", "--label", required=True,help="class label we are interested in detecting + tracking")
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())

涉及到 caffe 模型的 prototxt,caffemodel,输入视频,类别标签,输出视频,检测框的置信度配置

moblienet 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"])# 初始化视频流、dlib 相关跟踪器、输出视频写入器和预测的类标签
print("[INFO] starting video stream...")
vs = cv2.VideoCapture(args["video"])
tracker = None
writer = None
label = ""
# 启动每秒帧数估计器
fps = FPS().start()

循环读取视频帧

# 循环播放视频文件流中的帧
while True:# 从视频文件中获取下一帧(grabbed, frame) = vs.read()# 检查我们是否已经到达视频文件的末尾if frame is None:break# 调整帧大小以加快处理速度,然后将帧从 BGR 转换为 RGB 排序(dlib 需要 RGB 排序)frame = imutils.resize(frame, width=600)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)

resize 图片至宽为 600,转化为 RGB 输入模式,设置输出视频相关配置

    # 如果我们的相关对象跟踪器是None,我们首先需要应用一个对象检测器来为跟踪器提供实际跟踪的东西if tracker is None:# 获得帧尺寸并将帧转换为 blob(h, w) = frame.shape[:2]blob = cv2.dnn.blobFromImage(frame, 0.007843, (w, h), 127.5)# blob传入网络并获得检测结果net.setInput(blob)detections = net.forward()# 确保至少有一个检测结果if len(detections) > 0:# 找到概率最大的检测索引——为方便起见,我们只跟踪我们以最大概率找到的第一个对象;# 未来的示例将演示如何检测和提取*特定*对象i = np.argmax(detections[0, 0, :, 2])# 获取与对象关联的概率及其类标签conf = detections[0, 0, i, 2]label = CLASSES[int(detections[0, 0, i, 1])]# filter out weak detections by requiring a minimum# confidenceif conf > args["confidence"] and label == args["label"]:# compute the (x, y)-coordinates of the bounding box# for the objectbox = detections[0, 0, i, 3:7] * np.array([w, h, w, h])(startX, startY, endX, endY) = box.astype("int")# construct a dlib rectangle object from the bounding# box coordinates and then start the dlib correlation# trackertracker = dlib.correlation_tracker()rect = dlib.rectangle(startX, startY, endX, endY)tracker.start_track(rgb, rect)# draw the bounding box and text for the objectcv2.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)

第一帧的时候,调用目标检测模型,获取检测结果 detections

如果检测到了目标,预测的分数大于配置的阈值,且预测的类别和配置的类别一致

初始化跟踪器 tracker,可视化检测结果


否则,我们已经执行了检测,所以让我们跟踪对象

    else:# 更新跟踪器并抓取被跟踪对象的位置tracker.update(rgb)pos = tracker.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, label, (startX, startY - 15),cv2.FONT_HERSHEY_SIMPLEX, 0.45, (0, 255, 0), 2)

后续帧采用跟踪算法,update 更新目标坐标后,通过 get_position 获取新的坐标,并可视化


    # 检查我们是否应该将帧写入磁盘if writer is not None:writer.write(frame)# 显示输出帧cv2.imshow("Frame", frame)key = cv2.waitKey(1) & 0xFF# 如果按下了“q”键,则退出循环if key == ord("q"):break# 更新FPS计数器fps.update()

保存和可视化结果,按 q 键退出视频流


# 我们的 fps 计数器停止并且 FPS 信息显示在终端中
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()
# 最后,我们关闭所有 OpenCV 窗口并释放视频流
cv2.destroyAllWindows()
vs.release()

完成信息统计,释放资源

3、效果展示

train_result

cat_result

4、完整代码

# 导入必要的包
from imutils.video import FPS
import numpy as np
import argparse
import imutils
import dlib
import cv2# 构造参数解析并解析参数
ap = argparse.ArgumentParser()
ap.add_argument("-p", "--prototxt", required=True,help="path to Caffe 'deploy' prototxt file")
ap.add_argument("-m", "--model", required=True,help="path to Caffe pre-trained model")
ap.add_argument("-v", "--video", required=True,help="path to input video file")
ap.add_argument("-l", "--label", required=True,help="class label we are interested in detecting + tracking")
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())# 初始化MobileNet 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"])# 初始化视频流、dlib 相关跟踪器、输出视频写入器和预测的类标签
print("[INFO] starting video stream...")
vs = cv2.VideoCapture(args["video"])
tracker = None
writer = None
label = ""
# 启动每秒帧数估计器
fps = FPS().start()# 循环播放视频文件流中的帧
while True:# 从视频文件中获取下一帧(grabbed, frame) = vs.read()# 检查我们是否已经到达视频文件的末尾if frame is None:break# 调整帧大小以加快处理速度,然后将帧从 BGR 转换为 RGB 排序(dlib 需要 RGB 排序)frame = imutils.resize(frame, width=600)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)# 如果我们的相关对象跟踪器是None,我们首先需要应用一个对象检测器来为跟踪器提供实际跟踪的东西if tracker is None:# 获得帧尺寸并将帧转换为 blob(h, w) = frame.shape[:2]blob = cv2.dnn.blobFromImage(frame, 0.007843, (w, h), 127.5)# blob传入网络并获得检测结果net.setInput(blob)detections = net.forward()# 确保至少有一个检测结果if len(detections) > 0:# 找到概率最大的检测索引——为方便起见,我们只跟踪我们以最大概率找到的第一个对象;# 未来的示例将演示如何检测和提取*特定*对象i = np.argmax(detections[0, 0, :, 2])# 获取与对象关联的概率及其类标签conf = detections[0, 0, i, 2]label = CLASSES[int(detections[0, 0, i, 1])]# filter out weak detections by requiring a minimum# confidenceif conf > args["confidence"] and label == args["label"]:# compute the (x, y)-coordinates of the bounding box# for the objectbox = detections[0, 0, i, 3:7] * np.array([w, h, w, h])(startX, startY, endX, endY) = box.astype("int")# construct a dlib rectangle object from the bounding# box coordinates and then start the dlib correlation# trackertracker = dlib.correlation_tracker()rect = dlib.rectangle(startX, startY, endX, endY)tracker.start_track(rgb, rect)# draw the bounding box and text for the objectcv2.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:# 更新跟踪器并抓取被跟踪对象的位置tracker.update(rgb)pos = tracker.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, label, (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# 如果按下了“q”键,则退出循环if key == ord("q"):break# 更新FPS计数器fps.update()# 我们的 fps 计数器停止并且 FPS 信息显示在终端中
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()
# 最后,我们关闭所有 OpenCV 窗口并释放视频流
cv2.destroyAllWindows()
vs.release()

测试脚本1

python .\track.py -p .\mobilenet_ssd\MobileNetSSD_deploy.prototxt -m .\mobilenet_ssd\MobileNetSSD_deploy.caffemodel -v .\cat.mp4 -l cat -o cat_result.mp4

测试脚本2

python .\track.py -p .\mobilenet_ssd\MobileNetSSD_deploy.prototxt -m .\mobilenet_ssd\MobileNetSSD_deploy.caffemodel -v .\train.mp4 -l aeroplane -o train_result.mp4

5、涉及到的库函数

dlib.correlation_tracker()

dlib.correlation_tracker 是 Dlib 库中的一个功能,用于实现目标跟踪(Object Tracking)。

dlib.correlation_tracker 基于判别式相关滤波器(Discriminative Correlation Filter, DCF)的方法,这种方法通过训练一个滤波器来区分目标对象和背景,从而实现高效的跟踪。

使用 dlib.correlation_tracker 跟踪目标通常涉及以下几个步骤:

  • 初始化跟踪器:首先,你需要创建一个 correlation_tracker 对象。这通常是在你已知目标对象在第一帧中的位置时进行的。
  • 设置目标区域:你需要指定一个矩形区域(通常通过左上角和右下角的坐标或者通过中心点和尺寸)来标识目标对象在第一帧中的位置。
  • 更新跟踪器:对于后续的视频帧,你需要将新的帧传递给跟踪器,并让它更新目标的位置。这个过程会不断重复,直到视频结束或者跟踪失败。
  • 获取跟踪结果:每次更新后,你可以从跟踪器中获取当前帧中目标对象的位置。

以下是一个简单的示例,展示了如何使用 dlib.correlation_tracker 进行目标跟踪:

import dlib
import cv2# 加载视频
cap = cv2.VideoCapture('video.mp4')# 读取第一帧
ret, frame = cap.read()# 选择目标区域(这里需要手动选择或者通过某种方法自动选择)
rect = dlib.rectangle(50, 50, 200, 200)  # 示例矩形,需要替换为实际的目标位置# 创建跟踪器
tracker = dlib.correlation_tracker()
tracker.start_track(frame, rect)while cap.isOpened():ret, frame = cap.read()if not ret:break# 更新跟踪器tracker.update(frame)# 获取跟踪结果rect = tracker.get_position()# 在帧上绘制跟踪结果cv2.rectangle(frame, (rect.left(), rect.top()), (rect.right(), rect.bottom()), (0, 255, 0), 2)# 显示结果cv2.imshow('Tracking', frame)# 按下 'q' 键退出if cv2.waitKey(1) & 0xFF == ord('q'):break# 释放资源
cap.release()
cv2.destroyAllWindows()

注意事项

  • 目标初始化:目标在第一帧中的位置对于跟踪器的性能至关重要。如果初始化不准确,跟踪可能会失败。
  • 视频质量:视频的质量(如分辨率、帧率、光照条件等)也会影响跟踪器的性能。
  • 遮挡和快速移动:当目标被遮挡或者快速移动时,跟踪器可能会遇到困难。虽然 dlib.correlation_tracker 已经在很多场景下表现良好,但在这些情况下可能需要更复杂的策略。

通过 dlib.correlation_tracker,你可以实现高效且相对准确的目标跟踪,适用于各种计算机视觉应用,如视频监控、人机交互等。

6、参考

  • 目标跟踪(4)使用dlib进行对象跟踪
  • dlib–win系统所有版本文件下载地址whl文件

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

探索温度计的数字化设计:一个可视化温度数据的Web图表案例

随着科技的发展,数据可视化在各个领域中的应用越来越广泛。在温度监控和展示方面,传统的温度计已逐渐被数字化温度计所取代。本文将介绍一个使用Echarts库创建的温度计Web图表,该图表通过动态数据可视化展示了温度值,并通过渐变色…

20241128解决Ubuntu20.04安装libwxgtk3.0-dev异常的问题

20241128解决Ubuntu20.04安装libwxgtk3.0-dev异常的问题 2024/11/28 16:17 缘起:中科创达的高通CM6125开发板的Android10的编译环境需要。 安装异常:rootrootrootroot-X99-Turbo:~$ rootrootrootroot-X99-Turbo:~$ sudo apt-get install libwxgtk3.0-de…

大疆T100大载重吊运植保无人机技术详解

大疆T100作为一款大载重吊运植保无人机,融合了全新的AI和AR功能,旨在进一步提升安全性并满足喷洒、播撒、吊运等多种作业场景的需求。以下是对其技术的详细解析: 一、总体性能 最大起飞重量:149.9公斤 喷洒容量:75升…

arkTS:使用ArkUI实现用户信息的持久化管理与自动填充(PersistentStorage)

arkUI:使用ArkUI实现用户信息的持久化管理与自动填充(PersistentStorage) 1 主要内容说明2 例子2.1 登录页2.1.1登陆页的相关说明2.1.1.1 持久化存储的初始化2.1.1.2 输入框2.1.1.3 记住密码选项2.1.1.4 登录按钮的逻辑2.1.1.5 注册跳转 2.1.…

腾讯云 AI 代码助手:单元测试应用实践

引言 在软件开发这一充满创造性的领域中,开发人员不仅要构建功能强大的软件,还要确保这些软件的稳定性和可靠性。然而,开发过程中并非所有任务都能激发创造力,有些甚至是重复且乏味的。其中,编写单元测试无疑是最令人…

1、Three.js开端准备环境

准备工作 从 CDN 导入 1.安装 VSCode 2.安装 Node.js 3.查看Three.js最新版本 4.如何cdn引入: https://cdn.jsdelivr.net/npm/threev版本号/build/three.module.js 例如:https://cdn.jsdelivr.net/npm/threev0.170.0/build/three.module.js 我们需要…

Python毕业设计选题:基于django+vue的校园影院售票系统

开发语言:Python框架:djangoPython版本:python3.7.7数据库:mysql 5.7数据库工具:Navicat11开发软件:PyCharm 系统展示 管理员登录 管理员功能界面 用户管理 影院信息管理 电影类型管理 电影信息管理 系统…

初窥 HTTP 缓存

引言 对于前端来说, 你肯定听说过 HTTP 缓存。 当然不管你知不知道它, 对于提高网站性能和用户体验, 它都扮演着重要的角色! 它通过在客户端和服务器之间存储和重用先前获取的资源副本, 来减少网络流量和降低资源加载时间, 从而提升用户体验! 以下是 HTTP 缓存的重要性: 减少…

Django 视图层

from django.shortcuts import render, HttpResponse, redirectfrom django.http import JsonResponse1. render: 渲染模板 def index(request):print(reverse(index))return render(request, "index.html")return render(request, index.html, context{name: lisi})…

简单介绍下 VitePress 中的 vp-doc 和 vp-raw

VitePress 是一个轻量级的静态网站生成器,专为快速构建文档网站而设计。它是基于 Vite 和 Vue 3 构建的,旨在提供快速的开发体验和高效的构建过程。 存在两个需要注意的点:vp-doc 和 vp-raw,它们代表了不同的 CSS 样式类和用途&a…

【数据结构】LinkedList与链表

LinkedList与链表 1. ArrayList的缺陷2. 链表2.1 链表的概念及结构2.2 链表的实现 3.链表面试题 【本节目标】 ArrayList的缺陷链表链表相关ojLinkedList的模拟实现LinkedList的使用ArrayList和LinkedList的区别 1. ArrayList的缺陷 上节课已经熟悉了ArrayList的使用&#xf…

Matrix Multiplication

lab要求如下:

Laravel8.5+微信小程序实现京东商城秒杀方案

一、商品秒杀涉及的知识点 鉴权策略封装掊口访问频次限制小程序设计页面防抖接口调用订单创建事务使用超卖防御 二、订单库存系统方案(3种) 下单减库存 优点是库存和订单的强一致性,商品不会卖超,但是可能导致恶意下单&#xff…

esp8266 编译、烧录环境搭建

一、准备 xtensa-lx106-elf-gcc8-4-0-esp-2020r3-win32下载:点击跳转 MSYS2 压缩包文件: 固件烧录工具:点击跳转 esp8266源码地址:点击跳转 二、搭建编译环境 1、在D盘创建一个ESP8266目录,解压MSYS2.zip到里面&a…

WEB攻防-通用漏洞CSRFSSRF协议玩法内网探针漏洞利用

CSRF构造工具,也可以用bp构造 选中要保存的请求,点击Generate HTML,生成带有添加用户请求的html文件,然后将构造的html放在网站上,生成访问地址,诱导管理员点击链接,就会添加用户 start Recording之后就会…

2-7 C函数指针与回调函数

前言: 对函数指针与回调函数知识回顾,仅供学习参考... 目录 前言: 1.0 函数指针 2.0 函数指针变量 3.0 函数指针与指针函数 4.0 函数指针类型 5.0 卡点 后记: 1.0 函数指针 函数指针,简单来说就是指向函数的指针…

分布式FastDFS存储的同步方式

目录 一:FatsDFS的结构图 二:FatsDFS文件同步 前言: 1:同步日志所在目录 2:binlog格式 3:同步规则 4:binlog同步过程 1 :获取组内的其他Storage信息 tracker_report_thread_e…

【大模型】ChatGPT 提示词优化进阶操作实战详解

目录 一、前言 二、ChatGPT 提示词几个基本的优化原则 2.1 明确的提示词 2.1.1 提示词具体而清晰 2.1.1.1操作案例演示 2.2 确定焦点 2.2.1 操作案例演示 2.3 保持提示词的相关性 2.3.1 什么是相关性 2.3.2 提示词相关性操作案例一 2.3.2 提示词相关性操作案例二 三…

C 语言学习的经典书籍有哪些?

学习C语言的理由 C语言是一种程席设计语言,它是由美国AT&T公司贝尔实验室的Dennis Ritchie于1972年发明的。C语言之所以流行,是因为它简单易用。学习C语言的几个理由如下: (1)C、C#和Java使用一种被称为面向对象程序设计(0bject-Orient…

在鲲鹏麒麟服务器上部署MySQL主从集群

因项目需求需要部署主从MySQL集群,继续采用上次的部署的MySQL镜像arm64v8/mysql:latest,版本信息为v8.1.0。计划部署服务器192.168.31.100和192.168.31.101 部署MySQL主节点 在192.168.31.100上先创建好/data/docker/mysql/data和/data/docker/mysql/l…