视频实时行为检测——基于yolov5+deepsort+slowfast算法


前言

前段时间打算做一个目标行为检测的项目,翻阅了大量资料,也借鉴了不少项目,于是打算通过yolov5实现目标检测,deepsort实现目标跟踪以及slowfast实现动作识别,最终实现端到端的目标行为检测模型。

一、核心功能设计

总的来说,我们需要能够实现实时检测视频中的人物,并且能够识别目标的动作,所以我们拆解需求后,整理核心功能如下所示:

  1. yolov5实现目标检测,确定目标坐标
  2. deepsort实现目标跟踪,持续标注目标坐标
  3. slowfast实现动作识别,并给出置信率
  4. 用框持续框住目标,并将动作类别以及置信度显示在框上

最终效果如下所示:

视频AI行为检测

二、核心实现步骤

1.yolov5实现目标检测

“YOLO”是一种运行速度很快的目标检测AI模型,YOLO将对象检测重新定义为一个回归问题。它将单个卷积神经网络(CNN)应用于整个图像,将图像分成网格,并预测每个网格的类概率和边界框。YOLO非常快,它比“R-CNN”快1000倍,比“Fast R-CNN”快100倍。YOLOv5是YOLO比较新的一个版本。
所以我们把视频分解成多幅图像,并利用yolov5算法进行目标检测并逐帧执行时,可以看到目标跟踪框随目标移动。

效果如下所示:

在这里插入图片描述

2.deepsort实现目标跟踪

但是,如果视频帧中有多个目标,如何知道一帧中的目标和上一帧是同一个对象?这就是目标跟踪的工作,应用多个检测来识别特定目标随时间的变化,实现目标跟踪。
Deepsort是实现目标跟踪的算法,从sort(simple online and realtime tracking)演变而来,其使用卡尔曼滤波器预测所检测对象的运动轨迹,匈牙利算法将它们与新的检测目标相匹配。Deepsort易于使用且运行速度快,成为AI目标检测跟踪之热门算法。

首先来看一下DeepSORT的核心流程:
预测(track)——>观测(detection+数据关联)——>更新

  • 预测:预测下一帧的目标的bbox,即后文中的tracks
  • 观测:对当前帧进行目标检测,仅仅检测出目标并不能与上一帧的目标对应起来,所以还要进行数据关联
  • 更新:预测Bbox和检测Bbox都会有误差,所以进行更新,更新后的跟踪结果通常比单纯预测或者单纯检测的误差小很多。

    在这里插入图片描述

3.slowfast动作识别

我们将视频序列和检测框信息输入行为分类模型,输出每个检测框的行为类别,达到行为检测的目的。
而行为分类模型我们采用的是slowfast算法,其包括一个Slow路径,以低帧速率操作,以捕捉空间语义,以及一个Fast路径,以高帧速率操作,以精细的时间分辨率捕捉运动。快速路径可以通过减少信道容量而变得非常轻量级,同时还可以学习有用的时间信息用于视频识别。

在这里插入图片描述

三、核心代码解析

1.参数

if __name__=="__main__":
    parser = argparse.ArgumentParser()
    parser.add_argument('--input', type=str, default="test/test1.mp4", help='test imgs folder or video or camera')
    parser.add_argument('--output', default="output/out1.mp4", help='folder to save result imgs,can not use input folder')
    # object detect config
    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', help='IOU threshold for NMS')
    parser.add_argument('--device', default=0, help='cuda device,i.e. 0 or 0,1,2,3 or cpu')
    parser.add_argument('--classes',nargs='+', help='filter by class: --class 0,or --class 0 2 3')
    config = parser.parse_args()
    
    print(config)
    main(config)

从__main__开始分析,设置了输入输出参数以及目标检测的一些参数,包括输入路径、输出路径、尺寸大小、置信度、iou值、以及目标检测的类别,其中0是人。

2.主函数

对输入的config参数解析并使用,模型使用yolov5l6,权重下载到本地

    model = torch.hub.load('ultralytics/yolov5', 'yolov5l6') #加载yolov5模型
    model.conf = config.conf
    model.iou = config.iou
    model.max_det = 200
    model.classes = config.classes
    device = config.device
    imsize = config.imsize
    video_model = slowfast_r50_detection(True).eval().to(device) #加载slowfast_r50_detection模型
    # video_model = slowfast_r50_detection(False).eval().to(device)
    # video_model.load_state_dict(torch.load("SLOWFAST_8x8_R50_DETECTION.pyth")['model_state'])

