dvg-utils是一组工具,可以帮助你使用OpenCV快速构建图像和视频处理管道。

在不同的平台和设备上进行计算机视觉和深度学习的实验带来了许多挑战,尤其是当你希望与团队共同维护一个代码库而不需要做重复的工作。从不同设备设置视频流的步骤基本上是一样的,该过程我们需要记录日志,读取配置文件,绘制带有标签的框,保存结果,收集一些指标等,为什么不将这些工作放在一起呢?这就是本文向你介绍dvg-utils的意义。

目录

  1. dvg-utils简介

  2. 设置

  3. 命令行工具

  4. 捕获视频

  5. 捕获图像

  6. 例子

  7. 指标

  8. 概要

  9. 资源

dvg-utils简介

自从我写了第一篇关于为图像和视频处理创建一个模块化而且简单的管道的文章以来,差不多过去一年了,从那以后我也一直在学习,学到了很多东西。在这段时间里,我做了许多不同的项目,它们总是需要相同的步骤。

每个计算机视觉管道都需要以下代码块:

  • 设置日志

  • 读取配置文件

  • 捕获图像或视频流

  • 处理数据

  • 可视化结果

  • 显示结果

  • 保存结果

  • 收集指标

这些代码块中的大多数都是在每个项目中会反复出现的模板代码。

为了更轻松,更快速地设置计算机视觉项目,我在SławomirGilewski的帮助下创建了dvg-utils Python软件包。

  • dvg-utils:https://github.com/jagin/dvg-utils

  • SławomirGilewski:https://medium.com/u/1ddaceb8aa71

设置

在开始之前,我建议使用Python虚拟环境。虚拟环境允许你在系统上运行独立的Python环境,更多请看一下RealPython上的这篇文章。

  • https://realpython.com/python-virtual-environments-a-primer/

我假设你正在使用具有Linux或MacOs系统的台式机/笔记本电脑(我没有机会在Windows平台上对其进行测试,但它应该可以运行)。

如果你想从Jetson设备运行一些示例,Jetpack的SDK已经安装了OpenCV,你可以跳过pip install opencv-contrib-python这一步骤。

对于树莓派用户,请在此文章的帮助下安装OpenCV 。

  • https://www.pyimagesearch.com/2019/09/16/install-opencv-4-on-raspberry-pi-4-and-raspbian-buster/

为了浏览库和用法示例,让我们克隆它并安装所需的软件包:

$ git clone https://github.com/jagin/dvg-utils.git
$ cd ./dvg-utils
$ pip install tqdm pyyaml numpy
$ pip install opencv-contrib-python
$ pip install dvg-utils

命令行工具

安装dvg-utils后,你可以访问dvg-utils工具命令:

  • 将视频文件转换为一组图像

$ dvg-utils v2i -i assets/videos/faces.mp4 -o output --display
  • 将一组帧图像转换为视频文件

$ dvg-utils i2v -i output -o output/my_new_file.avi --display
  • 绘制指标(我将在本故事的后面部分对此进行详细介绍)

对于参数描述,请运行以下命令之一:

$ dvg-utils v2i -h
$ dvg-utils i2v -h
$ dvg-utils pm -h

如果可以分别处理每一帧,则将视频转换为图像并返回,你可以并行处理这些帧,然后将它们组合回带有可视注释的视频文件中。

捕获视频

dvg-utils的强大功能来自于从OpenCV cv2.VideoCapture和树莓派相机支持的所有源捕获视频流,使用单线:

video_capture = VideoCapture(conf["videoCapture"]).open()

技巧是使用conf["videoCapture"],其中包含我们的视频捕获配置的字典,该字典从YAML配置文件中读取,参考:https://medium.com/swlh/python-yaml-configuration-with-environment-variables-parsing-77930f4273ac (向Maria Karanasou致谢,她使用环境变量parsing进行了Python YAML配置)

