(2024年4月编写)

github地址

https://github.com/sherlockchou86/video_pipe_c

作者微信

zhzhi78(备注 videopipe),拉群交流(1000人群),及时获取代码更新。

网站介绍

http://www.videopipe.cool/

配套教程

http://www.videopipe.cool/index.php/2024/09/11/videopipetutorials/

演示Sample

http://www.videopipe.cool/index.php/2024/08/21/videopipesamples/

0、一个引子

计算机视觉(Computer Vision,后简称CV)是人工智能领域中的一个细分场景。随着深度学习技术的飞速发展,基于神经网络的图像算法已经慢慢取代了传统图像算法,也越来越多地落地到实际应用场景中。下图列举了常见的神经网络图像算法:

图1 常见神经网络图像算法

神经网络的训练、调优离不开算法工程师,近几年在众多IT技术招聘岗位中,无论是薪资待遇还是招聘数量上,算法工程师岗位都是名列前茅。那么在这个调参(炼丹)火热的时代(公司保安大爷都知道什么叫“监督学习”),如何将训练好的神经网络图像算法模型快速部署落地到实际应用场景中呢?VideoPipe视频分析框架满足这一需求,它适用于大部分视频结构化应用场景,可以快速集成训练好的图像算法模型,包括但不限于:

  • 图像分类算法。给定的图片是小猫还是小狗?是白毛还是黑毛?
  • 目标检测算法。给定的图片中包含哪些目标(车、人、文字...)?目标坐标、尺寸是多少?
  • 图像分割算法。为给定的图片做像素级分割,不同区域显示不同颜色。
  • 图像特征编码算法。为给定的图片提取“指纹级”特征,可用于图片识别、对比、检索。
  • 图像生成算法。随机生成指定风格的图片,或为图片转换风格(比如将手机拍摄的人物照片转成卡通风格)。

VideoPipe视频分析框架可广泛应用于智慧交通、智能安防等领域,可快速构建人脸识别车牌识别交通事件检测以图搜图OCR文字识别AI换脸等软件系统。下图是使用VideoPipe实现口算练习检查(仿作业帮APP)的功能截图:

图2 口算练习检查

图中绿色代表正确,红色代表错误(并在括号中给出了正确答案),橙色代表格式不对(比如表达式中左括号没有对应的右括号)。另外,图中上半部分的管道代表口算练习检查的核心环节。下面整理了作业帮APP中口算练习检查功能的完整流程,我们按照该流程可以完整复现作业帮APP中的功能:

  1. 用户打开作业帮APP,点击口算检查按钮,APP弹出相机界面准备拍照
  2. 用户将手机对准口算作业本,保持相机画面正对口算题目,点击拍照按钮
  3. 作业帮APP抓拍一张照片,通过http协议上传到作业帮服务器
  4. 服务器收到图片数据(编码数据),对其进行解码,生成图片
  5. 服务器调用OCR文字识别算法,对图片中的口算题目进行检测和识别,得到String类型字符串,类似1+1=2
  6. 服务器调用数学表达式解析库(一种可以对数学表达式进行解析和计算的工具库),计算=号左边的结果(这里结果是2),然后将左边结果和=号右边的值(学生答题结果,这里也是2)进行比较,给出对错结论
  7. 按照步骤6的方式检查整张图片中的口算表达式,最后计算总得分
  8. 服务器将检查结果(对、错、无效)用不同颜色叠加到原上传图片上
  9. 服务器将最终结果(含叠加结果的图片)返回给作业帮APP,APP呈现给用户

我们可以看到,口算练习检查整个流程包含了多个处理环节和技术栈,我用图片直观描述如下:

图3 口算练习检查流程

图中虚线部分全部可以借助VideoPipe来实现,图片接收和解码字符检测和识别数学表达式解析和计算检查结果叠加,这些环节在VideoPipe中有节点类型一一与之对应:

  • vp_image_src_node节点:完成接收图片和解码工作
  • vp_ppocr_text_detector_node节点:完成字符检测和识别
  • vp_expr_check_node节点:完成数学表达式解析和计算
  • vp_expr_osd_node节点:完成检查结果叠加

VideoPipe可以帮助你实现口算练习检查的核心环节,当然VideoPipe能做的远不止于此,接下来我来对它做详细介绍。

1、VideoPipe介绍

