视频目标检测 yolov

目录

 yolov相关介绍

预训练是检测动物世界的动物的,1060显卡单帧需要300毫秒


 yolov相关介绍

论文地址: https://arxiv.org/pdf/2208.09686.pdf

代码地址: https://github.com/YuHengsss/YOLOV

ModelsizemAP@50valSpeed 2080Ti(batch size=1)
(ms)
weights
YOLOX-s57669.59.4google
YOLOX-l57676.114.8google
YOLOX-x57677.820.4google
YOLOV-s57677.311.3google
YOLOV-l57683.616.4google
YOLOV-x57685.522.7google
YOLOV-x + post57687.5-

视频目标检测(VID)具有挑战性,因为目标外观的高度变化以及某些帧中的各种劣化。积极的一面是,与静止图像相比,在视频的某一帧中进行检测可以得到其他帧的支持。因此,如何跨不同帧聚合特征是VID问题的关键。

大多数现有的聚合算法都是为两阶段检测器定制的。但是,由于两阶段的性质,此类检测器通常在计算上很耗时。今天分享的研究者提出了一种简单而有效的策略来解决上述问题,该策略花费了边际开销,并显著提高了准确性。具体来说,与传统的两阶段流水线不同,研究者主张将区域级候选放在一阶段检测之后,以避免处理大量低质量候选。此外,构建了一个新的模块来评估目标框架与其参考框架之间的关系,并指导聚合。

进行了广泛的实验和消融研究以验证新提出设计的有效性,并揭示其在有效性和效率方面优于其他最先进的VID方法。基于YOLOX的模型可以实现可观的性能(例如,在单个2080Ti GPU上的ImageNet VID数据集上以超过30 FPS的速度达到87.5% AP50),使其对大规模或实时应用程序具有吸引力。

视频目标检测可以看作是静止图像目标检测的高级版本。直观地说,可以通过将帧一一输入静止图像目标检测器来处理视频序列。但是,通过这种方式,跨帧的时间信息将被浪费,这可能是消除/减少单个图像中发生的歧义的关键。

如上图所示,视频帧中经常出现运动模糊、相机散焦和遮挡等退化,显着增加了检测的难度。例如,仅通过查看上图中的最后一帧,人类很难甚至不可能分辨出物体在哪里和是什么。另一方面,视频序列可以提供比单个静止图像更丰富的信息。换言之,同一序列中的其他帧可能支持对某一帧的预测。因此,如何有效地聚合来自不同帧的时间消息对于准确性至关重要。从上图可以看出,研究者提出的方法给出了正确的答案。

03

新框架

考虑到视频的特性(各种退化与丰富的时间信息),而不是单独处理帧,如何从其他帧中为目标帧(关键帧)寻求支持信息对于提高视频检测的准确性起着关键作用。最近的尝试是在准确性上的显着提高证实了时间聚合对问题的重要性。然而,大多数现有方法都是基于两阶段的技术。

如前所述,与一级基础相比,它们的主要缺点是推理速度相对较慢。为了减轻这种限制,研究者将区域/特征选择放在单级检测器的预测头之后。

图片

研究者选择YOLOX作为基础来展示研究者的主要主张。提出的框架如上图所示。

让我们回顾一下传统的两阶段管道:

1)首先“选择”大量候选区域作为提议; 

2)确定每个提议是否是一个目标以及它属于哪个类。计算瓶颈主要来自于处理大量的低置信区域候选。

从上图可以看出,提出的框架也包含两个阶段。不同的是,它的第一阶段是预测(丢弃大量低置信度的区域),而第二阶段可以被视为区域级细化(通过聚合利用其他帧)。

通过这一原则,新的设计可以同时受益于一级检测器的效率和从时间聚合中获得的准确性。值得强调的是,如此微小的设计差异会导致性能上的巨大差异。所提出的策略可以推广到许多基础检测器,例如YOLOX、FCOS和PPYOLOE。

图片

此外,考虑到softmax的特性,可能一小部分参考特征持有大部分权重。换句话说,它经常忽略低权重的特征,这限制了可能后续使用的参考特征的多样性。

