本次的音视频赛道是之前没有接触过的领域,因此这次主要是利用chatGPT等工具,对baseline的内容代码进行理解和分析。
1.1 数据的分析工作
'''
代码解释:统计文件的行数
!表示在jupyter中执行shell命令的符号
wc 表示一种统计文件的字数,行数的工具
-l 表示选项,统计文件的行数'''
!wc -l /kaggle/input/ffdv-sample-dataset/ffdv_phase1_sample/train_label.txt !wc -l /kaggle/input/ffdv-sample-dataset/ffdv_phase1_sample/val_label.txt
1.2 对于导入库的理解
'''
torch.manual_seed:设置随机种子,保证可重复性
cudnn: 为NVIDIA用于加速学习的库
torch.backends.cudnn.deterministic: 是否使用确定性的算法,这里为不保证确定性,选择性能
benchmark: 基准
torch.backends.cudnn.benchmark:进行基准测试,选择性能最佳算法运算
cv2:opencv的库,用于处理图像
glob:处理和读取文件,按照某种模式
os:与操作系统进行交互
PIL:用于图像处理'''
import torch torch.manual_seed(100) torch.backends.cudnn.deterministic = False torch.backends.cudnn.benchmark = True import torchvision.models as models import torchvision.transforms as transforms import torchvision.datasets as datasets import torch.nn as nn import torch.nn.functional as F import torch.optim as optim from torch.autograd import Variable from torch.utils.data.dataset import Dataset import timm import time import pandas as pd import numpy as np import cv2, glob, os from PIL import Image
1.3 对于音频提取部分的理解
'''
generate_mel_spectrogram: 从视频文件生成梅尔频谱图
n_mels: 梅尔频谱图的梅尔带的数量
fmax: 梅尔频谱图的最大频率
target:梅尔频谱图的最大尺寸audio_path: 指定音频文件的保存位置
VideoFileClip:加载视频文件
video.audio.write_audiofile: 将视频的音频部分进行保存
verbose: 是否输出详细信息
y, sr: y-音频信号的波形数据, sr-采样频率
ref=np.max: 转化时按照最大的值进行参考
None: 表示大小类型不变
uint8:无符号8为整数表示,表示图像的常用方式,表示像素值
interpolation=cv2.INTER_LINEAR:图像缩放的差值算法'''
def generate_mel_spectrogram(video_path, n_mels=128, fmax=8000, target_size=(256, 256)): # 提取音频 audio_path = 'extracted_audio.wav' video = mp.VideoFileClip(video_path) video.audio.write_audiofile(audio_path, verbose=False, logger=None) # 加载音频文件 y, sr = librosa.load(audio_path) # 生成MEL频谱图 S = librosa.feature.melspectrogram(y=y, sr=sr, n_mels=n_mels) # 将频谱图转换为dB单位 S_dB = librosa.power_to_db(S, ref=np.max) # 归一化到0-255之间 S_dB_normalized = cv2.normalize(S_dB, None, 0, 255, cv2.NORM_MINMAX) # 将浮点数转换为无符号8位整型 S_dB_normalized = S_dB_normalized.astype(np.uint8) # 缩放到目标大小 img_resized = cv2.resize(S_dB_normalized, target_size, interpolation=cv2.INTER_LINEAR) return img_resized # 使用示例 video_path = '/kaggle/input/ffdv-sample-dataset/ffdv_phase1_sample/trainset/00566910c8715febe00294037a831cc3.mp4' # 替换为您的视频文件路径 mel_spectrogram_image = generate_mel_spectrogram(video_path)
1.4 图像格式转换部分的理解
# 遍历图像进行转换
'''
glob.glob:获取文件夹下,所有文件的路径
[:400]: 表示只处理前400个图像
cv2.imwrite:保存到指定路径,修改文件的后缀名为jpg
video_path.split('/')[-1]:表示提取最后一个元素,为文件名
[:-4]:切片操作,删除后四个字符,即‘.mp4’
'''
for video_path in glob.glob('/kaggle/input/ffdv-sample-dataset/ffdv_phase1_sample/trainset/*.mp4')[:400]: mel_spectrogram_image = generate_mel_spectrogram(video_path) cv2.imwrite('./ffdv_phase1_sample/trainset/' + video_path.split('/')[-1][:-4] + '.jpg', mel_spectrogram_image) # for video_path in glob.glob('/kaggle/input/ffdv-sample-dataset/ffdv_phase1_sample/valset/*.mp4'): mel_spectrogram_image = generate_mel_spectrogram(video_path) cv2.imwrite('./ffdv_phase1_sample/valset/' + video_path.split('/')[-1][:-4] + '.jpg', mel_spectrogram_image)
1.5 加载数据部分的理解
# 加载训练集的标签
# 验证集的标签
# 修改文件的名称
# 加载标签的路径信息
train_label = pd.read_csv("/kaggle/input/ffdv-sample-dataset/ffdv_phase1_sample/train_label.txt") val_label = pd.read_csv("/kaggle/input/ffdv-sample-dataset/ffdv_phase1_sample/val_label.txt") train_label['path'] = '/kaggle/working/ffdv_phase1_sample/trainset/' + train_label['video_name'].apply(lambda x: x[:-4] + '.jpg') val_label['path'] = '/kaggle/working/ffdv_phase1_sample/valset/' + val_label['video_name'].apply(lambda x: x[:-4] + '.jpg') train_label = train_label[train_label['path'].apply(os.path.exists)] val_label = val_label[val_label['path'].apply(os.path.exists)]
1.5 数据集处理部分的理解
# 自定义的数据集类
# 加载图像,并进行转化
# 转化为RGB图像,torch形式
# 返回数据集的数量
# img_path为路径列表
class FFDIDataset(Dataset): def __init__(self, img_path, img_label, transform=None): self.img_path = img_path self.img_label = img_label if transform is not None: self.transform = transform else: self.transform = None def __getitem__(self, index): img = Image.open(self.img_path[index]).convert('RGB') if self.transform is not None: img = self.transform(img) return img, torch.from_numpy(np.array(self.img_label[index])) def __len__(self): return len(self.img_path)