一个用于视频(含图片,下同)分析的图像算法集成框架。它可以处理复杂任务,如流读取(从本地或网络)、解码、基于深度学习模型推理(分类/检测/特征提取/...)、跟踪、行为分析(逻辑处理)、数据叠加(OSD)、数据转发(如Kafka/Socket)、编码和流推送(RTMP或本地文件)。整个框架采用面向插件的编程风格,我们可以使用各种不同类型的插件,即框架中的Node类型,来构建不同类型的视频分析管道。

图4 VideoPipe工作管道(示意)

VideoPipe类似于英伟达的DeepStream和华为的mxVision,但它更易于使用,更具备可移植性,并且对于像GStreamer这样难以学习(编程风格或调试方面)的第三方模块依赖较少。该框架纯粹由原生C++ STL编写,只依赖主流的第三方库(如OpenCV),因此代码更易于在不同平台上移植。

注意:

VideoPipe是一个让计算机视觉领域中算法模型集成更加简单的框架,它并不是TensorFlow、TensorRT类似的深度学习框架。

2、主要功能

VideoPipe包含以下主要功能:

  • 流读取。支持主流的视频流协议,如udp(视频或图像)、rtsp、rtmp、文件(视频或图像)。
  • 视频解码。支持基于OpenCV/GStreamer的视频(图片)解码(支持硬件加速)。
  • 基于深度学习的算法推理。支持基于深度学习算法的多级推理,例如目标检测、图像分类、特征提取。你只需准备好模型并了解如何解析其输出即可。推理可以基于不同的后端实现,如OpenCV::DNN(默认)TensorRTPaddleInferenceONNXRuntime等,任何你喜欢的都可以。
  • 屏幕显示(OSD)。支持可视化,如将模型输出结果绘制到帧上。
  • 数据代理。支持将结构化数据(json/xml/自定义格式)以kafka/Sokcet等方式推送到云端、文件或其他第三方平台。
  • 目标跟踪。支持目标追踪,例如IOU、SORT跟踪算法等。
  • 行为分析(BA)。支持基于跟踪的行为分析,例如越线、停车、违章等交通判断。
  • 录制。支持特定时间段的视频录制,特定帧的截图。
  • 视频编码。支持基于OpenCV/GStreamer的视频(图片)编码(支持硬件加速)。
  • 流推送。支持通过rtmp、rtsp(无需专门的rtsp服务器)、文件(视频/图像)、udp(仅限图像)、屏幕显示(GUI)进行流推送或结果展示。

3、主要特点

VideoPipe具备以下特点:

  1. 可视化管道,对程序调试非常有帮助。管道的运行状态会自动在屏幕上刷新,包括管道中每个连接点的fps、缓存大小、延迟等信息,你可以根据这些运行信息快速确定管道的瓶颈所在。
  2. 节点之间通过智能指针传递数据,默认情况下是浅拷贝,当数据在整个管道中流动时无需进行内容拷贝操作。当然,如果需要,你可以指定深拷贝,例如当管道具有多个分支时,你需要分别在两个不同的内容拷贝上进行操作。
  3. 你可以构建不同类型的管道,支持单通道或多通道的管道,管道中的各通道是独立的。每个通道可以拆分成多个分支并行处理不同的任务,之后进行数据同步,再合并回一个分支进行输出。
  4. 管道支持钩子(回调),你可以向管道注册回调以获取状态通知(参见第1项特点),例如实时获取某个连接点的fps。
  5. VideoPipe中已经内置了丰富的节点(Node)类型,所有节点都可以由用户重新实现,也可以根据你的实际需求实现更多节点类型。
  6. 支持动态操作管道,支持多线程并行操作,支持热插拔操作模式(管道无需先暂停,即插即用)。
  7. 整个框架主要由原生C++编写,可在所有平台上移植。

4、如何使用

4.1 快速开始

下面是一个如何构建Pipeline然后运行的Sample(请先修改代码中的相关文件路径):