为了避免这种风险,研究者引入了平均池化参考特征(A.P.)。具体来说,选择相似度得分高于阈值τ的所有参考,并将平均池化应用于这些。请注意,这项工作中的相似性是通过N (Vc)N(Vc)T计算的。算子N(·)表示层归一化,保证值在一定范围内,从而消除尺度差异的影响。通过这样做,可以维护来自相关特征的更多信息。然后将平均池化特征和关键特征传输到一个线性投影层中进行最终分类。该过程如是上图所示。

有人可能会问,N(Qc)N(Kc)T或N(Qr)N(Kr)T是否可以作为相似度执行。事实上,这是另一种选择。但是,在实践中,由于Q和K之间的差异,它不像我们在训练期间的选择那样稳定。

预训练是检测动物世界的动物的,1060显卡单帧需要300毫秒

视频预测代码:

#!/usr/bin/env python3
# -*- coding:utf-8 -*-
# Copyright (c) Megvii, Inc. and its affiliates.

import argparse
import os
import time
from loguru import logger

import cv2

import torch

from yolox.data.data_augment import ValTransform
from yolox.data.datasets import COCO_CLASSES
from yolox.data.datasets.vid_classes import VID_classes
# from yolox.data.datasets.vid_classes import OVIS_classes as VID_classes
from yolox.exp import get_exp
from yolox.utils import fuse_model, get_model_info, postprocess, vis
import random

IMAGE_EXT = [".jpg", ".jpeg", ".webp", ".bmp", ".png"]


def make_parser():
    parser = argparse.ArgumentParser("YOLOX Demo!")
    # parser.add_argument(
    #     "demo", default="video", help="demo type, eg. image, video and webcam"
    # )
    parser.add_argument("-expn", "--experiment_name", type=str, default=None)
    parser.add_argument("-n", "--name", type=str, default=None, help="model name")

    parser.add_argument("--path", default=r"C:\Users\Administrator\Videos\f7.mp4", help="path to images or video")

    parser.add_argument("--camid", type=int, default=0, help="webcam demo camera id")

    # exp file
    parser.add_argument("-f", "--exp_file", default='../exps/yolov/yolov_s.py', type=str, help="pls input your expriment description file", )
    parser.add_argument("-c", "--ckpt", default='../yolov_s.pth', type=str, help="ckpt for eval")
    # parser.add_argument("-c", "--ckpt", default='../yoloxs_vid.pth', type=str, help="ckpt for eval")
    parser.add_argument("--device", default="gpu", type=str, help="device to run our model, can either be cpu or gpu", )
    parser.add_argument("--dataset", default='vid', type=str, help="Decide pred classes")
    parser.add_argument("--conf", default=0.05, type=float, help="test conf")
    parser.add_argument("--nms", default=0.5, type=float, help="test nms threshold")
    parser.add_argument("--tsize", default=576, type=int, help="test img size")
    parser.add_argument("--fp16", dest="fp16", default=True, action="store_true", help="Adopting mix precision evaluating.", )
    parser.add_argument("--legacy", dest="legacy", default=False, action="store_true", help="To be compatible with older versions", )
    parser.add_argument("--fuse", dest="fuse", default=False, action="store_true", help="Fuse conv and bn for testing.", )
    parser.add_argument("--trt", dest="trt", default=False, action="store_true", help="Using TensorRT model for testing.", )
    parser.add_argument('--output_dir', default='out', help='path where to save, empty for no saving')
    parser.add_argument('--gframe', default=32, help='global frame num')
    parser.add_argument('--save_result', default=True)
    return parser


def get_image_list(path):
    image_names = []
    for maindir, subdir, file_name_list in os.walk(path):
        for filename in file_name_list:
            apath = os.path.join(maindir, filename)
            ext = os.path.splitext(apath)[1]
            if ext in IMAGE_EXT:
                image_names.append(apath)
    return image_names


