YOLO+SlowFast+DeepSORT 简单实现视频行为识别

前段时间刷短视频看到过别人用摄像头自动化监控员工上班状态,比如标注员工是不是离开了工位,在位置上是不是摸鱼。虽然是段子,但是这个是可以用识别技术实现一下,于是我在网上找,知道发现了 SlowFast,那么下面就用 SlowFast 简单测试一下视频的行为识别。

工具简介

YOLO

YOLO 是一个基于深度学习神经网络的对象识别和定位算法,前面我也用 v5s 训练了标注的扑克牌,实现了图片或视频中的点数识别,这里就跳过了。

DeepSORT

DeepSORT 是一个实现目标跟踪的算法,其使用卡尔曼滤波器预测所检测对象的运动轨迹。也就是当视频中有多个目标,算法能知道上一帧与下一帧各目标对象的匹配,从而完成平滑锁定,而不是在视频播放或记录时,检测框一闪一闪的。

SlowFast

SlowFast 是一个行为分类模型 (pytorchvideo 内置),可以通过输入视频序列和检测框信息,输出每个检测框的行为类别。所以需要借助类似 YOLO 的多目标检测模型,当然 SlowFast 也可以自行标注数据集训练,来完成自定义的行为识别。

流程

  • 读取视频或者摄像头中的图片
  • 通过 yolo 检测出画面的目标
  • 通过 deep_sort 对目标进行跟踪
  • 通过 slowfast 识别出目标的动作
  • 根据识别的动作进行业务处理等

编码

整个流程下来,除了安装 slowfast 依赖 (pytorchvideo) 外,deep_sort 可以下载 github.com/wufan-tb/yo… 然后 import 到项目中。如果要实时处理摄像头的视频,可以通过采用多线程,单独开一个线程读摄像头并一秒保存一张图,再开一个线程用于处理保存的图片,最后将处理后的结果保存为视频,或者只是做一些业务操作,以下只是一个例子。

