前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >使用NVIDIA flownet2-pytorch实现生成光流

使用NVIDIA flownet2-pytorch实现生成光流

作者头像
代码医生工作室
发布2019-07-12 11:49:16
发布2019-07-12 11:49:16
7.8K00
代码可运行
举报
文章被收录于专栏:相约机器人相约机器人
运行总次数:0
代码可运行

本博客将重点关注光流,这将通过从标准的sintel数据和自定义舞蹈视频生成光流文件来完成。

NVIDIA flownet2-pytorch

https://github.com/NVIDIA/flownet2-pytorch

Dancelogue linked repo

https://github.com/dancelogue/flownet2-pytorch

这篇博客的目标是:

  • 启动并运行flownet2-pytorch代码库。
  • 按原始存储库中提供的示例所述下载相关数据集。
  • 生成光流文件,然后研究流文件的结构。
  • 将流文件转换为颜色编码方案,使人们更容易理解。
  • 将光流生成应用于舞蹈视频并分析结果。

系统要求

flownet2-pytorch实现设计用于GPU。不幸的是这意味着如果无法访问其中一个,则无法完全关注此博客。为了减轻这个问题,由模型生成的样本的数据被提供,并且允许读者与博客的其余遵循通过。

本教程的其余部分使用ubuntu 18.04和NVIDIA GEFORCE GTX 1080 Ti GPU进行。Docker是必需的,必须启用GPU,这可以使用nvidia-docker软件包完成。

https://github.com/NVIDIA/nvidia-docker

下载代码库和数据集

以下列出了所有需要的代码和数据,以便跟进博客(下载数据已经自动化,因此读者无需手动完成,请参阅“入门”部分):

  • 可以从以下repo克隆此博客的代码库。

https://github.com/dancelogue/flownet2-pytorch

  • 可以通过单击以下链接下载sintel数据,压缩文件为5.63 GB,解压缩时增加到12.24 GB。

http://files.is.tue.mpg.de/sintel/MPI-Sintel-complete.zip

  • 可以下载定制数据,其包括样本光流.flo文件,来自样本光流文件的生成的颜色编码方案,用于进行光流的舞蹈视频,舞蹈视频的光流视频表示。

https://dancelogue.s3.amazonaws.com/open_source/datasets/generating-optical-flow-using-flownet-for-human-action-deep-learning-algorithms/000835.flo

https://dancelogue.s3.amazonaws.com/open_source/datasets/generating-optical-flow-using-flownet-for-human-action-deep-learning-algorithms/000835.flo.png

https://dancelogue.s3.amazonaws.com/open_source/datasets/generating-optical-flow-using-flownet-for-human-action-deep-learning-algorithms/sample-video.mp4

https://dancelogue.s3.amazonaws.com/open_source/datasets/generating-optical-flow-using-flownet-for-human-action-deep-learning-algorithms/sample-optical-flow-video.mp4

完成此博客所需的内存空间要求约为32 GB。其原因将在后面解释。

叉子的差异

如上所述,创建了原始flownet2-pytorch的一个分支,这是因为在撰写此博客时,原始存储库在构建和运行docker映像时遇到问题,例如python包版本问题,c库编译问题等。另外,进行了增强,以便更轻松地下载数据集。所做的更改旨在解决这些问题,可以在以下拉取请求中看到

https://github.com/dancelogue/flownet2-pytorch/pull/1/files。

  • 主要更新是Dockerfile,包括修复python包版本,更新cuda和pytorch版本,运行自动构建和安装相关层,添加ffmpeg,添加第三方github包,允许读取,处理并将流文件转换为颜色编码方案。
  • 还为数据集和训练模型添加了下载脚本,以便更容易上手,其灵感来自vid2vid存储库,该存储库也来自NVIDIA。

https://github.com/NVIDIA/vid2vid

入门

考虑到这一点,第一件事是从克隆原始存储库的dancelogue分支。然后使用以下命令运行docker脚本:

https://github.com/dancelogue/flownet2-pytorch

代码语言:javascript
代码运行次数:0
运行
复制
bash launch_docker.sh

设置应该花费几分钟之后,它应该将终端上下文更改为docker会话。

接下来是下载相关数据集,可以通过在docker上下文中运行以下命令来实现初始设置所需的所有数据:

代码语言:javascript
代码运行次数:0
运行
复制
bash scripts/download.sh

这会将FlowNet2_checkpoint.pth.tar模型权重下载到模型文件夹,以及将MPI-Sintel数据下载到数据集文件夹。这是必需的,以便按照flownet2-pytorch入门指南中所示的推理示例的说明进行操作。还下载了自定义舞蹈视频以及示例光学流.flo文件。

此博客的其余部分已自动执行,可以通过以下命令运行:

代码语言:javascript
代码运行次数:0
运行
复制
bash scripts/run.sh

运行推理示例

原始推理示例的命令如下:

代码语言:javascript
代码运行次数:0
运行
复制
python main.py --inference --model FlowNet2 --save_flow \
--inference_dataset MpiSintelClean \
--inference_dataset_root /path/to/mpi-sintel/clean/dataset \
--resume /path/to/checkpoints