class Predictor(object):
    def __init__(self, model, exp, cls_names=COCO_CLASSES, trt_file=None, decoder=None, device="cpu", legacy=False, ):
        self.model = model
        self.cls_names = cls_names
        self.decoder = decoder
        self.num_classes = exp.num_classes
        self.confthre = exp.test_conf
        self.nmsthre = exp.nmsthre
        self.test_size = exp.test_size
        self.device = device
        self.preproc = ValTransform(legacy=legacy)
        self.model = model.half()

    def inference(self, img, img_path=None):
        tensor_type = torch.cuda.HalfTensor
        if self.device == "gpu":
            img = img.cuda()
            img = img.type(tensor_type)
        with torch.no_grad():
            t0 = time.time()
            outputs, outputs_ori = self.model(img, nms_thresh=self.nmsthre)
            logger.info("Infer time: {:.4f}s".format(time.time() - t0))
        return outputs

    def visual(self, output, img, ratio, cls_conf=0.0):

        if output is None:
            return img
        bboxes = output[:, 0:4]

        # preprocessing: resize
        bboxes /= ratio

        cls = output[:, 6]
        scores = output[:, 4] * output[:, 5]

        vis_res = vis(img, bboxes, scores, cls, cls_conf, self.cls_names)
        return vis_res


def image_demo(predictor, vis_folder, path, current_time, save_result):
    if os.path.isdir(path):
        files = get_image_list(path)
    else:
        files = [path]
    files.sort()
    for image_name in files:
        outputs, img_info = predictor.inference(image_name, [image_name])
        result_image = predictor.visual(outputs[0], img_info, predictor.confthre)
        if save_result:
            save_folder = os.path.join(vis_folder, time.strftime("%Y_%m_%d_%H_%M_%S", current_time))
            os.makedirs(save_folder, exist_ok=True)
            save_file_name = os.path.join(save_folder, os.path.basename(image_name))
            logger.info("Saving detection result in {}".format(save_file_name))
            cv2.imwrite(save_file_name, result_image)
        ch = cv2.waitKey(0)
        if ch == 27 or ch == ord("q") or ch == ord("Q"):
            break


def imageflow_demo(predictor, vis_folder, current_time, args):
    gframe = args.gframe
    cap = cv2.VideoCapture(args.path)
    width = cap.get(cv2.CAP_PROP_FRAME_WIDTH)  # float
    height = cap.get(cv2.CAP_PROP_FRAME_HEIGHT)  # float
    fps = cap.get(cv2.CAP_PROP_FPS)
    save_folder = os.path.join(vis_folder, time.strftime("%Y_%m_%d_%H_%M_%S", current_time))

    os.makedirs(save_folder, exist_ok=True)
    ratio = min(predictor.test_size[0] / height, predictor.test_size[1] / width)
    save_path = os.path.join(save_folder, args.path.split("/")[-1])
    save_path='out.mp4'
    logger.info(f"video save_path is {save_path}")
    vid_writer = cv2.VideoWriter(save_path, cv2.VideoWriter_fourcc(*"mp4v"), fps, (int(width), int(height)))
    frames = []
    outputs = []
    ori_frames = []
    while True:
        ret_val, frame = cap.read()
        if ret_val:
            ori_frames.append(frame)
            frame, _ = predictor.preproc(frame, None, exp.test_size)
            frames.append(torch.tensor(frame))
        else:
            break
    res = []
    frame_len = len(frames)
    index_list = list(range(frame_len))
    random.seed(41)
    random.shuffle(index_list)
    random.seed(41)
    random.shuffle(frames)

    split_num = int(frame_len / (gframe))  #

    for i in range(split_num):
        res.append(frames[i * gframe:(i + 1) * gframe])
    res.append(frames[(i + 1) * gframe:])

    for ele in res:
        if ele == []: continue
        ele = torch.stack(ele)
        t0 = time.time()
        outputs.extend(predictor.inference(ele))
    outputs = [j for _, j in sorted(zip(index_list, outputs))]
    for output, img in zip(outputs, ori_frames[:len(outputs)]):

        result_frame = predictor.visual(output, img, ratio, cls_conf=args.conf)

        if args.save_result:
            cv2.imshow("sdf",result_frame)
            cv2.waitKey(0)
            vid_writer.write(result_frame)


