admin管理员组

文章数量:1566355

1、下载FlowNet2.0+Pytorch版本代码地址:

GitHub - NVIDIA/flownet2-pytorch: Pytorch implementation of FlowNet 2.0: Evolution of Optical Flow Estimation with Deep Networks

下载权重:手把手安装flownet2-pytorch_resample2d-CSDN博客 

2、环境搭建参考:手把手安装flownet2-pytorch_resample2d-CSDN博客

python3.9+CUDA11.6+torch1.12.0

"""创建一个新的conda环境"""

conda create --name flownet2 python=3.9


"""激活环境"""
conda activate flownet2

#安装gpu版本的torch1.12.0
conda install pytorch==1.12.0 torchvision==0.13.0 torchaudio==0.12.0 cudatoolkit=11.6 -c pytorch -c conda-forge

"""安装g++,gcc"""

"""#检查 gcc 是否已安装"""

conda list gcc

"""#安装gcc,g++(安装 MinGW-w64,这个包包括了 gcc、g++ 和其他一些必要的工具,是在 Windows 上进行 C/C++ 开发的一种有效方式。)"""
conda install -c msys2 m2w64-toolchain

"""#安装完成后,你可以在同一个 Conda 环境中检查 gcc,g++ 的版本,以确认安装是否成功:"""
g++ --version
gcc --version

"""#安装完成后添加路径到系统环境变量
#将 MinGW-w64 的 bin 目录添加到系统环境变量,使得你可以在任何命令行窗口中直接调用 g++:
对于 Windows:
搜索并打开“系统环境变量”设置(可以在开始菜单中搜索“环境变量”)。
在“系统属性”窗口中,点击“环境变量”。
在“系统变量”区域中找到并选择“Path”变量,然后点击“编辑”。
点击“新建”,并输入 MinGW-w64 的 bin 目录路径,如:C:\Users\YourUsername\anaconda3\envs\flownet2\Library\mingw-w64\bin
"""

"""安装其他环境,创建一个名为 requirements.txt 的文件,并将所有的依赖项列入该文件,每行一个依赖项,如下所示:"""
numpy
tensorboardX
setproctitle
colorama
tqdm
scipy
matplotlib
pytz
opencv-python
imageio

"""使用 pip 一键安装依赖"""
pip install -r requirements.txt



3、下载编译好的压缩包,到任意位置解压完在虚拟环境里安装pip install -r all.txt

来源:Flownet2 NVIDIA pytorch最新安装教程 有效的避坑教程-CSDN博客

4、修改代码:参考手把手安装flownet2-pytorch_resample2d-CSDN博客

在 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

5、报错信息:

参考:用自己的视频调用FlowNet2.0+Pytorch版本(小白日记win10)_win10 flownet-CSDN博客

修改utils\tools.py中的:

把argspec = inspect.getargspec(class_obj.__init__)替换为

argspec = inspect.getfullargspec(class_obj.__init__)

6、推理测试:参考使用FlowNet1和FlowNet2分别进行预测_训练好的flownet预训练模型-CSDN博客

i、运行png图像
import cv2
import numpy as np
import torch
import argparse
import time
import os  # 导入os模块
from models import FlowNet2
from utils.flow_utils import flow2img

"""
测试PNG图片的光流

使用说明:更改图片路径和保存路径 更改需要的图片尺寸
"""


# 路径和模型配置
image_path = 'frames/'
save_path = 'frames/result/'  # 确保这个路径正确
model_path = "FlowNet2_checkpoint.pth.tar"
crop_size = (1024, 1024)

# 检查并创建结果保存目录
if not os.path.exists(save_path):  # 检查目录是否存在
    os.makedirs(save_path)  # 如果不存在,创建目录

# 设置模型参数
parser = argparse.ArgumentParser()
parser.add_argument('--fp16', action='store_true', help='Run model in pseudo-fp16 mode (fp16 storage fp32 math).')
parser.add_argument("--rgb_max", type=float, default=255.)
args = parser.parse_args()

# 加载模型
net = FlowNet2(args).cuda()
dict = torch.load(model_path)
net.load_state_dict(dict["state_dict"])

# 获取图像文件列表并排序
files = sorted([f for f in os.listdir(image_path) if f.endswith('.png')])
num_images = len(files)