#include "../nodes/vp_file_src_node.h"
#include "../nodes/infers/vp_yunet_face_detector_node.h"
#include "../nodes/infers/vp_sface_feature_encoder_node.h"
#include "../nodes/osd/vp_face_osd_node_v2.h"
#include "../nodes/vp_screen_des_node.h"
#include "../nodes/vp_rtmp_des_node.h"
#include "../utils/analysis_board/vp_analysis_board.h" /*
* ## 1-1-N sample ##
* 1个视频输入,1个视频分析任务(人脸检测和识别),2个输出(屏幕输出/RTMP推流输出)
*/ int main() {
VP_SET_LOG_INCLUDE_CODE_LOCATION(false);
VP_SET_LOG_INCLUDE_THREAD_ID(false);
VP_LOGGER_INIT(); // 创建节点
auto file_src_0 = std::make_shared<vp_nodes::vp_file_src_node>("file_src_0", 0, "./test_video/10.mp4", 0.6);
auto yunet_face_detector_0 = std::make_shared<vp_nodes::vp_yunet_face_detector_node>("yunet_face_detector_0", "./models/face/face_detection_yunet_2022mar.onnx");
auto sface_face_encoder_0 = std::make_shared<vp_nodes::vp_sface_feature_encoder_node>("sface_face_encoder_0", "./models/face/face_recognition_sface_2021dec.onnx");
auto osd_0 = std::make_shared<vp_nodes::vp_face_osd_node_v2>("osd_0");
auto screen_des_0 = std::make_shared<vp_nodes::vp_screen_des_node>("screen_des_0", 0);
auto rtmp_des_0 = std::make_shared<vp_nodes::vp_rtmp_des_node>("rtmp_des_0", 0, "rtmp://192.168.77.60/live/10000"); // 构建管道
yunet_face_detector_0->attach_to({file_src_0});
sface_face_encoder_0->attach_to({yunet_face_detector_0});
osd_0->attach_to({sface_face_encoder_0}); // 管道自动拆分
screen_des_0->attach_to({osd_0});
rtmp_des_0->attach_to({osd_0}); // 启动管道
file_src_0->start(); // 可视化管道
vp_utils::vp_analysis_board board({file_src_0});
board.display();
}

上面代码运行后,会出现3个画面:

  1. 管道的运行状态图,状态自动刷新
  2. 屏幕显示结果(GUI)
  3. 播放器显示结果(RTMP)

图5 1-1-N_sample运行截图

在上面Sample中,VideoPipe从本地读取视频文件,然后检测其中的人脸、对每个人脸提取特征、比较2张人脸的相似度、将结果叠加到视频上,最后在屏幕中显示,并以RTMP的形式将视频推到服务器上供互联网其他用户播放。整个流程完全由VideoPipe帮忙完成,插件式编程风格,直观、灵活。

4.2 更多案例

github仓库中有接近40个Sample,涵盖人脸识别车辆检测分类以图搜图目标跟踪交通事件检测车牌识别动态管道图像分割等等。下面是拥堵检测口算练习检查的截图:

车牌识别

拥堵检测

更多案例请访问github仓库。

5、原理细节

下面给大家详细介绍框架实现原理和技术细节,对该部分感兴趣的小伙伴可以加我微信交流(见文章末尾)。

5.1 视频结构化应用的核心环节

视频结构化是将非结构化数据(视频/图片)转换为结构化数据的过程。非结构化数据通常包括:

  • 视频
  • 图像
  • 音频
  • 自然语言文本

而结构化数据主要包括诸如 JSON、XML或数据库中的数据表等,这些数据可以直接由机器(程序)处理。具体到视频(含图片,下同)方面,结构化的过程主要涉及以下核心部分:

  • 读取流。从网络或本地机器获取视频流。
  • 解码。将字节流解码为帧,因为算法只能作用于图像。
  • 推理。对图像进行深度学习推理,如检测、分类或特征提取。
  • 跟踪。跟踪视频中的目标。
  • 行为分析/逻辑处理。分析目标的轨迹、属性。
  • OSD。在图像上显示结果,用于调试或得到直观效果。
  • 消息代理。将结构化数据推送到外部,供业务平台使用。
  • 编码。对包含结果的帧进行编码,以便传输、存储。
  • 推送流。将字节流推送到外部或直接保存。

上述每个环节对应VideoPipe中的一种插件类型,即代码中的Node

5.2 VideoPipe中的Node

VideoPipe中的每个Node负责一种任务(严格遵循单一职责原则),例如解码或推理。我们可以将许多节点串在一起构建成管道,并让视频数据流经整个管道。每个Node内部都有两个队列,一个用于缓存上游节点推送的数据,另一个用于缓存等待被推送到下游节点的数据。我们可以在两个队列之间编写逻辑代码,这是典型的生产者-消费者模式。

默认情况下,生产者和消费者在节点内部使用单个线程工作,因此在处理复杂任务时(例如,在 vp_message_broker_node中推送数据是一个耗时的操作),我们需要编写异步代码来避免阻塞管道。