ini
复制代码
import torch
import numpy as np
import os,cv2,time,torch,random,pytorchvideo,warnings,argparse,math
warnings.filterwarnings("ignore",category=UserWarning)from pytorchvideo.transforms.functional import (uniform_temporal_subsample,short_side_scale_with_boxes,clip_boxes_to_image,)
from torchvision.transforms._functional_video import normalize
from pytorchvideo.data.ava import AvaLabeledVideoFramePaths
from pytorchvideo.models.hub import slowfast_r50_detection
from deep_sort.deep_sort import DeepSortclass MyVideoCapture:def __init__(self, source):self.cap = cv2.VideoCapture(source)self.idx = -1self.end = Falseself.stack = []def read(self):self.idx += 1ret, img = self.cap.read()if ret:self.stack.append(img)else:self.end = Truereturn ret, imgdef to_tensor(self, img):img = torch.from_numpy(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))return img.unsqueeze(0)def get_video_clip(self):assert len(self.stack) > 0, "clip length must large than 0 !"self.stack = [self.to_tensor(img) for img in self.stack]clip = torch.cat(self.stack).permute(-1, 0, 1, 2)del self.stackself.stack = []return clipdef release(self):self.cap.release()def tensor_to_numpy(tensor):img = tensor.cpu().numpy().transpose((1, 2, 0))return imgdef ava_inference_transform(clip, boxes,num_frames = 32, #if using slowfast_r50_detection, change this to 32, 4 for slow crop_size = 640, data_mean = [0.45, 0.45, 0.45], data_std = [0.225, 0.225, 0.225],slow_fast_alpha = 4, #if using slowfast_r50_detection, change this to 4, None for slow
):boxes = np.array(boxes)roi_boxes = boxes.copy()clip = uniform_temporal_subsample(clip, num_frames)clip = clip.float()clip = clip / 255.0height, width = clip.shape[2], clip.shape[3]boxes = clip_boxes_to_image(boxes, height, width)clip, boxes = short_side_scale_with_boxes(clip,size=crop_size,boxes=boxes,)clip = normalize(clip,np.array(data_mean, dtype=np.float32),np.array(data_std, dtype=np.float32),) boxes = clip_boxes_to_image(boxes, clip.shape[2],  clip.shape[3])if slow_fast_alpha is not None:fast_pathway = clipslow_pathway = torch.index_select(clip,1,torch.linspace(0, clip.shape[1] - 1, clip.shape[1] // slow_fast_alpha).long())clip = [slow_pathway, fast_pathway]return clip, torch.from_numpy(boxes), roi_boxesdef plot_one_box(x, img, color=[100,100,100], text_info="None",velocity=None, thickness=1, fontsize=0.5, fontthickness=1):c1, c2 = (int(x[0]), int(x[1])), (int(x[2]), int(x[3]))cv2.rectangle(img, c1, c2, color, thickness, lineType=cv2.LINE_AA)t_size = cv2.getTextSize(text_info, cv2.FONT_HERSHEY_TRIPLEX, fontsize , fontthickness+2)[0]cv2.rectangle(img, c1, (c1[0] + int(t_size[0]), c1[1] + int(t_size[1]*1.45)), color, -1)cv2.putText(img, text_info, (c1[0], c1[1]+t_size[1]+2), cv2.FONT_HERSHEY_TRIPLEX, fontsize, [255,255,255], fontthickness)return imgdef deepsort_update(Tracker, pred, xywh, np_img):outputs = Tracker.update(xywh, pred[:,4:5],pred[:,5].tolist(),cv2.cvtColor(np_img,cv2.COLOR_BGR2RGB))return outputsdef save_yolopreds_tovideo(yolo_preds, id_to_ava_labels, color_map, output_video, vis=False):for i, (im, pred) in enumerate(zip(yolo_preds.ims, yolo_preds.pred)):if pred.shape[0]:for j, (*box, cls, trackid, vx, vy) in enumerate(pred):if int(cls) != 0:ava_label = ''elif trackid in id_to_ava_labels.keys():ava_label = id_to_ava_labels[trackid].split(' ')[0]else:ava_label = 'Unknow'text = '{} {} {}'.format(int(trackid),yolo_preds.names[int(cls)],ava_label)color = color_map[int(cls)]im = plot_one_box(box,im,color,text)im = im.astype(np.uint8)output_video.write(im)if vis:cv2.imshow("demo", im)def main(config):device = config.deviceimsize = config.imsize# model = torch.hub.load('D:/3code/6pytorch/opencv_demo/05_yolo_v5.6', 'yolov5s', source='local', pretrained=True).to(device)model = torch.hub.load('ultralytics/yolov5', 'yolov5l6').to(device)model.conf = config.confmodel.iou = config.ioumodel.max_det = 100if config.classes:model.classes = config.classesvideo_model = slowfast_r50_detection(True).eval().to(device)deepsort_tracker = DeepSort("deep_sort/deep_sort/deep/checkpoint/ckpt.t7")ava_labelnames,_ = AvaLabeledVideoFramePaths.read_label_map("selfutils/temp.pbtxt")coco_color_map = [[random.randint(0, 255) for _ in range(3)] for _ in range(80)]vide_save_path = config.outputvideo=cv2.VideoCapture(config.input)width,height = int(video.get(3)),int(video.get(4))video.release()outputvideo = cv2.VideoWriter(vide_save_path,cv2.VideoWriter_fourcc(*'mp4v'), 25, (width,height))print("processing...")cap = MyVideoCapture(config.input)id_to_ava_labels = {}a=time.time()while not cap.end:ret, img = cap.read()if not ret:continueyolo_preds=model([img], size=imsize)yolo_preds.files=["img.jpg"]deepsort_outputs=[]for j in range(len(yolo_preds.pred)):temp=deepsort_update(deepsort_tracker,yolo_preds.pred[j].cpu(),yolo_preds.xywh[j][:,0:4].cpu(),yolo_preds.ims[j])if len(temp)==0:temp=np.ones((0,8))deepsort_outputs.append(temp.astype(np.float32))yolo_preds.pred=deepsort_outputsif len(cap.stack) == 25:print(f"processing {cap.idx // 25}th second clips")clip = cap.get_video_clip()if yolo_preds.pred[0].shape[0]:inputs, inp_boxes, _=ava_inference_transform(clip, yolo_preds.pred[0][:,0:4], crop_size=imsize)inp_boxes = torch.cat([torch.zeros(inp_boxes.shape[0],1), inp_boxes], dim=1)if isinstance(inputs, list):inputs = [inp.unsqueeze(0).to(device) for inp in inputs]else:inputs = inputs.unsqueeze(0).to(device)with torch.no_grad():slowfaster_preds = video_model(inputs, inp_boxes.to(device))slowfaster_preds = slowfaster_preds.cpu()for tid,avalabel in zip(yolo_preds.pred[0][:,5].tolist(), np.argmax(slowfaster_preds, axis=1).tolist()):id_to_ava_labels[tid] = ava_labelnames[avalabel+1]save_yolopreds_tovideo(yolo_preds, id_to_ava_labels, coco_color_map, outputvideo, config.show)print("total cost: {:.3f} s, video length: {} s".format(time.time()-a, cap.idx / 25))cap.release()outputvideo.release()print('saved video to:', vide_save_path)if __name__=="__main__":parser = argparse.ArgumentParser()parser.add_argument('--input', type=str, default="/home/wufan/images/video/vad.mp4", help='test imgs folder or video or camera')parser.add_argument('--output', type=str, default="output.mp4", help='folder to save result imgs, can not use input folder')parser.add_argument('--imsize', type=int, default=640, help='inference size (pixels)')parser.add_argument('--conf', type=float, default=0.4, help='object confidence threshold')parser.add_argument('--iou', type=float, default=0.4, help='IOU threshold for NMS')parser.add_argument('--device', default='cuda', help='cuda device, i.e. 0 or 0,1,2,3 or cpu')parser.add_argument('--classes', nargs='+', type=int, help='filter by class: --class 0, or --class 0 2 3')parser.add_argument('--show', action='store_true', help='show img')config = parser.parse_args()if config.input.isdigit():print("using local camera.")config.input = int(config.input)print(config)main(config)

其他

demo 中用的是网络 yolo,默认下载位置 C:\Users\Administrator/.cache\torch\hub\ultralytics_yolov5_master,而 slowfast 权重文件位置是 C:\Users\Administrator.cache\torch\hub\checkpoints\SLOWFAST_8x8_R50_DETECTION.pyth。

报错

运行执行命令,出现 AttributeError: ‘Upsample’ object has no attribute 'recompute_scale_factor’错误,根据提示,找到 torch 下的 upsampling.py,将 return F.interpolate (input, self.size, self.scale_factor, self.mode, self.align_corners,

recompute_scale_factor=self.recompute_scale_factor) 修改为

return F.interpolate(input, self.size, self.scale_factor, self.mode, self.align_corners)。

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

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

相关文章

计算机毕业设计------基于SpringCloud的实验室管理系统

项目介绍 实验室管理系统的用户可以分为两种:系统管理员和普通用户。系统管理员主要功能: 登录登出、分析数据、管理用户、管理日志、管理实验室、管理预约、维护个人资料、实验室保修管理 用户主要功能: 注册登录、查询实验室、实验室预约…

基于ThinkPHP的云盘系统Cloudreve本地搭建并实现远程访问

文章目录 1、前言2、本地网站搭建2.1 环境使用2.2 支持组件选择2.3 网页安装2.4 测试和使用2.5 问题解决 3、本地网页发布3.1 cpolar云端设置3.2 cpolar本地设置 4、公网访问测试5、结语 1、前言 自云存储概念兴起已经有段时间了,各互联网大厂也纷纷加入战局&#…

element中Table表格控件实现单选功能、多选功能、两种分页方式

目录 1、Table表格控件实现单选功能2、Table控件和Pagination控件实现多选和两种分页方式方法一&#xff1a;使用slice方法方法二&#xff1a;多次调用接口 1、Table表格控件实现单选功能 <template><div><!-- highlight-current-row 是否要高亮当前行 -->…

WEB:探索开源PDF.js技术应用

1、简述 PDF.js 是一个由 Mozilla 开发的开源 JavaScript 库&#xff0c;用于在浏览器中渲染 PDF 文档。它的目标是提供一个纯粹的前端解决方案&#xff0c;摆脱了依赖插件或外部程序的束缚&#xff0c;使得在任何支持 JavaScript 的浏览器中都可以轻松地显示 PDF 文档。 2、…

【JUC】Synchronized及JVM底层原理

Synchronized使用方式 Synchronized有三种应用方式 作用于实例方法&#xff0c;当前示实例加锁进入同步代码前要获得当前实例的锁&#xff0c;即synchronized普通同步方法&#xff0c;调用指令将会检查方法的ACC_SYNCHRONIZED访问标志是否被设置。 如果设置了&#xff0c;执行…

Linux 的引导与服务控制

一 开机启动过程 bios加电自检-->mbr-->grub-->加载内核文件-->启动进程 1 bios家电自检 检测硬件是否正常&#xff0c;然后根据bios中的启动项设置&#xff0c;去找内核文件 2 mbr 因为grup太大,第一个扇区存不下所有的grub程序&#xff0c;所以分为2部分指…

【每天五道题,轻松公务员】Day3:太阳常识

目录 专栏了解 ☞欢迎订阅☜ ★专栏亮点★ ◇专栏作者◇ 太阳常识 题目一 题目二 题目三 题目四 题目五 答案 补充扩展 专栏了解 ☞欢迎订阅☜ 欢迎订阅此专栏&#xff1a;考公务员&#xff0c;必订&#xff01;https://blog.csdn.net/m0_73787047/category_1254…

Android studio BottomNavigationView 应用设计

一、新建Bottom Navigation Activity项目&#xff1a; 二、修改bottom_nav_menu.xml: <itemandroid:id"id/navigation_beijing"android:icon"drawable/ic_beijing_24dp"android:title"string/title_beijing" /><itemandroid:id"i…

反编译有哪些优势

在现在这个信息化的时代&#xff0c;软件开发中的编程是关键步骤&#xff0c;了解编程的反编译同样至关重要。对于大多数人来说&#xff0c;编程和反编译似乎是两个相对比较陌生的概念&#xff0c;但是都在软件开发周期中起着至关重要的作用。尤其是反编译&#xff0c;它在多个…

maven学习笔记

先赞后看&#xff0c;养成习惯&#xff01;&#xff01;&#xff01;❤️ ❤️ ❤️ 文章码字不易&#xff0c;如果喜欢可以关注我哦&#xff01; ​如果本篇内容对你有所启发&#xff0c;欢迎访问我的个人博客了解更多内容&#xff1a;链接地址 基础 maven的作用 项目构建&a…

xshell配色

xshell-设置命令行提示符&配色方案 更换配色&#xff1a; Protect Eyes.xcs [Protect Eyes] text00ff40 cyan(bold)93a1a1 text(bold)839496 magentadd3682 green80ff80 green(bold)859900 background042028 cyan2aa198 red(bold)cb4b16 yellowb58900 magenta(bold)6c71c…

总结MySQL 的一些知识点:MySQL 排序

&#x1f337;&#x1f341; 博主猫头虎&#xff08;&#x1f405;&#x1f43e;&#xff09;带您 Go to New World✨&#x1f341; &#x1f984; 博客首页——&#x1f405;&#x1f43e;猫头虎的博客&#x1f390; &#x1f433; 《面试题大全专栏》 &#x1f995; 文章图文…

VPP配置指南:基于IKEv2的IPsec VPN

正文共&#xff1a;1024 字 13 图&#xff0c;预估阅读时间&#xff1a;1 分钟 现在&#xff0c;我们已经能够熟练地部署VPP了&#xff08;不用半小时&#xff0c;最快8分钟即可在CentOS上完成VPP的部署&#xff09;&#xff0c;而且已经能够满足基本的转发要求&#xff0c;那今…

非科班,培训出身,怎么进大厂?

今天分享一下我是怎么进大厂的经历&#xff0c;希望能给大家带来一点点启发&#xff01; 阿七毕业于上海一所大学的管理学院&#xff0c;在读期间没写过一行 Java 代码。毕业之后二战考研失利。 回过头来看&#xff0c;也很庆幸这次考研失利&#xff0c;因为这个时候对社会一…

【Vue2+3入门到实战】(22)VUE3之组合式API - setup、reactive和ref函数、computed、watch、生命周期函数详细讲解

目录 一、组合式API - setup选项1. setup选项的写法和执行时机2. setup中写代码的特点3. <script setup>语法糖 二、组合式API - reactive和ref函数1. reactive2. ref3. reactive 对比 ref 三、组合式API - computed四、组合式API - watch1. 侦听单个数据2. 侦听多个数据…

基于Kettle开发的web版数据集成开源工具(data-integration)-部署篇

目录 &#x1f4da;第一章 前言&#x1f4d7;背景&#x1f4d7;目的&#x1f4d7;总体方向 &#x1f4da;第二章 下载编译&#x1f4d7;下载&#x1f4d7;编译 &#x1f4da;第三章 部署&#x1f4d7;准备工作&#x1f4d5; 安装数据库&redis&consul&#x1f4d5; 修改…

wy的leetcode刷题记录_Day71

wy的leetcode刷题记录_Day71 声明 本文章的所有题目信息都来源于leetcode 如有侵权请联系我删掉! 时间&#xff1a;2024-1-3&#xff08;补&#xff09; 前言 目录 wy的leetcode刷题记录_Day71声明前言2487. 从链表中移除节点题目介绍思路代码收获 509. 斐波那契数题目介绍思…

为即将到来的量子攻击做好准备的 4 个步骤

当谈到网络和技术领域时&#xff0c;一场风暴正在酝酿——这场风暴有可能摧毁我们数字安全的根本结构。这场风暴被称为 Q-Day&#xff0c;是即将到来的量子计算时代的简写&#xff0c;届时量子计算机的功能将使最复杂的加密算法变得过时。 这场量子革命正以惊人的速度到来&am…

golang 图片加水印

需求&#xff1a; 1&#xff0c;员工签到图片加水印 2&#xff0c;水印文字需要有半透明的底色&#xff0c;避免水印看不清 3&#xff0c;图片宽设置在600&#xff0c;小于600或者大于600都需要等比例修改图片的高度&#xff0c;保持水印在图片中的大小和位置 4&#xff0c;处理…