# 循环处理图像对
for i in range(num_images - 1):  # 减1因为我们是成对处理
    img1 = cv2.imread(os.path.join(image_path, files[i]))
    img2 = cv2.imread(os.path.join(image_path, files[i+1]))

    pim1 = cv2.resize(img1, crop_size, interpolation=cv2.INTER_CUBIC)
    pim2 = cv2.resize(img2, crop_size, interpolation=cv2.INTER_CUBIC)

    images = np.array([pim1, pim2]).transpose(3, 0, 1, 2)
    im = torch.from_numpy(images.astype(np.float32)).unsqueeze(0).cuda()

    start = time.time()
    result = net(im).squeeze()
    end = time.time()
    print(f'Processing time: {end-start} seconds')

    data = result.data.cpu().numpy().transpose(1, 2, 0)
    img = flow2img(data)
    cv2.imwrite(os.path.join(save_path, f'flow_{i:04d}.png'), img)
ii、运行视频文件 
import numpy as np
import cv2
import warnings
import torch
import argparse
import time
import os
from models import FlowNet2
from utils.flow_utils import flow2img

"""
按照自己的路径修改视频地址和保存地址,以及加载权重地址
"""

warnings.filterwarnings("ignore")

# 输入视频地址
cap = cv2.VideoCapture('203-seg02.mp4')

# 获取第一帧
ret, frame1 = cap.read()
prvs = frame1

# 控制实现的张数
i = 0
save_path = 'result'

# 检查并创建结果保存目录
if not os.path.exists(save_path):
    os.makedirs(save_path)

# 解析参数和模型初始化
parser = argparse.ArgumentParser()
parser.add_argument('--fp16', action='store_true', help='Run model in pseudo-fp16 mode (fp16 storage fp32 math).')
parser.add_argument("--rgb_max", type=float, default=255.)
args = parser.parse_args()

net = FlowNet2(args).cuda()
dict = torch.load("FlowNet2_checkpoint.pth.tar")
net.load_state_dict(dict["state_dict"])

while True:
    ret, frame2 = cap.read()
    if not ret:
        break

    next = frame2
    crop_size = (1024, 1024)
    pim1 = cv2.resize(prvs, crop_size, interpolation=cv2.INTER_CUBIC)
    pim2 = cv2.resize(next, crop_size, interpolation=cv2.INTER_CUBIC)

    images = [pim1, pim2]
    images = np.array(images).transpose(3, 0, 1, 2)
    im = torch.from_numpy(images.astype(np.float32)).unsqueeze(0).cuda()

    start = time.time()
    result = net(im).squeeze()
    end = time.time()
    print(f"Processing time: {end - start:.2f} seconds")

    data = result.data.cpu().numpy().transpose(1, 2, 0)
    img = flow2img(data)
    file_path = os.path.join(save_path, f'{i:04d}.png')
    cv2.imwrite(file_path, img)
    i += 1
    prvs = next
iii、将光流图片合成视频

import os
import cv2
from PIL import Image
import moviepy.editor as mov

"""
按需修改光流图片加载路径和保存路径
"""

def image_to_video(image_path, media_path):
    '''
    将目录下的图片合成为一个视频。
    
    :param image_path: 存放图片的目录
    :param media_path: 视频保存的路径
    '''
    # 获取图片文件并排序,假设文件名中的数字用于排序
    image_files = [img for img in os.listdir(image_path) if img.endswith('.png') or img.endswith('.jpg')]
    image_files.sort(key=lambda x: int(''.join(filter(str.isdigit, x))))
    
    # 检查是否有图片
    if not image_files:
        print("没有找到图片")
        return
    
    print("图片文件列表:", image_files)
    
    # 初始化视频写入器
    first_image = Image.open(os.path.join(image_path, image_files[0]))
    fourcc = cv2.VideoWriter_fourcc(*'MP4V')
    fps = 10
    video_writer = cv2.VideoWriter(media_path, fourcc, fps, first_image.size)

    # 逐一读取图片,写入视频
    for image_file in image_files:
        img_path = os.path.join(image_path, image_file)
        image = cv2.imread(img_path)
        if image is not None:
            video_writer.write(image)
            print(f"{image_file} 已合并到视频。")
        else:
            print(f"警告: {image_file} 无法读取。")

    # 释放资源
    video_writer.release()
    print('视频已保存至:', media_path)

# 使用示例
image_to_video('result', 'result/result.mp4')

7、按照官方教程运行推理生成的光流图是.flo文件不能直接可视化,于是通过下面两种方法来生成png格式的图片参考(2021-01-05 从零开始:使用Flownet2生成optical flow-CSDN博客)

