项目说明

本项目分为两个部分,第一部分是CV进行光流估计的演示,第二部分是深度学习解决光流估计的开山之作:Flownet的飞桨复现

加个链接RAFT 光流估计模型

OpenCV光流估计算法

光流估计是一个非常有趣的研究方向,可以帮助其他的机器视觉模型更好的理解视频内容,关注到视频的重点。在Flownet之前就有许多的传统算法,可以计算出光流,本部分会尽可能的描述清楚。视觉算法库OpenCV中最为常用的光流估计算法接口,包括稀疏光流估计算法cv2.calcOpticalFlowPyrLK(),和稠密光流估计cv2.calcOpticalFlowFarneback()。

稀疏光流估计算法cv2.calcOpticalFlowPyrLK()

稀疏光流估计算法为Lucas-Kanade算法,该算法为1981年由Lucas和Kanade两位科学家提出的,最为经典也较容易理解的算法,该算法作出了三个重要的假设:

  1. 亮度恒定不变,同一个像素点在连续两帧图像的亮度是相同的,不会发生改变;
  2. 时间连续或者运动是小运动,同一个像素点在连续两帧图像的位置不会剧烈变化,只会有一些微小的位移;
  3. 空间一致性,一个场景上邻近的点投影到图像上也是邻近点,且邻近点速度一致。因为光流法基本方程约束只有一个,而要求x,y方向的速度,有两个未知变量。所以需要连立n多个方程求解(这一条很难理解,下文会解释)。

基本约束方程的推导如下图所示:
在这里插入图片描述

那么问题就来了,一个方程,两个未知数无法计算,所以就用到了上面的第三个假设,在一个小范围的邻域内的像素点移动的距离是相同的,那就可以利用这个邻域内的多个像素点来求解

cv2.calcOpticalFlowPyrLK()
参数:
prevImage 前一帧图像
nextImage 当前帧图像
prevPts 待跟踪的特征点向量
winSize 搜索窗口的大小
maxLevel 最大的金字塔层数
返回:
nextPts 输出跟踪特征点向量
status 特征点是否找到,找到的状态为1,未找到的状态为0

稠密光流估计cv2.calcOpticalFlowFarneback()

和稀疏光流相比,稠密光流不仅仅是选取图像中的某些特征点(一般用角点)进行计算;而是对图像进行逐点匹配,计算所有点的偏移量,得到光流场,从而进行配准.因此其计算量会显著大于稀疏光流,但效果一般优于稀疏光流。

cv2.calcOpticalFlowFarneback(prevImg, nextImg, pyr_scale, levels, winsize, iterations, poly_n, poly_sigma, flags[, flow])
参数:
prevImg: 前一帧8-bit单通道图像
nextImg: 当前帧图像,与前一帧保持同样的格式、尺寸
pyr_scale: 金字塔上下两层之间的尺度关系,该参数一般设置为pyrScale=0.5,表示图像金字塔上一层是下一层的2倍降采样
levels:图像金字塔的层数
winsize:均值窗口大小,winsize越大,算法对图像噪声越鲁棒,并且能提升对快速运动目标的检测效果,但也会引起运动区域模糊。
iterations:算法在图像金字塔每层的迭代次数
poly_n:用于在每个像素点处计算多项式展开的相邻像素点的个数。poly_n越大,图像的近似逼近越光滑,算法鲁棒性更好,也会带来更多的运动区域模糊。通常,poly_n=5 or 7
poly_sigma:标准差,poly_n=5时,poly_sigma = 1.1;poly_n=7时,poly_sigma = 1.5
返回值:
flow:计算得到的光流

Flownet

论文地址

FlowNet: Learning Optical Flow with Convolutional Networks
ICCV 2015

网络结构

在这里插入图片描述

如上图所示就是FlowNet神经网络的大体思路。输入为两张图像,他们分别是第 t 帧以及第 t+1 帧的图像,它们首先通过一个由卷积层组成的收缩部分,用以提取各自的特征矩阵,但是这样会使图片缩小,因此需要再通过一个扩大层,将其扩展到原图大小,进行光流预测,和Unet是比较相似的。

在这里插入图片描述

上图为收缩部分的网络结构,直接将两个3维图像叠加成6维矩阵输入到网络中。(除了这种方案,还有一个FlowNetCorr方案,这种方案在本项目的后续版本中将会更新)

在这里插入图片描述

上图为放大部分的网络结构,主要是由逆卷积组成。

文件说明

work目录下的文件夹说明:

  • log存放日志
  • output存放checkpoint
  • core和models存放源码
  • datasets存放数据集
  • chirs_split.txt用于划分FlyingChairs的训练集和验证集

数据集依然使用了FlyingChairs,具体介绍可以参考这个项目RAFT 光流估计模型

数据集处理

#清空checkpoints
# 如果没有则不用执行
# 建议每次关闭项目之前都执行一下,因为占用的空间确实很大
很大
!rm -rf /home/aistudio/work/output/*
#清空数据集
# 如果没有生成数据集则不用执行
# 建议每次关闭项目之前都执行一下,因为占用的空间确实很大
!rm -rf /home/aistudio/work/datasets/*
# 创建数据集的指令和代码,因为飞椅数据集较大,我分两部分上传:ppm和flow部分,ppm文件是视频帧,flow文件是光流
%cd /home/aistudio/
# 创建飞椅数据集所需的文件夹
!mkdir work/datasets
!mkdir work/datasets/FlyingChairs_release
!mkdir work/datasets/FlyingChairs_release/data
# 解压飞椅数据集
!unzip -oq /home/aistudio/data/data152386/ppm.zip -d /home/aistudio/work/datasets/FlyingChairs_release/data/
!unzip -oq /home/aistudio/data/data152386/flow.zip -d /home/aistudio/work/datasets/FlyingChairs_release/data/
from shutil import move
import os
flist = os.listdir('/home/aistudio/work/datasets/FlyingChairs_release/data/ppm/')
for f in flist:
    move('/home/aistudio/work/datasets/FlyingChairs_release/data/ppm/' + f, '/home/aistudio/work/datasets/FlyingChairs_release/data/')
flist = os.listdir('/home/aistudio/work/datasets/FlyingChairs_release/data/flow/')
for f in flist:
    move('/home/aistudio/work/datasets/FlyingChairs_release/data/flow/' + f, '/home/aistudio/work/datasets/FlyingChairs_release/data/')
os.rmdir('/home/aistudio/work/datasets/FlyingChairs_release/data/ppm/')
os.rmdir('/home/aistudio/work/datasets/FlyingChairs_release/data/flow/')
# 打印结果,看是否可以得到except的数字
print('except:68616  get: %i' % len(os.listdir('/home/aistudio/work/datasets/FlyingChairs_release/data/')))
/home/aistudio
mkdir: cannot create directory ‘work/datasets’: File exists
except:68616  get: 68616

模型训练及验证

# 具体参数的调整可以在train.py的58~68行进行修改
# 由于本身就是光流估计的初代模型,且发布时间久远,flownet的启发意义大于模型的效果,不必特意追求该模型的拟合效果
%cd /home/aistudio/work
!python train.py  
/home/aistudio/work

感谢燕大伯乐智荐课题组的大力支持!

感谢WJY给我带来许多乐趣!

声明

此项目为搬运
原项目链接

Logo

学大模型,用大模型上飞桨星河社区!每天8点V100G算力免费领!免费领取ERNIE 4.0 100w Token >>>

更多推荐