加载Slowfast、Deepsort模型,使用的Slowfast是在AVA2.2上训练的,通过AvaLabeledVideoFramePaths函数获得id到动作的mapping

    deepsort_tracker = DeepSort("deep_sort/deep_sort/deep/checkpoint/ckpt.t7") #加载DeepSort模型
    ava_labelnames,_ = AvaLabeledVideoFramePaths.read_label_map("selfutils/temp.pbtxt") #加载类别标签
    ava_labelnames_abnormal,_ = AvaLabeledVideoFramePaths.read_label_map("selfutils/ava_action_abnormal.pbtxt") #加载类别标签

    coco_color_map = [[random.randint(0, 255) for _ in range(3)] for _ in range(80)]

读取视频和载入视频

    vide_save_path = config.output
    video=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...")
    
    video = pytorchvideo.data.encoded_video.EncodedVideo.from_path(config.input) # 载入视频

首先对视频进行抽帧处理,通过get_clip()对一秒内的视频进行抽帧,只保留视频图片,将tensor转numpy数组,BGR格式

    a=time.time()
    for i in range(0,math.ceil(video.duration),1): #截视频
        video_clips=video.get_clip(i, i+1-0.04)
        video_clips=video_clips['video']
        if video_clips is None:
            continue
        img_num=video_clips.shape[1]
        imgs=[]
        for j in range(img_num):
            imgs.append(tensor_to_numpy(video_clips[:,j,:,:]))
            # "video": A tensor of the clip's RGB frames with shape: (channel,time,height,width).
        	# 将tensor转为numpy数组,BGR格式

通过yolov5网络进行目标检测

        yolo_preds=model(imgs, size=imsize)
        # 每25帧后插入1帧作为预测图像
        yolo_preds.files=[f"img_{i*25+k}.jpg" for k in range(img_num)]
        print(i,video_clips.shape,img_num)

使用预训练的Deepsort权重,以yolo预测结果作为输入,用Deepsort的结果代替yolo预测的结果,这里Deepsort是用来给相同id的目标分配动作label的。

        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.imgs[j])
            if len(temp)==0:
                temp=np.ones((0,8))
            deepsort_outputs.append(temp.astype(np.float32))
        yolo_preds.pred=deepsort_outputs

