Flownet2 安装、光流估计提取笔记

前言

最近需要用到视频的光流文件,所以决定跟随前辈们的步伐,自行使用 Flownet2 提取视频光流,但是由于 Flownet2 太老了,网上的攻略也都是几年前的了,我安装的时候遇到了很多攻略里没提到的问题,被困扰了许久才解决,所以中间就打算边做边记,方便后面换新服务器的时候重新安装 Flownet2 不会太麻烦。

 

2025.03.24 更新

这篇文章提取出来的光流尺寸和视频帧的尺寸不一样,如果视频帧的尺寸是 240 * 360,提取出来的光流尺寸只有 192 * 320,如果要用官方 Flownet2 提取指定尺寸的光流,需要额外编写矫正光流图尺寸的代码。后面重新使用了其他人的提取模块提取了和视频帧尺寸一样的光流,具体也是一个视频异常检测的项目:LiUzHiAn/hf2vad

 

指南参考1:手把手安装flownet2-pytorch_resample2d-CSDN博客

指南参考2:Flownet2-PyTorch 安装使用流程-CSDN博客

 

服务器的环境:

Ubuntu 16.04,Cuda 10.2

 

1) 创建环境:

conda create -n flownet2 python=3.7

这里我用过 python 3.6 和 3.8,但后面均出现了问题无法解决,尤其是 3.6,跟着攻略走也不行,太老了不要用!

 

2) 进入环境

conda activate flownet2

 

3) 安装 gcc 7, g++ 7

sudo add-apt-repository ppa:ubuntu-toolchain-r/test 
sudo apt-get update
sudo apt-get install gcc-7
sudo apt-get install g++-7

这里我在安装的时候会提示“您的网络需要认证吗?”,需要手动上服务器进行网页认证。(非常想吐槽的一点就是以前校园网支持2台PC设备登录,但最近只能1台设备登录了,需要来回在服务器和自己电脑上认证校园网,就很不方便)

 

4) 将gcc7,g++7作为默认选项

sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-7 100
sudo update-alternatives --config gcc

sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-7 100
sudo update-alternatives --config g++

sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-7 50

这里如果之前配置过一遍后面就不用再配置了,和环境无关

 

5) 安装 Pytorch

# 失败指令
conda install pytorch==1.9.0 torchvision==0.6.1 cudatoolkit=10.2 -c pytorch
这里使用 失败指令 会卡很长时间,一直在 Solving environment,而且后面没办法执行第 8 步,直接提示没有找到包 pytorch,查阅很久,求助大模型均无果
pip install https://download.pytorch.org/whl/cu102/torch-1.12.0%2Bcu102-cp37-cp37m-linux_x86_64.whl#sha256=6cdaf3bba2733cabdb96d39d5ca5f733d5e1be9f4e27afc7dabed349dc86

在下面的网站中找到符合自己 python 版本、torchvision 版本的包,然后右键保存链接,粘贴到 pip install 后面,各个网站的连接如下(其中的 cu102 要替换成自己对应的 cuda 版本,torch 版本和 torchvision 版本也要对应上,对应关系可以看这个博客:点击跳转):

这里我安装了 pytorch-1.12.0+cu102-cp37torchvision-0.13.0+cu102-cp37

 

6) 下载 flownet2 代码

git clone https://github.com/NVIDIA/flownet2-pytorch.git
cd flownet2-pytorch

 

7)对代码进行修改

在以下三个文件

  • networks/channelnorm_package/setup.py
  • networks/resample2d_package/setup.py
  • networks/correlation_package/setup.py

作如下修改

# 原代码
cxx_args = ['-std=c++11']
# 修改后
cxx_args = ['-std=c++14']

flownet2-pytorch/utils/frame_utils.py 作如下修改

# 原代码 
from scipy.misc import imread
# 修改后
from imageio import imread

flownet2-pytorch/datasets.py 作如下修改

# 原代码
from scipy.misc import imread, imresize
# 修改后
from imageio import imread

flownet2-pytorch/networks/channelnorm_package/channelnorm.py 中作如下修改

# 原代码
class ChannelNormFunction(Function):
    @staticmethod
    def forward(ctx, input1, norm_deg=2):
        assert input1.is_contiguous()  # 在上方插入
# 修改后
class ChannelNormFunction(Function):
    @staticmethod
    def forward(ctx, input1, norm_deg=2):
        input1 = input1.contiguous()  # 新添加的代码
        assert input1.is_contiguous()

 

8) 进入 install.sh 所在文件夹后输入如下命令

./install.sh

 

9) 输入如下指令测试一下

python main.py -h

接下来就是缺啥装啥的阶段了
缺失的依赖(opencv-python 和 numpy 我没安装过不知道为何也测试成功了):

pip install tensorboardX
pip install setproctitle
pip install colorama
pip install tqdm
pip install imageio
pip install scipy
pip install matplotlib
pip install pytz
pip install opencv-python
pip install numpy

 

10) 下载预训练的权重文件

我只用 Flownet2 来做光流估计,所以直接下载训练好的权重文件,由于官方 github 仓库里的链接需要申请,等不了了就直接找了这个帖子里的百度网盘:手把手安装flownet2-pytorch_resample2d-CSDN博客

 

11) 开始正式推理

新建一个 run.sh 文件,写入如下代码

python ./flownet2-pytorch/main.py \
--inference \
--save_flow \
--model FlowNet2 \
--inference_dataset ImagesFromFolder \
--resume /path/to/your/flownet2/checkpoint \
--inference_dataset_root /path/to/your/dataset/root/ \
--save /path/to/your/saved/folder/ \
--number_gpus 1

