行人实时动作识别

  • 详细资料和代码请加微信:17324069443

一、项目介绍

基于PyTorchVideo的实时动作识别框架:
我们选择了yolov5作为目标检测器,而不是Faster R-CNN,它速度更快、更方便。
我们使用一个跟踪器(deepsort)来为不同帧中所有具有相同ID的对象分配动作标签。
行为识别使用 slowfast算法,根据前后帧的图片,分析这个序列,来判断是做了什么动作
我们在单个RTX 2080Ti GPU上以30个推理批处理大小达到了24.2 FPS的处理速度。
在这里插入图片描述

二、算法介绍

2.1 yolov5目标检测

YOLOv5是一种基于深度学习的目标检测算法,它在目标检测和图像识别领域具有很高的性能。YOLOv5建立在先前版本(如YOLOv3和YOLOv4)的基础上,通过引入一系列改进来提高检测准确性和速度。
YOLOv5的核心架构是基于单阶段目标检测器(one-stage detector)。与传统的两阶段方法不同,YOLOv5通过单个神经网络模型直接从图像中预测目标的类别和边界框位置。这使得YOLOv5在速度和准确性之间取得了良好的平衡,适用于许多实时应用场景。
YOLOv5的主要特点和优势包括:

  • 轻量化设计
  • 多尺度检测
  • 自动数据增强
  • 简单易用

YOLOv5在许多基准数据集上取得了优秀的检测性能,并且被广泛应用于实际场景中,包括智能监控、自动驾驶、工业检测等领域。其高性能和灵活性使得YOLOv5成为目标检测领域的热门选择之一。

2.2 DeepSort目标跟踪

DeepSort是一种基于深度学习的目标跟踪算法,旨在解决多目标跟踪问题。它结合了目标检测和目标跟踪两个关键任务,能够在视频序列中准确地追踪多个目标并分配唯一的ID。
DeepSort算法的核心思想是将卷积神经网络(CNN)用于目标检测,以便识别视频帧中的目标,并结合深度学习技术来进行目标特征提取和关联。具体来说,DeepSort首先使用一个预训练的目标检测器(如YOLO或Faster R-CNN)来检测视频帧中的目标,并提取目标的特征表示。
接着,DeepSort利用深度学习模型(通常是基于Siamese网络或类似的架构)来计算不同目标之间的相似度,并根据目标之间的特征相似性来进行目标关联。通过在时间序列中跟踪目标的位置,并根据目标的外观和运动特征来更新目标的状态,DeepSort能够有效地处理目标在视频中的出现、消失和遮挡等情况,实现稳健的多目标跟踪。
DeepSort算法在目标跟踪领域取得了显著的成果,特别是在具有复杂背景和目标重叠的场景下表现突出。它在许多跟踪竞赛和实际应用中都取得了优异的性能,成为目标跟踪领域的重要算法之一。深度学习方法的引入使得DeepSort在目标跟踪任务中更加准确、高效,并且具有良好的通用性和可扩展性。

2.3 slowfast动作识别

SlowFast是一种用于视频动作识别的深度学习算法。它是在Facebook AI研究团队提出的基础上发展而来的,旨在解决传统的单帧或连续帧方法在动作识别任务中存在的困难。
SlowFast算法的核心思想是引入两个不同速度的流来处理视频数据:慢速流(Slow)和快速流(Fast)。慢速流用于捕捉视频中的空间细节,它对每个帧进行较高的时间采样,以更好地理解运动的细节。快速流则用于捕捉动作的快速变化,它对每个帧进行较低的时间采样,以更好地捕捉动作的整体动态。
具体实现上,SlowFast网络由两个并行的卷积神经网络流组成:慢速流和快速流。慢速流通常包含较多的卷积层和较大的时间步长,以便对空间细节进行更深入的分析。而快速流则包含较少的卷积层和较小的时间步长,以便对动作的快速变化进行快速响应。
在训练过程中,SlowFast网络通过使用慢速流和快速流来学习视频的空间和时间特征,以及它们之间的关系。通过在大规模视频数据集上进行训练,SlowFast网络能够学习到通用的动作表示,从而在动作识别任务中取得良好的性能。
SlowFast算法在视频动作识别领域表现出色,其能够有效地捕捉视频中的空间和时间信息,并且在处理速度和准确率之间取得了良好的平衡。它在许多视频动作识别的挑战中取得了领先的结果,并被广泛应用于视频分析、智能监控等领域。

三、代码实现