通过ava_inference_transform()函数对预测输入进行预处理,然后通过调用Slowfast模型进行预测,最后为每个id分配动作类别

        id_to_ava_labels={}
        if yolo_preds.pred[img_num//2].shape[0]:
            inputs,inp_boxes,_=ava_inference_transform(video_clips,yolo_preds.pred[img_num//2][:,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,avapred in zip(yolo_preds.pred[img_num//2][:,5].tolist(),np.argmax(slowfaster_preds,axis=1).tolist(),torch.max(slowfaster_preds,axis=1).values.tolist()):
                # if(avalabel in ava_labelnames_abnormal):
                    # id_to_ava_labels[tid]=ava_labelnames[avalabel+1]+'_abnormal'
                id_to_ava_labels[tid]=[ava_labelnames[avalabel+1],avapred]            # print(avalabel)

        # print(avalabel)
        # print(ava_labelnames[avalabel+1])
        if((avalabel+1) in ava_labelnames_abnormal):
            isnormal=False
        else:
            isnormal=True
        save_yolopreds_tovideo(yolo_preds,id_to_ava_labels,coco_color_map,outputvideo,isnormal)
    print("total cost: {:.3f}s,video clips length: {}s".format(time.time()-a,video.duration))
        
    outputvideo.release()
    print('saved video to:', vide_save_path)

3.将结果保存成视频

def save_yolopreds_tovideo(yolo_preds,color_map,output_video,isnormal):
    for i, (im, pred) in enumerate(zip(yolo_preds.imgs, yolo_preds.pred)):
        im=cv2.cvtColor(im,cv2.COLOR_BGR2RGB)
        if pred.shape[0]:
            for j, (*box, cls, trackid, vx, vy) in enumerate(pred):
                if int(cls) != 0:
                    ava_label = ''
                    ava_pred=0.0

                elif trackid in id_to_ava_labels.keys():
                    ava_label = id_to_ava_labels[trackid][0].split(' ')[0]
                    ava_pred=id_to_ava_labels[trackid][1]
                else:
                    ava_label = 'Unknow'
                    ava_pred=0.0

                if(isnormal):
                    text = '{:.4f} {} {}'.format(ava_pred,yolo_preds.names[int(cls)],ava_label)
                    color = [40,113,62]
                else:
                    text = '{:.4f} {} {} {}'.format(ava_pred,ava_label,'abnormal')
                    color = [43,44,124]

                # print(cls)
                im = plot_one_box(box,im,color,text)
        output_video.write(im.astype(np.uint8))

总结

基于yolov5+deepsort+slowfast算法的视频实时行为检测就介绍到这里了!!!
如果该文章对您有所帮助,麻烦点赞,关注,收藏三连支持下!
创作不易,白嫖不好,各位的支持和认可,是我创作的最大动力!
如果本篇博客有任何错误,请批评指教,不胜感激 !!!


参考
Yolov5+SlowFast: 基于PytorchVideo的实时行为检测算法
YOLOv5算法详解
pytorch yolo5+Deepsort实现目标检测和跟踪
Yolov5+Deepsort+Slowfast实现实时动作检测

原文地址:https://yunlord.blog.csdn.net" target="_blank" rel="noopener" title="Yunlord">Yunlord</a> <img class="article-time-img article-heard-img" src="https://csdnimg.cn/release/blogv2/di

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


软件简介:蓝湖辅助工具,减少移动端开发中控件属性的复制和粘贴.待开发的功能:1.支持自动生成约束2.开发设置页面3.做一个浏览器插件,支持不需要下载整个工程,可即时操作当前蓝湖浏览页面4.支持Flutter语言模板生成5.支持更多平台,如Sketch等6.支持用户自定义语言模板
现实生活中,我们听到的声音都是时间连续的,我们称为这种信号叫模拟信号。模拟信号需要进行数字化以后才能在计算机中使用。目前我们在计算机上进行音频播放都需要依赖于音频文件。那么音频文件如何生成的呢?音频文件的生成过程是将声音信息采样、量化和编码产生的数字信号的过程,我们人耳所能听到的声音频率范围为(20Hz~20KHz),因此音频文件格式的最大带宽是20KHZ。根据奈奎斯特的理论,音频文件的采样率一般在40~50KHZ之间。奈奎斯特采样定律,又称香农采样定律。...............
前言最近在B站上看到一个漂亮的仙女姐姐跳舞视频,循环看了亿遍又亿遍,久久不能离开!看着小仙紫姐姐的蹦迪视频,除了一键三连还能做什么?突发奇想,能不能把舞蹈视频转成代码舞呢?说干就干,今天就手把手教大家如何把跳舞视频转成代码舞,跟着仙女姐姐一起蹦起来~视频来源:【紫颜】见过仙女蹦迪吗 【千盏】一、核心功能设计总体来说,我们需要分为以下几步完成:从B站上把小姐姐的视频下载下来对视频进行截取GIF,把截取的GIF通过ASCII Animator进行ASCII字符转换把转换的字符gif根据每
【Android App】实战项目之仿抖音的短视频分享App(附源码和演示视频 超详细必看)
前言这一篇博客应该是我花时间最多的一次了,从2022年1月底至2022年4月底。我已经将这篇博客的内容写为论文,上传至arxiv:https://arxiv.org/pdf/2204.10160.pdf欢迎大家指出我论文中的问题,特别是语法与用词问题在github上,我也上传了完整的项目:https://github.com/Whiffe/Custom-ava-dataset_Custom-Spatio-Temporally-Action-Video-Dataset关于自定义ava数据集,也是后台
因为我既对接过session、cookie,也对接过JWT,今年因为工作需要也对接了gtoken的2个版本,对这方面的理解还算深入。尤其是看到官方文档评论区又小伙伴表示看不懂,所以做了这期视频内容出来:视频在这里:本期内容对应B站的开源视频因为涉及的知识点比较多,视频内容比较长。如果你觉得看视频浪费时间,可以直接阅读源码:goframe v2版本集成gtokengoframe v1版本集成gtokengoframe v2版本集成jwtgoframe v2版本session登录官方调用示例文档jwt和sess
【Android App】实战项目之仿微信的私信和群聊App(附源码和演示视频 超详细必看)
用Android Studio的VideoView组件实现简单的本地视频播放器。本文将讲解如何使用Android视频播放器VideoView组件来播放本地视频和网络视频,实现起来还是比较简单的。VideoView组件的作用与ImageView类似,只是ImageView用于显示图片,VideoView用于播放视频。...
采用MATLAB对正弦信号,语音信号进行生成、采样和内插恢复,利用MATLAB工具箱对混杂噪声的音频信号进行滤波
随着移动互联网、云端存储等技术的快速发展,包含丰富信息的音频数据呈现几何级速率增长。这些海量数据在为人工分析带来困难的同时,也为音频认知、创新学习研究提供了数据基础。在本节中,我们通过构建生成模型来生成音频序列文件,从而进一步加深对序列数据处理问题的了解。
基于yolov5+deepsort+slowfast算法的视频实时行为检测。1. yolov5实现目标检测,确定目标坐标 2. deepsort实现目标跟踪,持续标注目标坐标 3. slowfast实现动作识别,并给出置信率 4. 用框持续框住目标,并将动作类别以及置信度显示在框上
数字电子钟设计本文主要完成数字电子钟的以下功能1、计时功能(24小时)2、秒表功能(一个按键实现开始暂停,另一个按键实现清零功能)3、闹钟功能(设置闹钟以及到时响10秒)4、校时功能5、其他功能(清零、加速、星期、八位数码管显示等)前排提示:前面几篇文章介绍过的内容就不详细介绍了,可以看我专栏的前几篇文章。PS.工程文件放在最后面总体设计本次设计主要是在前一篇文章 数字电子钟基本功能的实现 的基础上改编而成的,主要结构不变,分频器将50MHz分为较低的频率备用;dig_select
1.进入官网下载OBS stdioOpen Broadcaster Software | OBS (obsproject.com)2.下载一个插件,拓展OBS的虚拟摄像头功能链接:OBS 虚拟摄像头插件.zip_免费高速下载|百度网盘-分享无限制 (baidu.com)提取码:6656--来自百度网盘超级会员V1的分享**注意**该插件必须下载但OBS的根目录(应该是自动匹配了的)3.打开OBS,选中虚拟摄像头选择启用在底部添加一段视频录制选择下面,进行录制.
Meta公司在9月29日首次推出一款人工智能系统模型:Make-A-Video,可以从给定的文字提示生成短视频。基于**文本到图像生成技术的最新进展**,该技术旨在实现文本到视频的生成,可以仅用几个单词或几行文本生成异想天开、独一无二的视频,将无限的想象力带入生活
音频信号叠加噪声及滤波一、前言二、信号分析及加噪三、滤波去噪四、总结一、前言之前一直对硬件上的内容比较关注,但是可能是因为硬件方面的东西可能真的是比较杂,而且需要渗透的东西太多了,所以学习进展比较缓慢。因为也很少有单纯的硬件学习研究,总是会伴随着各种理论需要硬件做支撑,所以还是想要慢慢接触理论学习。但是之前总找不到切入点,不知道从哪里开始,就一直拖着。最近稍微接触了一点信号处理,就用这个当作切入点,开始接触理论学习。二、信号分析及加噪信号处理选用了matlab做工具,选了一个最简单的语音信号处理方
腾讯云 TRTC 实时音视频服务体验,从认识 TRTC 到 TRTC 的开发实践,Demo 演示& IM 服务搭建。
音乐音频分类技术能够基于音乐内容为音乐添加类别标签,在音乐资源的高效组织、检索和推荐等相关方面的研究和应用具有重要意义。传统的音乐分类方法大量使用了人工设计的声学特征,特征的设计需要音乐领域的知识,不同分类任务的特征往往并不通用。深度学习的出现给更好地解决音乐分类问题提供了新的思路,本文对基于深度学习的音乐音频分类方法进行了研究。首先将音乐的音频信号转换成声谱作为统一表示,避免了手工选取特征存在的问题,然后基于一维卷积构建了一种音乐分类模型。
C++知识精讲16 | 井字棋游戏(配资源+视频)【赋源码,双人对战】
本文主要讲解如何在Java中,使用FFmpeg进行视频的帧读取,并最终合并成Gif动态图。
在本篇博文中,我们谈及了 Swift 中 some、any 关键字以及主关联类型(primary associated types)的前世今生,并由浅及深用简明的示例向大家讲解了它们之间的奥秘玄机。