简单了解了一下,--inference 是推理模式,--save-flow 是要将光流文件保存下来,--model 就是要使用的模型,--inference_dataset ImagesFromFolder 表示从文件夹里读取图片,--resume 是下载的权重文件路径,--inference_dataset_root 是要处理的数据集路径,里面包含图片,--save 就是光流文件保存的路径,--number_gpus 不明,有人说确保输出的光流文件数量为图片数量减1,这里没有动它。要修改的地方就是 --resume--inference_dataset_root--save 这三个路径

在准备运行 run.sh 时发现权限不够,又搜了一下如何修改权限。后面发现直接运行 run.sh 不显示报错细节。。。

 

12) 运行中出现的其他问题

①一开始运行出现了这个问题:
ValueError: Function has keyword-only parameters or annotations, use getfullargspec() API which can support them

网上各说各的,去问了 GPT,说 python 3.7 已经弃用了 getargspec,得到的解决方法是找到 utils/tools.py,定位到第 64 行,进行如下修改:

# 源代码
    argspec = inspect.getargspec(class_obj.__init__)
# 修改后
    argspec = inspect.getfullargspec(class_obj.__init__)
② 又遇到问题了
 File "/home/zlab-3/xxx/flownet_work/flownet2-pytorch/datasets.py", line 66, in __init__
    self.frame_size = frame_utils.read_gen(self.image_list[0][0]).shape
IndexError: list index out of range

GPT 的说法是 self.image_list 为空,看了源代码后发现它默认读取 MPI Sintel,这意味着如果要想让 flownet2 在我的数据集上推理,就需要添加 --inference_dataset ImagesFromFolder 。(好在后面查到解决方法了,差点打算自己搓一个 Dataset 类)

改了之后还是报错,就跑去看 ImagesFromFolder 类,发现 iext 形参(321行左右)默认是 png,手动改成了适配ped2数据集的 tif 格式,这个问题就解决了。

 

③ 又又遇到问题了
  File "/home/zlab-3/xxx/flownet_work/flownet2-pytorch/datasets.py", line 337, in __init__
    self.frame_size = frame_utils.read_gen(self.image_list[0][0]).shape
AttributeError: 'list' object has no attribute 'shape'

列表当然没有 shape 属性,那为什么是列表?噢,read_gen 返回了列表。
read_gen 是干嘛的?看了下,第 8 行应该是判断图片类型后缀是不是[png, jpeg, ppm, jpg],但是 tif 文件不在里面,后面直接就返回一个空列表。按照如下修改:

# 修改前
if ext == '.png' or ext == '.jpeg' or ext == '.ppm' or ext == '.jpg':
# 修改后
if ext in ['.png', '.jpeg', '.ppm', '.jpg', '.tif', '.tiff']

这个文件里还有一个地方需要注意,如果安装的 imageio 版本比较高,需要将 from imageio import imread 改为 from imageio.v2 import imread

 

④又又又出问题了

还是这个 read_gen 函数

   if im.shape[2] > 3:
IndexError: tuple index out of range

我的 tif 图片是灰度图,只有两个维度,得先将其复制为三个通道:

if ext in ['.png', '.jpeg', '.ppm', '.jpg', '.tif', '.tiff']:
  im = imread(file_name)
  if im.ndim == 2:                         # 添加
    im = np.stack((im, im, im), axis=-1)   # 添加
  if im.shape[2] > 3:
    return im[:,:,:3]

不清楚这样对光流的提取是否有影响。

 

成功运行

然后 Flownet2 终于成功提取出第一个视频的光流!至此模型已经跑通。接下来就是修改 run.sh 让模型开始批量处理视频:

#!/bin/bash
# 设置通用参数
CHECKPOINT="/home/zlab-3/xxx/flownet_work/checkpoints/FlowNet2_checkpoint.pth.tar"
SAVE_ROOT="/home/zlab-3/xxx/dataset/UCSD_Anomaly_Dataset.v1p2/UCSDped2/Train_Flow"
BASE_DATASET="/home/zlab-3/xxx/dataset/UCSD_Anomaly_Dataset.v1p2/UCSDped2/Train"

# 遍历 BASE_DATASET 下的所有视频文件夹(假设文件夹命名为 Train001, Train002, ...)
for folder in ${BASE_DATASET}/Train*; do
  folder_name=$(basename "$folder")
  output_dir="${SAVE_ROOT}/${folder_name}"
  mkdir -p "$output_dir"

  echo "Processing $folder, saving flow to $output_dir"

  python ./flownet2-pytorch/main.py \
    --inference \
    --save_flow \
    --model FlowNet2 \
    --inference_dataset ImagesFromFolder \
    --resume ${CHECKPOINT} \
    --inference_dataset_root ${folder} \
    --save ${output_dir} \
    --number_gpus 1
done

做完查看了一下光流图片所占空间大小,UCSDped2+ 总共的光流 .flo 文件大约占 2G,如果我直接找现成的光流文件下载会不会更快一些呢……

至少下次再需要光流文件的时候我就不用再重新走一遍 Flownet2 的“苦痛之路” 了吧😭

 

其他情况

如果遇到类似的错误:

The detected CUDA version (10.2) mismatches the version that was used to compile
PyTorch (12.1). Please make sure to use the same CUDA versions.

说明系统的 CUDA 版本和 Pytorch 的不一样,需要更新 CUDA 版本或 降级 Pytorch 的 CUDA。(尝试过升级 cuda,但是遇到 服务器 ubuntu 版本 16.04 太老,升级 ubuntu 又要花时间,又尝试降级 pytorch,但 conda 又太慢,卡了太久索性删环境从头又配了一个)

 

其他用到的指令

查看当前 ubuntu 版本

lsb_release -a

查看当前 cuda 版本

nvcc -V

为某一个 .sh 文件授予可执行权限

chmod u+x run.sh

查看当前文件夹大小

df -h
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