def main(exp, args):
    if not args.experiment_name:
        args.experiment_name = exp.exp_name

    file_name = os.path.join(exp.output_dir, args.experiment_name)
    os.makedirs(file_name, exist_ok=True)

    vis_folder = None
    if args.save_result:
        vis_folder = os.path.join(file_name, "vis_res")
        os.makedirs(vis_folder, exist_ok=True)

    if args.trt:
        args.device = "gpu"

    logger.info("Args: {}".format(args))

    if args.conf is not None:
        exp.test_conf = args.conf
    if args.nms is not None:
        exp.nmsthre = args.nms
    if args.tsize is not None:
        exp.test_size = (args.tsize, args.tsize)

    model = exp.get_model()
    logger.info("Model Summary: {}".format(get_model_info(model, exp.test_size)))

    if args.device == "gpu":
        model.cuda()
    model.eval()

    if not args.trt:
        if args.ckpt is None:
            ckpt_file = os.path.join(file_name, "best_ckpt.pth")
        else:
            ckpt_file = args.ckpt
        logger.info("loading checkpoint")
        ckpt = torch.load(ckpt_file, map_location="cpu")
        # load the model state dict
        model.load_state_dict(ckpt["model"])
        logger.info("loaded checkpoint done.")

    if args.fuse:
        logger.info("\tFusing model...")
        model = fuse_model(model)

    if args.trt:
        assert not args.fuse, "TensorRT model is not support model fusing!"
        trt_file = os.path.join(file_name, "model_trt.pth")
        assert os.path.exists(trt_file), "TensorRT model is not found!\n Run python3 tools/trt.py first!"
        model.head.decode_in_inference = False
        decoder = model.head.decode_outputs
        logger.info("Using TensorRT to inference")
    else:
        trt_file = None
        decoder = None
    if args.dataset == 'vid':
        predictor = Predictor(model, exp, VID_classes, trt_file, decoder, args.device, args.legacy)
    else:
        predictor = Predictor(model, exp, COCO_CLASSES, trt_file, decoder, args.device, args.legacy)
    current_time = time.localtime()

    imageflow_demo(predictor, vis_folder, current_time, args)


if __name__ == "__main__":
    args = make_parser().parse_args()
    exp = get_exp(args.exp_file, args.name)

    main(exp, args)

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

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

相关文章

BGD 实战