但是基于fork,这已修改为:

代码语言:javascript
代码运行次数:0
运行
复制
python main.py --inference --model FlowNet2 --save_flow \
--inference_dataset MpiSintelClean \
--inference_dataset_root datasets/sintel/training \
--resume checkpoints/FlowNet2_checkpoint.pth.tar \
--save datasets/sintel/output

分解一下:

  • --model表示的是用模型的变化来使用。对于这个博客,它被设置为FlowNet2。
  • --resume参数表示训练模型权重的位置。已使用下载脚本将其下载到checkpoints文件夹中。请注意,经过训练的模型权重具有某些许可限制,如果需要在此博客之外使用它们,应该通过这些限制。
  • --inference论证仅仅意味着,基于训练数据中模型权重定义的学习能力,您可以告诉我有关新数据集的内容。这与训练模型权重将发生变化的模型不同。
  • --inference_dataset指示何种类型的数据将被送入。在目前的情况下,它是由指定的sintel MpiSintelClean。可以在链接中找到更多选项,并将其定义为类别FlyingChairs。还有一个ImagesFromFolder类,这意味着可以提供自定义数据,例如来自视频的帧,可以从中得到推论。

https://github.com/dancelogue/flownet2-pytorch/blob/master/datasets.py

  • --inference_dataset_root指示将用于推理过程,已经下载并解压到的数据的位置datasets/sintel文件夹。
  • --save_flow参数表明推断的光流应该保存为.flo文件。
  • --save参数指示哪个推断光流文件以及日志应保存到的位置。它是一个可选字段,默认为该work/位置。

运行上述命令会将生成的光流文件保存到datasets/sintel/output/inference/run.epoch-0-flow-field文件夹中。生成的光流文件具有扩展.flo,它们是流场表示。

分析和可视化光流文件

现在已经生成了光流文件,现在是时候分析结构,以便更好地理解结果,并将它们转换为流场颜色编码方案。可以从以下链接下载本节中使用的示例流文件。

https://dancelogue.s3.amazonaws.com/open_source/datasets/generating-optical-flow-using-flownet-for-human-action-deep-learning-algorithms/000835.flo

分析流文件

将光流文件加载到numpy是一个相当简单的过程,可以按如下方式进行:

代码语言:javascript
代码运行次数:0
运行
复制
path = Path('path/to/flow/file/<filename>.flo')
with path.open(mode='r') as flo:
    np_flow = np.fromfile(flo, np.float32)
    print(np_flow.shape)

上面的语法基于python3,其中文件被加载到缓冲区然后被送入numpy。接下来是尝试理解print语句实现的流文件的基本功能。假设您正在使用提供的示例流文件,这将给出以下结果(786435,)。这意味着对于每个流文件,它包含一个数组中包含786453个元素的数组。单个流文件的内存占用大约为15 MB,即使看起来微不足道,也会非常快速地增加,尤其是在查看具有数千帧的视频时。

在继续之前,需要查看链接中定义的光流规范。关心的是以下内容:

http://vision.middlebury.edu/flow/code/flow-code/README.txt

代码语言:javascript
代码运行次数:0
运行
复制
".flo" file format used for optical flow evaluation
 
Stores 2-band float image for horizontal (u) and vertical (v) flow components.
Floats are stored in little-endian order.
A flow value is considered "unknown" if either |u| or |v| is greater than 1e9.
 
  bytes  contents
 
  0-3     tag: "PIEH" in ASCII, which in little endian happens to be the float 202021.25
          (just a sanity check that floats are represented correctly)
  4-7     width as an integer
  8-11    height as an integer
  12-end  data (width*height*2*4 bytes total)
          the float values for u and v, interleaved, in row order, i.e.,
          u[row0,col0], v[row0,col0], u[row0,col1], v[row0,col1], ...

根据以上规范,以下代码将允许正确读取流文件(借用)。

https://github.com/georgegach/flow2image/blob/master/f2i.py

代码语言:javascript
代码运行次数:0
运行
复制
with path.open(mode='r') as flo:
  tag = np.fromfile(flo, np.float32, count=1)[0]
  width = np.fromfile(flo, np.int32, count=1)[0]
  height = np.fromfile(flo, np.int32, count=1)[0]
 
  print('tag', tag, 'width', width, 'height', height)
 
  nbands = 2
  tmp = np.fromfile(flo, np.float32, count= nbands * width * height)
  flow = np.resize(tmp, (int(height), int(width), int(nbands)))

基于光流格式规范,希望上面的代码应该更好地了解发生了什么,即得到标签,然后是宽度,然后是高度。print语句的输出是tag 202021.25 width 1024 height 384。根据给定的规范,可以看到标签与健全性检查值匹配,流文件的宽度为1024,高度为384.注意,正确读取文件缓冲区并将其加载到numpy中的顺序非常重要。由于在python中读取文件的方式(字节按顺序读取),否则标签,高度和宽度可能会混淆。现在有宽度和高度,可以读取剩余的光流数据并调整为更熟悉的形状,这是使用该np.resize方法完成的。

