草庐IT

视频分割、分类、行为标注工具

TF666666 2024-07-03 原文

视频Object、Region、Skeleton标注工具

原文git地址:https://github.com/anucvml/vidat

本文代码:链接:https://pan.baidu.com/s/1i3Z2ZCR6mrSZraW4ydRE3w
提取码:q3r5

此工具为浏览器内视频注释工具。

该项目的目的是为计算机视觉和机器学习应用开发一个高质量的视频注释工具,具有以下需求:

  1. 非专家使用简单高效。
  2. 支持多种注释类型,包括时间段、对象边界框、语义和实例区域、轨迹和人体姿势(骨架)。
  3. 在浏览器中运行,无需外部库或需要服务器端处理。但很容易插入后端以进行繁重的“在环”处理(例如,来自边界框的片段或来自部分标签的帧完成)。
  4. 兼容所有(大多数)现代浏览器和操作系统,包括平板电脑。
  5. 安全的。数据不需要离开本地机器(因为没有服务器端处理)。
  6. 开源。

Screenshots

Object

Region

Skeleton

Skeleton Type

Action

Usage

您需要先部署Vidat,然后使用URL 参数将视频加载到 Vidat

1、首先要部署nginx,官网下载对用版本的nginx: http://nginx.org/en/download.html

2、启动nginx,可以双击nginx.exe或者使用cmd进入该路径下使用命令start nginx启动

3、验证nginx是否配置好,打开浏览器输入http://localhost:80即可查看nginx欢迎界面