VideoPipe中有三种类型的节点,分别是:

  • SRC节点:源节点,数据被创建的地方(内部只有一个队列,用于缓存被推送到下游节点的数据)。
  • MID节点:中间节点,数据将在此处理。
  • DES节点:目标节点,数据消失的地方(内部只有一个队列,用于缓存来自上游节点的数据)。

每个节点本身具有合并多个上游节点和拆分成多个下游节点的能力。注意,默认情况下节点在将数据从一个节点传输到另一个节点时使用浅拷贝和等值拷贝。如果您需要深拷贝或希望按通道索引传输数据(希望数据不混淆),则在分裂点添加一个vp_split_node类型节点。

5.3 VideoPipe中的数据流

视频是一种重量级数据,因此频繁进行深拷贝会降低管道的性能。实际上,VideoPipe中两个节点之间传递的数据默认使用智能指针,一旦数据由源节点创建,数据内容在整个管道中大多数时间不会被复制(但如果需要,我们可以指定深度拷贝模式,例如使用vp_split_node)。

视频由连续的帧组成,VideoPipe 逐帧处理这些帧,因此帧元数据中的帧索引也会连续增加。

5.4 VideoPipe中的钩子

钩子是一种机制,让主体在发生某些事件时通知检测者,VideoPipe也支持钩子。管道触发回调函数(std::function)与外部代码通信,例如实时推送管道自身的 fps延迟其他状态信息。我们在编写回调函数内部代码时,不允许有阻塞出现,否则影响整个管道性能。

钩子有助于调试我们的应用程序,并快速找出整个管道中的瓶颈,VideoPipe框架中自带的可视化工具vp_analysis_board就依赖于钩子机制。

5.5 在VideoPipe中实现新的Node类型

vp_node是VideoPipe中所有节点的基类。我们可以定义一个从vp_node派生的新节点类,并重写一些虚函数,如handle_frame_metahandle_control_meta

  • handle_frame_meta:处理流经当前节点的帧数据。
  • handle_control_meta:处理流经当前节点的控制指令数据。

帧数据指的是VideoPipe中的 vp_frame_meta,其中包含与帧相关的数据,如帧索引数据缓冲区原始宽度等等。控制指令数据指的是VideoPipe中的 vp_control_meta,其中包含与命令相关的数据,例如记录视频记录图像等。

注意,并非所有流经当前节点的数据都应该被处理,我们只需要处理我们感兴趣的内容。

六、相似框架对比

VideoPipe主要用途与DeepStream/mxVision相似,用于快速构建视频分析应用系统。但三者之间存在一些差异:

序号 名称 是否开源 学习门槛 适用平台 性能 三方依赖
1 DeepStream 仅限英伟达
2 mxVision 仅限华为
3 VideoPipe 不限平台

DeepStream和mxVision(包括其他AI硬件厂家推出的类似框架)只可用于自家硬件平台,性能相对较高,VideoPipe由于要兼容各种不同硬件,数据共享方面弱于前者。VideoPipe学习门槛更低,核心代码完全开源,编码风格和代码调试方便均要优于其他类似框架(VideoPipe没有GObject相关内容)。下图显示视频分析过程中数据共享程度对整个处理管道性能的影响:

上图左侧数据来回在CPU和GPU之间传递,影响整个管道处理速度;右侧大部分操作全部在GPU侧完成,减少数据来回传递次数,数据共享程度更高,有利于管道处理性能。