videoCapture:capture: filefile:src: assets/videos/cars_driving.mp4# You can select the frame range for a video file# start_frame: 100# end_frame: 500camera:src: 0fourcc: MJPGresolution: [640, 480]fps: 30piCamera:src: 0resolution: [640, 480]framerate: 30settings:rotation: 180stream:# Jetson Nano camera streamsrc: >-nvarguscamerasrc sensor-id=0 sensor_mode=3 !video/x-raw(memory:NVMM), width=(int)1280, height=(int)720, format=(string)NV12, framerate=(fraction)30/1 !nvvidconv flip-method=2 !video/x-raw, width=(int)640, height=(int)480, format=(string)BGRx !videoconvert !video/x-raw, format=(string)BGR !appsinkapi_preference: CAP_GSTREAMER

我们可以定义不同的来源(filecamerapiCamerastream),但我们想要选择的属性在videoCapture.capture里面(在上面的例子中是assets/videos/cars_driving.mp4文件)。

让我们运行./examples/capture_video.py示例以查看实际效果:

$ python ./examples/capture_video.py
INFO: Load configuration from config/capture_video.yml
INFO: Capturing file: assets/videos/cars_driving.mp4
INFO: Codec: avc1
INFO: Resolution: 1280x720
INFO: FPS: 50.0
INFO: Capturing...
INFO: 3000 it, 13.106 s, 0.004 s/it, 228.89 it/s
3000it [00:13, 228.88it/s]

这个简单的例子是你学习视频处理管道的一个很好的起点。它已经包括:

  • 配置文件 config/capture_video.yml,它规定可在不同平台上使用的不同的视频源

  • 记录器来显示可用信息:记录器选项在 logger.yml 文件中定义,我们通过 setup_logger()dvgutil 包中调用函数来进行设置,

  • 显示带有处理后的帧数和预测的FPS结果dvgutils.vis带有helper函数的程序包可以很好地放置一些文本,绘制覆盖矩形或调整图像大小,并保留长宽比或填充,

  • 保存带注释的输出视频选项:包中有SaveVideoSaveImage类,dvgutils.modules可轻松保存视频和图像,

  • 用于保存有关管道性能的指标选项:通过包中的Metrics类,dvgutils.modules可以收集指标(如迭代时间,每秒迭代次数,每次迭代的秒数),你可以使用dvg-utils pm命令进行绘制。

这是完整的选项列表:

$ python ./examples/capture_video.py -h
usage: capture_video.py [-h] [-cf CONF][-cfo CONF_OVERWRITES [CONF_OVERWRITES ...]][-o OUTPUT] [--no-display] [--no-progress][--pipeline] [--metrics METRICS] [--fps FPS]
optional arguments:-h, --help            show this help message and exit-cf CONF, --conf CONFPath to the input configuration file (default:config/capture_video.yml)-cfo CONF_OVERWRITES [CONF_OVERWRITES ...], --conf-overwrites CONF_OVERWRITES [CONF_OVERWRITES ...]-o OUTPUT, --output OUTPUToutput video file name--no-display          hide display window--no-progress         don't display progress--pipeline            run as pipeline--metrics METRICS     metrics file name--fps FPS             output video fps

