背景
研一的一门课上,老师要求我们阅读一篇CV方向的论文并且进行复现。当然根据自己的能力,我选择了一篇带有源码的论文,就是Bidirectional Posture-Appearance Interaction Network for Driver Behavior Recognition一篇CCF-B的文章。虽然论文中作者给出了源码地址。但在跑起来的过程中还是遇到了不少的麻烦。下面是我遇到的问题及解决的过程,供各位参考。
问题及解决过程
1.环境问题
论文中没有明确源码运行的硬件条件,后面根据源码中运行代码的命令及参数,推断出是在Linux平台上的。源码中给了environment.yml文件,实际上可以直接用conda进行一键配置。但是问题就是这是三年前的论文,有些包更新的原因,以及conda源的问题(其中最主要的是torch的cuda版本),在使用readme中给的命令并不能安装全部的包。
解决过程
先使用environment.yml文件进行安装,然后使用conda -env命令查看安装上了哪些包,和文件中的内容做对比,把那些没安装上的做成requirements.txt,再使用pip命令进行安装。其中最主要的是torch的cuda版本,在官网很难下载,速度特别慢,使用清华源下载比较好。我没有nvidia的卡,故直接使用的正常版本torch(论文源码要求的是cuda’版本的,使用非cuda的过程中因为跑不起来,怀疑是笔电的性能,租的4090服务器,发现报错一样,就省钱又在自己的笔电下继续使用非cuda的版本)
其中有个roi-align==0.0.2一直找不到,在网上查了,好像是集成到了torch中,后面跑起来也没见报那个包的缺失问题,就没管了。
2.数据集的问题
根据源码的readme中给的开源数据集的地址,下载下来数据集发现运行不起来,一直报找不到图片,这个是卡的最久的问题,主要因为readme中也没提起下下来的数据集不能直接使用,要把其中的视频切分成帧,而我一直以为源码中集成了这项功能。就一直以为源码的逻辑有问题,或者笔电性能的问题。
3.解决过程
为此还租了服务器(4090的卡),发现问题一样,这下排除了是比电性能及torch版本的问题。后面困扰了很久之后,灵光一闪,会不会是视频要处理一下!!!论文中提到了一个采用系数采样策略从视频剪辑中随机采样连续 64 帧,为了简单,我直接使用ai给生成了一个把数据集拆分成帧并且保存的程序,经历了漫长的处理过程后,在运行源码发现跑起来了。下面是切分成帧的程序:
import cv2
import os
from tqdm import tqdm
def extract_frames(video_path, output_folder):
"""
从视频中提取每一帧,并将其保存为图片,显示进度条
:param video_path: 视频文件路径
:param output_folder: 输出的文件夹路径,用于保存图片
"""
# 打开视频文件
cap = cv2.VideoCapture(video_path)
frame_count = 0
if not cap.isOpened():
print(f"无法打开视频文件 {video_path}")
return
# 获取视频总帧数
total_frames = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
# 创建输出文件夹
if not os.path.exists(output_folder):
os.makedirs(output_folder)
# 使用 tqdm 显示进度条
for _ in tqdm(range(total_frames), desc=f"处理 {video_path}", unit="帧"):
ret, frame = cap.read()
if not ret:
break
# 生成图片命名格式
frame_count += 1
img_name = f"img_{frame_count:05d}.jpg"
img_path = os.path.join(output_folder, img_name)
# 保存帧为图片
cv2.imwrite(img_path, frame)
# 释放视频对象
cap.release()
print(f"视频 {video_path} 处理完成,共提取了 {frame_count} 帧,保存在 {output_folder} 中")
def process_videos(base_folder):
"""
处理所有的视频文件,将每个视频提取的帧保存到对应文件夹
:param base_folder: 存放视频文件夹的根目录
"""
# 获取根目录下所有文件夹并按数字顺序排序
vp_folders = [f for f in os.listdir(base_folder) if os.path.isdir(os.path.join(base_folder, f))]
vp_folders.sort(key=lambda x: int(x[2:])) # 提取文件夹名称中的数字并按其排序
for folder in vp_folders:
video_folder_path = os.path.join(base_folder, folder)
videos = [f for f in os.listdir(video_folder_path) if f.endswith('.mp4')] # 假设视频是mp4格式
for video in videos:
video_path = os.path.join(video_folder_path, video)
# 修改文件夹命名,保留完整的视频文件名(去掉扩展名)
output_folder = os.path.join(video_folder_path, video.rsplit('.', 1)[0]) # 去掉扩展名
extract_frames(video_path, output_folder)
# 设置根目录
base_folder = '/home/lzw/drive/drive_dataset/inner_mirror' # 替换为你的根目录路径
# 处理所有视频
process_videos(base_folder)
总结
对于这次的经历,感悟颇深,一是自己的能力还很差,即使有源码也搞了很久,更不用说去从零复现了;二就是解决问题时,最好的方式就是把造成这一问题的可能原因列出来,一条条的去分析排除,最后总会的到答案的。
12万+

被折叠的 条评论
为什么被折叠?