def tensor_to_numpy(tensor):
    img = tensor.cpu().numpy().transpose((1, 2, 0))
    return img

def 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.0
    height, 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 = clip
        slow_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_boxes

def plot_one_box(x, img, color=[100,100,100], text_info="None",
                 velocity=None,thickness=1,fontsize=0.5,fontthickness=1):
    # Plots one bounding box on image img
    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 img

def 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 outputs

def save_yolopreds_tovideo(yolo_preds,id_to_ava_labels,color_map,output_video):
    for i, (im, pred) in enumerate(zip(yolo_preds.ims, 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 = ''
                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)
        output_video.write(im.astype(np.uint8))

def main(config):
    model = torch.hub.load('ultralytics/yolov5', 'yolov5l6')
    model.conf = config.conf
    model.iou = config.iou
    model.max_det = 200
    if config.classes:
        model.classes = config.classes
    device = config.device
    imsize = config.imsize
    video_model = slowfast_r50_detection(True).eval().to(device)
    deepsort_tracker = DeepSort("data/models/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.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)
    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,:,:]))
        yolo_preds=model(imgs, size=imsize)
        yolo_preds.files=[f"img_{i*25+k}.jpg" for k in range(img_num)]

        print(i,video_clips.shape,img_num)
        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_outputs
        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 in zip(yolo_preds.pred[img_num//2][:,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)
    print("total cost: {:.3f}s, video clips length: {}s".format(time.time()-a,video.duration))
    outputvideo.release()
    print('saved video to:', vide_save_path)
    
    
if __name__=="__main__":
    parser = argparse.ArgumentParser()
    parser.add_argument('--input', type=str, default="data/1.mov", help='test imgs folder or video or camera')
    parser.add_argument('--output', type=str, default="data/output.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', type=float, default=0.4, help='IOU threshold for NMS')
    parser.add_argument('--device', default='cpu', 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')
    config = parser.parse_args()
    print(config)
    main(config)

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

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

相关文章

STM32CubeIDE基础学习-安装芯片固件支持包

STM32CubeIDE基础学习-添加芯片固件支持包 前言 前面的文章在安装STM32CubeIDE软件时没有安装这个芯片PACK包,如果工程没有这个固件支持包的话是无法正常使用的,随便安装一个和芯片对应系列的支持包就可以了。 这篇文章来记录一下新增PACK包的常用操作…

【Docker】Windows11操作系统下安装、使用Docker保姆级教程

【Docker】Windows11操作系统下安装、使用Docker保姆级教程 大家好 我是寸铁👊 总结了一篇【Docker】Windows11操作系统下安装、使用Docker保姆级教程的文章✨ 喜欢的小伙伴可以点点关注 💝 前言 什么是 Docker? Docker 是一个开源平台&…

【优选算法】前缀和

前缀和思想其实就是一种简单的dp思想,也就是动态规划 什么时候用到前缀和?当要快速求出数组中某一个区间的和 前缀和模板 暴力解法 定义一个指针从左向右遍历,并且累加值即可,这里就不过多赘述,主要还是来看前缀和…

缓存雪崩、击穿、穿透

目录 前言 一、缓存雪崩 1.大量数据同时过期 1.均匀设置过期时间 2.互斥锁 3.后台更新缓存 2.Redis故障宕机 1.服务熔断或请求限流机制 2.构建Redis缓存高可靠集群 二、缓存击穿 1.设置互斥锁; 2.不给热点数据设置过期时间,由后台更新缓存。 …

可行性研究报告-范例直接套用

1业务需求可行性分析 2技术可行性分析 2.1规范化原则 2.2高度的兼容性和可移植性 2.3人性化、适用性 2.4标准化统一设计原则 2.5先进安全可扩展性原则 3开发周期可行性分析 4人力资源可行性分析 5成本分析 6收益分析 7结论 软件开发多套实际项目案例、方案、源码获取&#xff1…

使用API有效率地管理Dynadot域名,进行DNS域名解析

关于Dynadot Dynadot是通过ICANN认证的域名注册商,自2002年成立以来,服务于全球108个国家和地区的客户,为数以万计的客户提供简洁,优惠,安全的域名注册以及管理服务。 Dynadot平台操作教程索引(包括域名邮…

nodejs,JSDOM 补 window环境

window[atob] 是一个在浏览器中使用的 JavaScript 函数,用于将 base64 编码的字符串解码为原始数据。具体来说,atob 函数会将 base64 字符串解码为一个 DOMString,其中包含解码后的二进制数据。这在处理从服务器获取的 base64 编码的数据或在…

RedisDesktopManager连接Ubuntu的Redis失败解决办法

配置redis 1.设置redis在后台服务,修改配置文件 默认情况下是 no ,修改为yes,可以后台服务 2、设置redis端口,默认端口是6379,可以根据自己的需要,找到/et/redis/redis.conf文件, 修改port 3、设置密码 配置文件中…

基于pytorch的手写体识别

一、环境搭建 链接: python与深度学习——基础环境搭建 二、数据集准备 本次实验用的是MINIST数据集,利用MINIST数据集进行卷积神经网络的学习,就类似于学习单片机的点灯实验,学习一门机器语言输出hello world。MINIST数据集,可以…

【书籍推广】这本书太好了!150页就能让你上手大模型应用开发

文章目录 蛇尾书特色蛇尾书思维导图作译者简介业内专家书评 如果问个问题:有哪些产品曾经创造了伟大的奇迹?ChatGPT 应该会当之无愧入选。仅仅发布 5 天,ChatGPT 就吸引了 100 万用户——当然,数据不是关键,关键是其背…

【Unity】VR开发的正确测试节奏

【背景】 VR开发由于其测试时对设备的依赖较大,因此有时在没有测试条件时想当然地写了大量代码,一旦到正式测试时需要debug,往往无法判断到底是哪个环节的问题(代码,环境,等等)。相对于PC平台的…

AI预测福彩3D第2弹【2024年3月5日预测】

书接上回,首先声明下,写这一系列文章的目的不为别的,就是想看下到底使用一些强大的AI算法能不能挖掘出彩票的规律,毕竟彩票的规律太乱,不是说没有规律,而是规律太多。经过上一篇文章的图片,大家…

git使用教程14-Pycharm版本控制与分支管理

一、版本控制 1、版本控制介绍 (1)Version Control System 版本控制系统,简称VCS。 (2)版本控制系统分类: 集中式版本控制工具:SVN 分布式版本控制工具:Git 2、Pycharm 支持的版本…

C++:Vector的使用

一、vector的介绍 vector的文档介绍 1. vector是表示可变大小数组的序列容器。 2. 就像数组一样,vector也采用的连续存储空间来存储元素。也就是意味着可以采用下标对vector的元素进行访问,和数组一样高效。但是又不像数组,它的大小是可以…

全链路监控

1. 全链路监控的兴起与发展 当代的互联网的服务,通常都是用复杂的、大规模分布式集群来实现的。互联网应用构建在不同的软件模块集上,这些软件模块,有可能是由不同的团队开发、可能使用不同的编程语言来实现、有可能布在了几千台服务器&…

CentOS 7操作系统安装教程

CentOS 7操作系统安装教程 CentOS 7是一款功能强大、稳定可靠的操作系统,适用于服务器、桌面等多种场景。下面将介绍CentOS 7的安装教程。 准备工作 下载CentOS 7镜像文件:https://mirrors.tuna.tsinghua.edu.cn/centos/7/isos/x86_64/准备安装介质&am…

【新书推荐】13.2 应用举例

本节内容:磁盘文件管理功能号调用应用举例。 ■例1:显示文本文件内容t13-1.asm。 ■例2:将键盘输入字符存入文件t13-2.asm。 ■例3:文件拼接t13-3.asm。 13.2.1 例1:显示文本文件内容 动手实验93:写一个…

Centos 9 安装 k8s

为了尽可能契合生产环境的部署情况,这里用kubeadm安装集群,同时方便跟随笔记一步步实践的过程,也更加了解k8s的一些特性和基础知识。 先决条件 这里将通过虚拟机安装3台centos stream 9服务器,并组成kubeneters集群(…

如何在MinIO系统中进行配置并结合内网穿透实现公网远程连接上传文件

文章目录 前言1. 创建Buckets和Access Keys2. Linux 安装Cpolar3. 创建连接MinIO服务公网地址4. 远程调用MinIO服务小结5. 固定连接TCP公网地址6. 固定地址连接测试 前言 MinIO是一款高性能、分布式的对象存储系统,它可以100%的运行在标准硬件上,即X86等…

ROS2中std_msgs/msg/Header 数据含义及使用

ROS2中std_msgs/msg/Headerr 数据含义及使用 ROS官方消息说明数据说明使用ros2标准的Header案例代码解释测试结果 ROS官方消息说明 ROS2中std_msgs消息包含类型 https://docs.ros2.org/latest/api/std_msgs/msg/std_msgs/msg/Header Message std_msgs/msg/Header数据格式&…