(注释:如果80端口被占用,服务启动失败,修改配置文件nginx.conf)

 server {
        listen       8088; # 更改对应的端口
        server_name  localhost;  # 服务的名字

        #charset koi8-r;

        #access_log  logs/host.access.log  main;

        location / {
            root   html;
            index  index.html index.htm;
        }

4、nginx停止服务,进入nginx安装路径下执行nginx -s stop 命令

5、部署Vidat,将对应文件夹放入到html文件夹下,启动nginx即可(同上启动nginx一样),注意将之前测试的nginx停止。

6、访问http://localhost:8088/vidat-v2.0.0/index.html地址即可,地址进行拼接http://localhost:8088/ + vidat-v2.0.0/index.html(后面是文件夹的路径)
7、检查是否启动成功。


数据格式(data)

数据要求:使用视频数据,本软件不支持cv2图片转视频格式,解码使用的是java解码,文件提供了java图像转视 频代码。

package cn.morethink.nettyexample.util;
import org.bytedeco.ffmpeg.global.avcodec;
import org.bytedeco.ffmpeg.global.avutil;
import org.bytedeco.javacv.FFmpegFrameRecorder;
import org.bytedeco.javacv.FrameRecorder;
import org.bytedeco.javacv.Java2DFrameConverter;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.util.HashMap;
import java.util.Map;

public class Img2mp4 {


    public static void main(String[] args) throws Exception {

        //合成的MP4 存放的地址路径 这里的路径并不会自动创建,需要手动提前创建好,否则会报错
        String mp4SavePath = "E:\\vidat-latest\\video\\000006.mp4";
        //图片存放的地址路径
        String img = "E:\\vidat-latest\\picture";
        int width = 2400;
        int height = 1800;
        //读取所有图片
        File file = new File(img);
        File[] files = file.listFiles();
        Map<Integer, File> imgMap = new HashMap<Integer, File>();
        int num = 0;
        for (File imgFile : files) {
            imgMap.put(num, imgFile);
            num++;
        }
        createMp4(mp4SavePath, imgMap, width, height);
    }

    private static void createMp4(String mp4SavePath, Map<Integer, File> imgMap, int width, int height) throws FrameRecorder.Exception {
        //视频宽高最好是按照常见的视频的宽高  16:9  或者 9:16
        FFmpegFrameRecorder recorder = new FFmpegFrameRecorder(mp4SavePath, width, height);
        //设置视频编码层模式     import org.bytedeco.ffmpeg.global.avcodec;可能需要手动复制添加
        recorder.setVideoCodec(avcodec.AV_CODEC_ID_H264);
        //设置视频为10帧每秒
        recorder.setFrameRate(10);
        //设置视频图像数据格式    import org.bytedeco.ffmpeg.global.avutil;可能需要手动复制添加
        recorder.setPixelFormat(avutil.AV_PIX_FMT_YUV420P);

        recorder.setFormat("mp4");
        try {
            recorder.start();
            Java2DFrameConverter converter = new Java2DFrameConverter();
            //根据图片数量/10 生成视频的秒数.
            for (int i = 0; i < 7 ; i++) {
                BufferedImage read = ImageIO.read(imgMap.get(i));
                // 调整每秒插入视频的图片数, 数值越小 视频越流畅 性能消耗越大
                for (int j = 0; j < 10; j++) {
                    recorder.record(converter.getFrame(read));
                }

            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            //最后一定要结束并释放资源
            recorder.stop();
            recorder.release();
        }
    }

}

数据结果:本视频标注结果是vidat-latest\public\annotation\example.json,同样提供了将格式转为labelme格式

import argparse
import json
import cv2
import numpy as np
import os

"""
parser = argparse.ArgumentParser()
parser.add_argument("square", help="display a square of a given number", type=int)
args = parser.parse_args()
print(args.square** 2)
"""

load_f = open(r"E:\vidat-latest\public\annotation\ning71x-16-0672_10_000000.json", encoding="utf-8")
anno = json.load(load_f)
# print(anno)
# print(anno.keys())
total_json = {}
version = anno["version"]
print(version)
annotation = anno["annotation"]
config = anno["config"]
print(annotation.keys())
video = annotation["video"]
keyframeList = annotation["keyframeList"]
regionAnnotationListMap = annotation["regionAnnotationListMap"]
# print(regionAnnotationListMap["0"])
shapes = []
if regionAnnotationListMap["0"]:
    for i in range(len(regionAnnotationListMap["0"])):
        single_particle = {}
        points = regionAnnotationListMap["0"][i]["pointList"]
        print(len(points))
        point_lists = []
        label = regionAnnotationListMap["0"][i]["labelId"]
        # print(label)
        shape_type = "polygon"
        flags = []
        for i in range(len(points)):
            point_x = points[i]["x"]
            point_y = points[i]["y"]
            point_lists.append([point_x, point_y])
        single_particle.update({"label": label,
                                "points": point_lists,
                                "group_id": None,
                                "shape_type": shape_type,
                                "flags": []})
        
        # print(single_particle)
        shapes.append(single_particle)
# print(shapes)
imagePath = video["src"]
imageData = None
imgHeight = video["height"]
imgWidth = video["width"]

total_json.update({"version": version,
                   "flags": [],
                   "shapes": shapes,
                   "imagePath": imagePath,
                   "imageData": imageData,
                   "imgHeight": imgHeight,
                   "imgWidth": imgWidth})

with open(r"E:\vidat-latest\public\annotation\labelme_ning71x-16-0672_10_000000.json", "w", encoding="utf-8") as f:
    json.dump(total_json, f, ensure_ascii=False)

        
            

数据保存:当前数据标注结束以后,对标注结果下载,保存名字自定义,保存名字更改为视频呢名字,方便使用。


视频教程:

链接:https://pan.baidu.com/s/1y_J3QtkmrEVYtIOgV-Eueg
提取码:rbys

参考资料

https://github.com/anucvml/vidat
@misc{zhang2020vidat,
author = {Jiahao Zhang and Stephen Gould and Itzik Ben-Shabat},
title = {Vidat—{ANU} {CVML} Video Annotation Tool},
howpublished = {\url{https://github.com/anucvml/vidat}},
year = {2020}
}
感谢vidat团队开源。

有关视频分割、分类、行为标注工具的更多相关文章

  1. ruby - 如何根据特征实现 FactoryGirl 的条件行为 - 2

    我有一个用户工厂。我希望默认情况下确认用户。但是鉴于unconfirmed特征,我不希望它们被确认。虽然我有一个基于实现细节而不是抽象的工作实现,但我想知道如何正确地做到这一点。factory:userdoafter(:create)do|user,evaluator|#unwantedimplementationdetailshereunlessFactoryGirl.factories[:user].defined_traits.map(&:name).include?(:unconfirmed)user.confirm!endendtrait:unconfirmeddoenden

  2. 世界前沿3D开发引擎HOOPS全面讲解——集3D数据读取、3D图形渲染、3D数据发布于一体的全新3D应用开发工具 - 2

    无论您是想搭建桌面端、WEB端或者移动端APP应用,HOOPSPlatform组件都可以为您提供弹性的3D集成架构,同时,由工业领域3D技术专家组成的HOOPS技术团队也能为您提供技术支持服务。如果您的客户期望有一种在多个平台(桌面/WEB/APP,而且某些客户端是“瘦”客户端)快速、方便地将数据接入到3D应用系统的解决方案,并且当访问数据时,在各个平台上的性能和用户体验保持一致,HOOPSPlatform将帮助您完成。利用HOOPSPlatform,您可以开发在任何环境下的3D基础应用架构。HOOPSPlatform可以帮您打造3D创新型产品,HOOPSSDK包含的技术有:快速且准确的CAD

  3. 基于C#实现简易绘图工具【100010177】 - 2

    C#实现简易绘图工具一.引言实验目的:通过制作窗体应用程序(C#画图软件),熟悉基本的窗体设计过程以及控件设计,事件处理等,熟悉使用C#的winform窗体进行绘图的基本步骤,对于面向对象编程有更加深刻的体会.Tutorial任务设计一个具有基本功能的画图软件**·包括简单的新建文件,保存,重新绘图等功能**·实现一些基本图形的绘制,包括铅笔和基本形状等,学习橡皮工具的创建**·设计一个合理舒适的UI界面**注明:你可能需要先了解一些关于winform窗体应用程序绘图的基本知识,以及关于GDI+类和结构的知识二.实验环境Windows系统下的visualstudio2017C#窗体应用程序三.

  4. postman接口测试工具-基础使用教程 - 2

    1.postman介绍Postman一款非常流行的API调试工具。其实,开发人员用的更多。因为测试人员做接口测试会有更多选择,例如Jmeter、soapUI等。不过,对于开发过程中去调试接口,Postman确实足够的简单方便,而且功能强大。2.下载安装官网地址:https://www.postman.com/下载完成后双击安装吧,安装过程极其简单,无需任何操作3.使用教程这里以百度为例,工具使用简单,填写URL地址即可发送请求,在下方查看响应结果和响应状态码常用方法都有支持请求方法:getpostputdeleteGet、Post、Put与Delete的作用get:请求方法一般是用于数据查询,

  5. 动漫制作技巧如何制作动漫视频 - 2

    动漫制作技巧是很多新人想了解的问题,今天小编就来解答与大家分享一下动漫制作流程,为了帮助有兴趣的同学理解,大多数人会选择动漫培训机构,那么今天小编就带大家来看看动漫制作要掌握哪些技巧?一、动漫作品首先完成草图设计和原型制作。设计草图要有目的、有对象、有步骤、要形象、要简单、符合实际。设计图要一致性,以保证制作的顺利进行。二、原型制作是根据设计图纸和制作材料,可以是手绘也可以是3d软件创建。在此步骤中,要注意的问题是色彩和平面布局。三、动漫制作制作完成后,加工成型。完成不同的表现形式后,就要对设计稿进行加工处理,使加工的难易度降低,并得到一些基本准确的概念,以便于后续的大样、准确的尺寸制定。四、

  6. python ffmpeg 使用 pyav 转换 一组图像 到 视频 - 2

    2022/8/4更新支持加入水印水印必须包含透明图像,并且水印图像大小要等于原图像的大小pythonconvert_image_to_video.py-f30-mwatermark.pngim_dirout.mkv2022/6/21更新让命令行参数更加易用新的命令行使用方法pythonconvert_image_to_video.py-f30im_dirout.mkvFFMPEG命令行转换一组JPG图像到视频时,是将这组图像视为MJPG流。我需要转换一组PNG图像到视频,FFMPEG就不认了。pyav内置了ffmpeg库,不需要系统带有ffmpeg工具因此我使用ffmpeg的python包装p

  7. TimeSformer:抛弃CNN的Transformer视频理解框架 - 2

    Transformers开始在视频识别领域的“猪突猛进”,各种改进和魔改层出不穷。由此作者将开启VideoTransformer系列的讲解,本篇主要介绍了FBAI团队的TimeSformer,这也是第一篇使用纯Transformer结构在视频识别上的文章。如果觉得有用,就请点赞、收藏、关注!paper:https://arxiv.org/abs/2102.05095code(offical):https://github.com/facebookresearch/TimeSformeraccept:ICML2021author:FacebookAI一、前言Transformers(VIT)在图

  8. ruby - Ruby gsub 替换中的行为不一致? - 2

    两个gsub产生不同的结果。谁能解释一下为什么?代码也可在https://gist.github.com/franklsf95/6c0f8938f28706b5644d获得.ver=9999str="\tCFBundleDevelopmentRegion\n\ten\n\tCFBundleVersion\n\t0.1.190\n\tAppID\n\t000000000000000"putsstr.gsub/(CFBundleVersion\n\t.*\.).*()/,"#{$1}#{ver}#{$2}"puts'--------'putsstr.gsub/(CFBundleVersio

  9. ruby-on-rails - Ruby 中意外的大小写行为 - 2

    我在一段非常简单的代码(如我所想)中得到了一个错误的值:org=4caseorgwhenorg=4val='H'endputsval=>nil请不要生气,我希望我错过了一些非常明显的东西,但我真的想不通。谢谢。 最佳答案 这是典型的Ruby错误。case有两种被调用的方法,一种是你传递一个东西作为分支的基础,另一种是你不传递的东西。如果您确实在case中指定了一个表达式语句然后评估所有其他条件并与===进行比较.在这种情况下org评估为false和org===false显然不是真的。所有其他情况也是如此,它们要么是真的,要么是假的。

  10. ruby - 使对象的行为类似于 ruby​​ 中并行分配的数组 - 2

    假设您在Ruby中执行此操作:ar=[1,2]x,y=ar然后,x==1和y==2。是否有一种方法可以在我自己的类中定义,从而产生相同的效果?例如rb=AllYourCode.newx,y=rb到目前为止,对于这样的赋值,我所能做的就是使x==rb和y=nil。Python有这样一个特性:>>>classFoo:...def__iter__(self):...returniter([1,2])...>>>x,y=Foo()>>>x1>>>y2 最佳答案 是的。定义#to_ary。这将使您的对象被视为要分配的数组。irb>o=Obje

随机推荐