梯度下降方法 2.1、三种梯度下降不同 梯度下降分三类:批量梯度下降BGD(Batch Gradient Descent)、小批量梯度下降MBGD(Mini-Batch Gradient Descent)、随机梯度下降SGD(Stochastic Gradient Descent&…

ROB端口需求

对于一个 4-way 的超标量处理器来说,在重排序缓存(ROB)中每周期可以退休的指令个数应该是不小于四条的;如图给出的ROB,在那些最旧的指令中,有三条指令都已经变为了complete状态,那么在一个周期内就可以将这三条指令都退休。 要实现…

Vue路由跳转重定向动态路由VueCli

Vue路由跳转&重定向&动态路由&VueCli 一、声明式导航-导航链接 1.需求 实现导航高亮效果 如果使用a标签进行跳转的话,需要给当前跳转的导航加样式,同时要移除上一个a标签的样式,太麻烦!!! …

抖店一件代发怎么做?保姆级运营教程!

我是电商珠珠 抖店是抖音发展的电商平台,一些没有电商经验的新手,不想囤货,担心卖不出去。 听说可以一件代发,但却不知道怎么做。 今天,我就来详细的跟大家讲一下。 一、选品上架 在选品的时候可以参考后台的电商…

GZ029 智能电子产品设计与开发赛题第5套

2023年全国职业院校技能大赛高职组 “GZ029智能电子产品设计与开发”赛项赛卷五 题目:模拟工业传送带物品检测系统的设计与开发 1 竞赛任务 在智能电视机上播放工业传送带传输物品视频,模拟工业传送带物品检测系统(以下简称物品检测系统&…

wpf TelerikUI使用DragDropManager

首先,我先创建事务对象ApplicationInfo,当暴露出一对属性当例子集合对于构成ListBoxes。这个类在例子中显示如下代码: public class ApplicationInfo { public Double Price { get; set; } public String IconPath { get; set; } public …

Nature 子刊| 单细胞转录组揭示从猴到人的进化过程

期刊:Nature Ecology & Evolution IF:16.8 发表时间:2023 DOI号:10.1038/s41559-023-02186-7 研究背景 据推测,人类认知功能的增强是由于皮质扩张和细胞多样性增加所致。然而,推动这些表型创新的机…

产品入门第一讲:Axure的安装以及基本使用

📚📚 🏅我是默,一个在CSDN分享笔记的博主。📚📚 ​​​ 🌟在这里,我要推荐给大家我的专栏《Axure》。🎯🎯 🚀无论你是编程小白,还是有…

【开源】基于Vue.js的就医保险管理系统

文末获取源码,项目编号: S 085 。 \color{red}{文末获取源码,项目编号:S085。} 文末获取源码,项目编号:S085。 目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 科室档案模块2.2 医生档案模块2.3 预…

竞赛保研 LSTM的预测算法 - 股票预测 天气预测 房价预测

0 简介 今天学长向大家介绍LSTM基础 基于LSTM的预测算法 - 股票预测 天气预测 房价预测 这是一个较为新颖的竞赛课题方向,学长非常推荐! 🧿 更多资料, 项目分享: https://gitee.com/dancheng-senior/postgraduate 1 基于 Ke…

yolov8学习

1.yolov8代码结构 1.ultralytics文件夹 (1)assets 待评估的图片 (2)cfg datasets:不同数据集对应yaml文件 models:不同模型对应的yaml文件 (3)data 用于图像预处理的py代码

【安卓】安卓xTS之Media模块 学习笔记(3) VTS测试

因为本文内容较多,将目录放在这里,便于检索。 文章目录 文章系列1. 背景2. 参考文档3. 测试步骤3.1 VTS测试包获取3.1.1 自行编译 3.2 VTS测试包文件结构3.3 测试命令3.3.1 常见命令3.3.2 一些常见的option: 4. 测试结果说明4.1 结果result4…

【强化学习-读书笔记】多臂赌博机 Multi-armed bandit

参考 Reinforcement Learning, Second Edition An Introduction By Richard S. Sutton and Andrew G. Barto强化学习与监督学习 强化学习与其他机器学习方法最大的不同,就在于前者的训练信号是用来评估(而不是指导)给定动作的好坏的。 …

跨国企业在跨境数据传输时需要注意的几点

对于跨国企业而言,跨境数据传输是一个极为关键的组成部分。这不仅涉及到数据的安全性、合规性和效率,还直接关系到企业的竞争力和未来发展前景。因此,在进行跨境数据传输时,企业需要特别关注以下几个关键点,并采取相应…

设计模式-组合模式

设计模式专栏 模式介绍模式特点应用场景组合模式和装饰者模式的区别代码示例Java实现组合模式python实现组合模式 组合模式在spring中的应用 模式介绍 组合模式是一种结构型设计模式,它针对由多个节点对象(部分)组成的树形结构的对象&#x…

MES管理系统的应用场景都包括哪些

在当今高度信息化的时代,企业生产管理面临着越来越多的挑战。如何实现生产过程的数字化、智能化和优化,提高生产效率和产品质量,是许多制造企业亟待解决的问题。作为一种面向车间现场生产制造过程的数字化管理工具,MES管理系统在企…

最大公因数,最小公倍数详解

前言 对于初学编程的小伙伴们肯定经常遇见此类问题,而且为之头疼,今天我来给大家分享一下,最大公因数和最小公倍数的求法。让我们开始吧! 文章目录 1,最大公因数法1法2法3 2,最小公倍数3,尾声 …

Linux安装Nginx并部署Vue项目

今天部署了一个Vue项目到阿里云的云服务器上,现记录该过程。 1. 修改Vue项目配置 我们去项目中发送axios请求的文件里更改一下后端的接口路由: 2. 执行命令打包 npm run build ### 或者 yarn build 打包成功之后,我们会看到一个dist包&a…

【Python】修改pip 默认安装位置

使用pip安装的时候,一般是默认安装在c盘里的。这样做很容易会让c盘的文件堆满。那么如何让pip安装的包放入d盘呢? 查看pip默认安装的位置 在cmd里输入python -m site,这里可以看到,安装包会默认下载到c盘中 从这里可以看到&am…

数据结构之----逻辑结构、物理结构

数据结构之----逻辑结构、物理结构 目前我们常见的数据结构分别有: 数组、链表、栈、队列、哈希表、树、堆、图 而它们可以从 逻辑结构和物理结构两个维度进行分类。 什么是逻辑结构? 逻辑结构是指数据元素之间的逻辑关系,而逻辑结构又分为…