了解如何调整流向量大小的快速方法是将它们打印到终端,这可以通过运行以下代码来完成:

代码语言:javascript
代码运行次数:0
运行
复制
>> print(flow.shape)
(384, 1024, 2)
 
>> print(flow[0][0])
[-1.2117167 -1.557275]

正如所期望的那样,新表示的形状意味着高度为384,宽度为1024,并且具有由2个值组成的位移向量。关注位置处的像素,0, 0可以看到该点处的位移矢量似乎指向左侧和底部,即x,y图的左下象限,这意味着期望该位置的颜色代码为基于下面给出的颜色编码方案,浅蓝色或甚至绿色。

可视化流文件

编写了很多开源代码库来可视化光流文件。为此目的选择的那个可以在github存储库中找到。其原因在于它允许从颜色编码方案生成视频剪辑,这将在稍后阶段有用。假设使用了本教程开头提供的docker上下文,可以使用以下命令生成光流的彩色编码图像文件。

https://github.com/georgegach/flow2image

代码语言:javascript
代码运行次数:0
运行
复制
python /flow2image/f2i.py \
datasets/sintel/output/inference/run.epoch-0-flow-field/*.flo \
-o datasets/sintel/output/color_coding

这将获取光流文件并生成图像文件,其中位移矢量被颜色编码,如下所示。

在位置0,0,即图像的右下部分,确实可以看到浅蓝色并且是从位移矢量所期望的,即它是指向左侧和底部的矢量的颜色。

将光流应用于舞蹈视频

在本节中,将使用舞蹈视频,并从中生成光流文件。舞蹈视频是:

它由现实世界环境中的舞蹈编排课程组成。

生成帧

由于流网代码库接收图像,首先需要做的是将视频转换为帧,这可以通过使用ffmpeg的以下命令来完成。

代码语言:javascript
代码运行次数:0
运行
复制
ffmpeg -i datasets/dancelogue/sample-video.mp4 \
datasets/dancelogue/frames/output_%02d.png

它将在帧文件夹内以有序序列输出帧,顺序很重要,因为流网算法使用相邻图像来计算图像之间的光流。生成的帧占用1.7 GB内存,而视频仅占11.7 MB,每帧大约2 MB。

生成光流

可以通过运行以下命令来生成光流表示。

代码语言:javascript
代码运行次数:0
运行
复制
python main.py --inference --model FlowNet2 --save_flow \
--inference_dataset ImagesFromFolder \
--inference_dataset_root datasets/dancelogue/frames/ \
--resume checkpoints/FlowNet2_checkpoint.pth.tar \
--save datasets/dancelogue/output

这与使用sintel数据集运行的推理模型类似,其中差异在--inference_dataset参数中变化,ImagesFromFolder并且在代码库中定义。这--inference_dataset_root是生成的视频帧的路径。生成的光流文件占用14.6 GB的内存,这是因为对于此示例,每个光流文件大约为15.7 MB。

生成颜色代码方案

生成颜色编码方案的命令是:

代码语言:javascript
代码运行次数:0
运行
复制
python /flow2image/f2i.py \
datasets/dancelogue/output/inference/run.epoch-0-flow-field/*.flo \
-o datasets/dancelogue/output/color_coding -v -r 30

这使用了flow2image存储库以及ffmpeg。它不仅生成光流颜色编码作为.png文件,而且-v -r 30参数从图像文件生成视频30 fps。生成的颜色编码帧占用422 MB的内存,其中包含一个8.7 MB的视频文件,000000.flo.mp4如果通过此博客,则该文件具有该名称。

https://github.com/georgegach/flow2image

结果

生成的光流视频表示如下:

从生成的视频中可以看出编排的要点,不同的颜色表示运动的方向。然而可以看出,尽管视频中没有明显的运动,但在中央舞者周围仍存在很多背景噪音。不幸的是,目前尚不清楚为什么会这样。

尺寸含义

在运行流网算法时,需要了解大小含义,例如11.7 MB视频,在提取时会生成1.7 GB的单个帧文件。然而当产生光流时,这变成包含所有光流表示的14.6GB文件。这是因为每个光流文件在存储器中占据大约15.7MB,但是每个图像帧占用2MB的存储器(对于所提供的示例的情况)。因此当运行光流算法时,需要了解计算要求与空间权衡。在构建视频深度学习系统时,这种折衷将影响架构,这意味着要么根据需要生成光流文件。

结论

已经看到了如何使用NVIDIA的flownet2-pytorch实现的分支生成光流文件,以及对光流文件的概述。

参考

https://blog.dancelogue.com/what-is-optical-flow-and-why-does-it-matter/

https://blogs.nvidia.com/blog/2016/08/22/difference-deep-learning-training-inference-ai/

https://stackoverflow.com/questions/28013200/reading-middlebury-flow-files-with-python-bytes-array-numpy

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-07-05,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 相约机器人 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档