视频分析框架VideoPipe完整介绍的更多相关文章

  1. 马蜂窝视频编辑框架设计及在 iOS 端的业务实践

    (马蜂窝技术公众号原创内容,ID: mfwtech) 熟悉马蜂窝的朋友一定知道,点击马蜂窝 App 首页的发布按钮,会发现发布的内容已经被简化成「图文」或者「视频」. 长期以来,游记.问答.攻略等图文 ...

  2. 系统级性能分析工具perf的介绍与使用[转]

    测试环境:Ubuntu16.04(在VMWare虚拟机使用perf top存在无法显示问题) Kernel:3.13.0-32 系统级性能优化通常包括两个阶段:性能剖析(performance pro ...

  3. ISP基本框架及算法介绍

    什么是ISP,他的工作原理是怎样的? ISP是Image Signal Processor的缩写,全称是影像处理器.在相机成像的整个环节中,它负责接收感光元件(Sensor)的原始信号数据,可以理解为 ...

  4. 【转】OMCS网络语音视频聊天框架(跨平台)

    原文地址:http://www.cnblogs.com/zhuweisky/archive/2012/08/02/2617877.html OMCS网络语音视频框架是集成了语音通话.视频通话.远程桌面 ...

  5. NVIDIA DeepStream 5.0构建智能视频分析应用程序

    NVIDIA DeepStream 5.0构建智能视频分析应用程序 无论是要平衡产品分配和优化流量的仓库,工厂流水线检查还是医院管理,要确保员工和护理人员在照顾病人的同时使用个人保护设备(PPE),就 ...

  6. 系统级性能分析工具perf的介绍与使用

    测试环境:Ubuntu16.04(在VMWare虚拟机使用perf top存在无法显示问题) Kernel:3.13.0-32 系统级性能优化通常包括两个阶段:性能剖析(performance pro ...

  7. iOS集成ijkplayer视频直播框架,遇到的bug和坑...

    p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 32.0px "Helvetica Neue"; color: #555555 } p. ...

  8. 符号执行-基于python的二进制分析框架angr

    转载:All Right 符号执行概述 在学习这个框架之前首先要知道符号执行.符号执行技术使用符号值代替数字值执行程序,得到的变量的值是由输入变 量的符号值和常量组成的表达式.符号执行技术首先由Kin ...

  9. 开源网络抓包与分析框架学习-Packetbeat篇

    开源简介packbeat是一个开源的实时网络抓包与分析框架,内置了很多常见的协议捕获及解析,如HTTP.MySQL.Redis等.在实际使用中,通常和Elasticsearch以及kibana联合使用 ...

  10. windows下nodejs express安装及入门网站,视频资料,开源项目介绍

    windows下nodejs express安装及入门网站,视频资料,开源项目介绍,pm2,supervisor,npm,Pomelo,Grunt安装使用注意事项等总结 第一步:下载安装文件下载地址: ...

随机推荐

  1. appium环境搭建及命令行启动sdk模拟器-附踩坑以及解决过程

    安装教程这里就不阐述了,网上一大堆教程,下载完成后安装然后配置对应的环境变量即可 android sdk及java home配置: path配置: %ANDROID_HOME%\platform-to ...

  2. 带你玩转nginx负载均衡

    nginx跨多个应用程序实例的负载平衡是一种用于优化资源利用率,最大化吞吐量,减少延迟和确保容错配置的常用技术. 环境介绍 配置nginx负载均衡器因会用到多台服务器来进行,所以下面我会用到docke ...

  3. .NET 隐藏/自定义windows系统光标

    本文介绍如何操作windows系统光标.正常我们设置/隐藏光标,只能改变当前窗体或者控件范围,无法全局操作windows光标.接到一个需求,想隐藏windows全局的鼠标光标显示,下面讲下如何操作 先 ...

  4. 将NC栅格表示时间维度的数据提取出来的方法

      本文介绍基于Python语言,逐一读取大量.nc格式的多时相栅格文件,导出其中所具有的全部时间信息的方法.   .nc是NetCDF(Network Common Data Form)文件的扩展名 ...

  5. 函数(C语言)

    目录 1. 函数的概念 2. 库函数 2.1 标准库和头文件 2.2 库函数的使用方法 3. 自定义函数 3.1 函数的语法形式 3.2 函数的举例 4. 形参和实参 4.1 实参 4.2 形参 4. ...

  6. Java基础完结

    花费了大概一周的时间,看完了韩顺平的Java基础课,不得不说韩老师讲的java基础还是相当仔细的,细节满满,我认为这既是优点也是缺点吧23333333-- 接下来准备看老杜的MySQL,因为没有配套的 ...

  7. KTL (0.9.2,通达信mdt文件)

    K,K线,Candle蜡烛图. T,技术分析,工具平台 L,公式Language语言使用c++14,Lite小巧简易. 项目仓库:https://github.com/bbqz007/KTL 国内仓库 ...

  8. 【一步步开发AI运动小程序】一、准备工作

    随着人工智能技术的不断发展,阿里体育等IT大厂,推出的"乐动力"."天天跳绳"AI运动APP,让云上运动会.线上运动会.健身打卡.AI体育指导等概念空前火热.那 ...

  9. (Redis基础教程之五)如何在Redis中操作字符串

    如何在ubuntu18.04上安装和保护redis 如何连接到Redis数据库 如何管理Redis数据库和Keys 如何在Redis中管理副本和客户端 如何在Redis中管理字符串 如何在Redis中 ...

  10. 使用IDEA一键发布应用

    1.编辑Dockerfile from java:8 WORKDIR /usr/local ADD ./target/jpaas-bpm.jar . CMD ["java",&qu ...