之前我提到过,我们可以使用其他输入源来运行管道。如何实现呢?有两种方法:

  • config/capture_video.yml部分设置capture属性videoCapture到选定的源(filecamerapiCamerastream

  • 使用选项-cfo videoCapture.capture=<selected_source>执行管道,该选项将覆盖YAML配置中的设置。

要使用网络摄像头执行示例,请运行:

$ python ./examples/capture_video.py -cfo videoCapture.capture=camera

如果你在树莓派上运行示例,则需要在树莓派上运行pip install picamera

你可以通过在显示屏上按ESC(只是将其关闭或在终端中按Ctrl + C)来中断该处理,所有这些操作都在dvgutils.modulesShowImage类中处理。

capture_video.py示例包含两个不同的实现方式,用于说明目的。第一个是一个简单的while循环,其中我们使用dvg-utils包中的通用类处理视频帧:

# Setup processing modules
video_capture = VideoCapture(conf["videoCapture"]).open()
save_video = SaveVideo(args["output"])
show_image = ShowImage("Video")
metrics = Metrics().start()
progress = Progress(disable=not args["progress"])
while True:# Grab the frameframe = video_capture.read()if frame is None:break... # Do some processing and visualizationsave_video(frame)show = show_image(frame)if not show:breakmetrics.update()progress.update()idx += 1

第二个基于流水线的概念,在流水线的概念中,我们定义了处理块,并借助Python生成器将数据推送到该流(CaptureVideoPipe是一个生成器,生成的帧数据通过管道步骤进行映射)。

# Setup pipeline steps
capture_video_pipe = CaptureVideoPipe(conf["videoCapture"])
save_video_pipe = SaveVideoPipe("vis_image", args["output"])
show_image_pipe = ShowImagePipe("vis_image", "Video")
metrics_pipe = MetricsPipe()
progress_pipe = ProgressPipe(disable=not args["progress"])# Create pipeline
pipeline = Pipeline(capture_video_pipe)
pipeline.map(...)  # Do some processing and visualization
pipeline.map(save_video_pipe)
pipeline.map(show_image_pipe)
pipeline.map(metrics_pipe)
pipeline.map(progress_pipe)# Process pipeline
pipeline.run()

创建模块化管道可以使我们有机会在不同项目中重用通用块。

捕获图像

使用dvg-utils,你可以几乎以与视频帧相同的方式来处理图像。examples/capture_image.py是一个很好的示例。

使用以下配置(config/capture_image.yml):

imageCapture:path: assets/images/friendsvalid_ext: jpg#contains: some_string# Transform imagetransform:resize:width: 320flip: 1  # 0 - vertical, 1 - horizontal, -1 - vertical and horizontal

你可以从assets/images/friends目录中读取所有JPG文件,甚至在它们运行你的处理代码之前对其进行转换:

$ python ./examples/capture_image.py

例子

dvg-utils包含许多示例,这些示例说明了如何构建图像或视频处理管道。让我们在 examples 文件夹中看看其中的一些示例。

对象检测

我们可以使用以下命令运行对象检测示例:

$ python ./examples/detect_object_video.py
INFO: Load configuration from config/detect_object_video.yml
INFO: Capturing file: assets/videos/people_walking.mp4
INFO: Codec: avc1
INFO: Resolution: 402x300
INFO: FPS: 30.0
INFO: Capturing...
INFO: 1283 it, 54.567 s, 0.043 s/it, 23.51 it/s
1283it [00:54, 23.51it/s]

该示例默认情况下会检测行人。

只需进行少量配置,即可在需要时检测汽车:

$ python ./examples/detect_object_video.py -cfo videoCapture.file.src=assets/videos/cars_driving.mp4 objectDetector.caffe.classes=\["cars"\]

detect_object_video.pyexamples/modules/object_detector/caffe_object_detector.py中使用Caffe MobileNet-SSD模型,并在config/detect_object_video.yml中进行配置(请参阅objectDetector部分)。

  • Caffe MobileNet-SSD:https://github.com/chuanqi305/MobileNet-SSD

对象跟踪

要跟踪对象,我们需要先对其进行检测。我们已经有了对象检测器,可以在跟踪管道中重用它(此示例需要pip install scipy dlib):

$ python ./examples/track_object_video.py
INFO: Load configuration from config/track_object_video.yml
INFO: Capturing file: assets/videos/people_walking.mp4
INFO: Codec: avc1
INFO: Resolution: 402x300
INFO: FPS: 30.0
INFO: Capturing...
INFO: 1283 it, 11.233 s, 0.009 s/it, 114.21 it/s
1283it [00:11, 114.17it/s]

在我们的例子中,我们可以使用管道来实现这两种目标跟踪算法。一个基于OpenCV Tracking API (默认使用KCF tracker),第二个基于Dlib包。你可以通过在config/track_object_video.yml中改变objectTracker.tracker 设置来激活它,或者运行:

$ python ./examples/track_object_video.py -cfo objectTracker.tracker=dlib

以下文章对两种跟踪器都有很好的解释:

  • 使用OpenCV跟踪对象

    • https://www.learnopencv.com/object-tracking-using-opencv-cpp-python/

  • 使用dlib进行对象跟踪

    • https://www.pyimagesearch.com/2018/10/22/object-tracking-with-dlib/

这个例子说明了尝试不同算法是多么容易。

对象计数

目标检测是跟踪的基础,目标跟踪是对被定义的虚拟线中的对象进行计数。这条线可能是商店的入口,而目标可能是一个人,所有这些我们都可以在不触及代码行的情况下进行配置。

要查看运行中的对象计数器,请执行以下操作:

$ python ./examples/count_object_video.py
INFO: Load configuration from config/count_object_video.yml
INFO: Capturing file: assets/videos/people_walking.mp4
INFO: Codec: avc1
INFO: Resolution: 402x300
INFO: FPS: 30.0
INFO: Capturing...
INFO: 1283 it, 11.631 s, 0.009 s/it, 110.31 it/s
1283it [00:11, 110.27it/s]  

本文很好地描述了此示例的思想:

  • OpenCV人群计数

    • https://www.pyimagesearch.com/2018/08/13/opencv-people-counter/

但我将其扩展为可以在图像的任何位置定义任何行(多亏有dvgutils.vis????),它在config/count_object_video.yml中具有:

objectCounter:line: [10, 220, 290, 120] # x1, y1, x2, y2

指标

使用不同的算法,解决方案或方法进行试验需要评估指标,通过评估指标我们可以知道哪种解决方案效果最好。

dvg-utils的dvgutils.modules包含用于收集指标的Metrics类,例如:

  • 迭代执行时间

  • 每秒平均迭代次数

  • 每次迭代的平均毫秒数

让我们运行带有--metrics选项的对象计数器示例:

$ python ./examples/count_object_video.py --metrics output/count_object_video.csv

将指标保存到output/count_object_video.csv文件中。

为了显示算法在FPS(每秒处理的帧数或迭代数)上下文中的性能,我们使用dvg-utils命令行工具(此命令要求pip install matplotlib):

$ dvg-utils pm output/count_object_video.csv -c ips

我们可以在对象计数器中使用Dlib跟踪器代替OpenCV的KCF :

$ python ./examples/count_object_video.py --metrics output/count_object_video_dlib.csv -cfo objectTracker.tracker=dlib

并比较结果:

$ dvg-utils pm -i output/count_object_video.csv -i output/count_object_video_dlib.csv -c ips

每秒执行117次迭代(即帧),而Dlib跟踪器平均只能以71 FPS的速度运行。

概要

我希望本文可以引起你对使用dvg-utils作为OpenCV实验工具的兴趣,并能帮助你创建富有远见的想法。

使用dvg-utils的主要好处是你可以快速创建计算机视觉管道并在不同的来源(例如,台式网络摄像头,树莓派照相机,带有树莓派照相机的Jetson设备,图像和视频文件等)上对其进行测试,而无需更改代码,只需通过配置即可。

资源

我一直在学习的两个主要的资源:

  • PyImageSearch

    • https://www.pyimagesearch.com/

  • 学习OpenCV

    • https://www.learnopencv.com/

参考链接:https://medium.com/deepvisionguru/dvg-utils-a-swiss-army-knife-for-opencv-processing-pipeline-b680357c084b

☆ END ☆

如果看到这里,说明你喜欢这篇文章,请转发、点赞。微信搜索「uncle_pn」,欢迎添加小编微信「 mthler」,每日朋友圈更新一篇高质量博文。

扫描二维码添加小编↓

使用Python+OpenCV+DVG-Utils实现人群计数与目标跟踪相关推荐

  1. python dlib学习(四):单目标跟踪

    前言 dlib提供了dlib.correlation_tracker()类用于跟踪目标. 官方文档入口:http://dlib.net/python/index.html#dlib.correlati ...

  2. 从理论到实战!视频流车辆计数和目标跟踪

    点击下方卡片,关注"CVer"公众号 AI/CV重磅干货,第一时间送达 常听技术大佬侃侃而谈AI模型开发,却不知从何开始? 自动驾驶车辆分割.智慧农业小麦计数.智能硬件垃圾分拣.智 ...

  3. 基于python+opencv利用颜色,区分多个目标(附带详细代码)

    效果图 先上个效果图: 视频可能看不清,解释一下:就是通过hsv色彩空间将蓝色和红色同时识别出来,并且区分它们,画出标志标出坐标. 说明 本实验仅适用于基于色彩的识别与区分,比如多种颜色的小球的识别与 ...

  4. 计算机视觉 | Python OpenCV 3 使用背景减除进行目标检测

    北京 | 高性能计算之GPU CUDA课程11月24-26日 3天密集学习 快速带你晋级 阅读全文 >

  5. OpenCV视频目标跟踪及背景分割器

    目标跟踪 本文主要介绍cv2中的视频分析Camshift和Meanshift. 目标: 学习Meanshift算法和Camshift算法来寻找和追踪视频中的目标物体 Meanshift算法: mean ...

  6. java opencv 视频教程_OpenCV视频目标跟踪示例教程(Meanshift)

    使用Opencv中的Camshift进行视频中目标跟踪是一个不错的选择,这方面的示例很多,但是大多代码不全,或者代码存在问题,不能正常使用,这里,对很多文章进行整理后,贴出了正确可以使用的代码. 安装 ...

  7. opencv动态目标跟踪学习总结

    用opencv实现对视频中动态目标的追踪 第一步,是要建立一个编程环境,然后加载opencv的库路径等等.具体步骤在 http://www.opencv.org.cn/ 的"安装" ...

  8. Python - Opencv应用实例之头发自动分割、计数、特征统计智能分析系统

    Python-Opencv应用实例之头发自动分割.计数.特征统计智能分析系统 简介: 本文章将通过Python+Opencv基于传统图像处理算法实现头发的自动分析功能. 自动分割:对图像中的头发丝实现 ...

  9. 图片人群计数模型代码运行指南

    PaperWithCode 八大数据集模型排名:https://paperswithcode.com/task/crowd-counting 搜索关键词 "人群计数"(crowd ...

最新文章

  1. 大赛归来的你们,依然青春少年
  2. Java多线程之线程间协作 notify与wait的使用
  3. 网站渗透测试,看这篇就够了
  4. 非线性回归模型(part2)--支持向量机
  5. 蚂蚁保护板_南京文明施工规范装修公司哪家好 红蚂蚁装饰标准施工分享你
  6. 对使用CodeSmith模板生成NHibernate的代码的分析
  7. 一个小厂前端 Leader 如何筛选候选人?
  8. 内核使用硬件ip的dma,dma_alloc_coherent 与 dma_alloc_writecombine (转)
  9. array 前端面试题_一则关于js数组的前端面试题
  10. mysql查询单表的销售额_MYsql数据库单表百万数据量查询
  11. 数字信号处理基础总结--7.28
  12. 机器学习之多层感知机理论与实践
  13. 转:单片机C语言中的data,idata,xdata,pdata,code
  14. 深入浅出 卡尔曼滤波
  15. 企业版微信公众号从零开始之二(申请认证流程)
  16. 什么专业要学计算机思维导论,大学计算机:计算思维导论CAP
  17. ADF4350调试笔记
  18. 从Python爬虫到Spark预处理数据的真实需求[三]
  19. Python基础之占位符
  20. 数字孪生银行项目经典案例

热门文章

  1. 拟合时用sigmoid函数代替阶跃函数
  2. 12个常用前端UI框架集都在这了!!!
  3. 什么叫电阻和电阻率?什么叫电导和电导率?
  4. 技术实践 | 在线 KTV 实现过程(内附demo体验)
  5. 笔录软件在linux系统,linux下f但tp服务器架设笔录.doc
  6. 解决Pygal图标没有交互性问题:鼠标移到图表中图形,无法显示相关联数据
  7. 内容付费的分类与分析
  8. GTY's math problem (BestCoder Round #29 A)
  9. 拒绝服务 DDoS 攻击
  10. Vue2中插槽使用——默认插槽、具名插槽、作用域插槽