# Example on MPISintel Clean   
python main.py --inference --model FlowNet2 --save_flow --inference_dataset MpiSintelClean \
--inference_dataset_root /path/to/mpi-sintel/clean/dataset \
--resume /path/to/checkpoints 
转换.flo的工具flowiz:https://github/georgegach/flowiz

安装:pip install flowiz -U

使用命令行调用:

i、将 .flo 文件转换为 .png 图像

"""
这个命令将会处理 demo/flo/ 目录下的所有 .flo 文件,
并将转换得到的 .png 图像保存在同一目录下。
"""
python -m flowiz demo/flo/*.flo
 ii、指定输出目录
"""
使用 -o 或 --outdir 参数指定输出目录:
这个命令将处理的结果保存在指定的 demo/png/ 目录下。
"""

python -m flowiz demo/flo/*.flo --outdir demo/png/
iii、将图片编译成视频
"""
使用 -v 或 --videodir 参数将转换得到的图片编译成视频文件:
这个命令会将 demo/png/ 目录下的图片编译成一个视频文件,
保存在 demo/mp4 目录下,视频的帧率为24 fps(每秒帧数)。
"""
python -m flowiz demo/flo/*.flo -o demo/png/ --videodir demo/mp4
iiii、控制视频的帧率
"""
使用 -r 或 --framerate 参数来控制输出视频的帧率
这个命令设置视频的帧率为每秒2帧,适用于创建慢动作视频或当图片数量较少时使视频播放时间更长。

"""
python -m flowiz demo/flo/*.flo -o demo/png/ -v demo/mp4 --framerate 2

使用python调用

i、转换一张图片
import flowiz as fz

"""使用 glob 模块搜索 demo/flo/ 目录下所有 .flo 文件,并将路径列表保存到 files 变量。"""
files = glob.glob('demo/flo/*.flo')
"""使用 flowiz 的 convert_from_file 函数转换列表中的第一个 .flo 文件为图像。"""
img = fz.convert_from_file(files[0])
plt.imshow(img)
ii、转换 demo/flo/ 目录下所有的 .flo 文件而不只是第一个,你可以通过循环遍历所有文件来实现这一功能。以下是修改后的 Python 代码示例,展示如何处理每个 .flo 文件并可视化或保存转换结果。
import flowiz as fz
import glob
import matplotlib.pyplot as plt

# 使用 glob.glob 获取所有 .flo 文件的路径
files = glob.glob('demo/flo/*.flo')

# 遍历文件列表,转换每一个 .flo 文件
for file in files:
    img = fz.convert_from_file(file)  # 转换文件
    plt.imshow(img)  # 显示图像
    plt.show()  # 显示每张图的窗口,你也可以选择保存图像
    """# 如果你想保存转换后的图像而不是显示,可以使用 plt.imsave"""
    # 例如:plt.imsave('output_path/' + os.path.basename(file) + '.png', img)
iii、转换成.mp4视频
确保在运行此脚本之前,你的系统已经安装了 opencv-pythonflowiz
若需处理 demo/flo/ 下的多个子文件夹中的 .flo 文件,并且为每个子文件夹生成单独的视频
import cv2
import numpy as np
import flowiz as fz
import glob
import os

# 指定 .flo 文件的顶级目录
base_directory = 'demo/flo/'
output_video_directory = 'output_videos/'
fps = 24  # 视频的帧率

# 确保视频输出目录存在
if not os.path.exists(output_video_directory):
    os.makedirs(output_video_directory)

# 遍历 base_directory 下的所有子目录
for subdir, dirs, files in os.walk(base_directory):
    for dir in dirs:
        flo_folder = os.path.join(subdir, dir)
        flo_files = glob.glob(f'{flo_folder}/*.flo')
        flo_files.sort()  # 排序确保按顺序处理

        if flo_files:
            first_image = fz.convert_from_file(flo_files[0])
            height, width, layers = first_image.shape
            output_video_path = os.path.join(output_video_directory, f'{dir}.mp4')
            video = cv2.VideoWriter(output_video_path, cv2.VideoWriter_fourcc(*'mp4v'), fps, (width, height))

            # 遍历当前子文件夹下的所有 .flo 文件,转换并写入到视频中
            for flo_file in flo_files:
                img = fz.convert_from_file(flo_file)
                img_bgr = cv2.cvtColor(img, cv2.COLOR_RGB2BGR)
                video.write(img_bgr)
                print(f'Processed {flo_file}')

            # 完成视频编码
            video.release()
            print(f'Video saved to {output_video_path}')
        else:
            print(f'No .flo files found in {flo_folder}')

本文标签: 版本VSCodePytorch