auto-mix-video / src /modules /extract_frame_static.py
yuanxuchang
git init.
ea7ef05
Raw
History Blame Contribute Delete
2.25 kB
import cv2
import torch
import numpy as np
def extract_video_features(video_path, model, processor, device):
"""提取视频关键帧特征
Args:
video_path: 视频文件路径
model: CLIP模型
processor: CLIP处理器
device: 计算设备
Returns:
features: 形状为 (n_frames, feature_dim) 的特征数组
timestamps: 对应帧的时间戳(秒)
"""
# 打开视频文件
cap = cv2.VideoCapture(video_path)
if not cap.isOpened():
raise ValueError(f"无法打开视频文件: {video_path}")
# 获取视频属性
fps = cap.get(cv2.CAP_PROP_FPS)
total_frames = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
# 处理无效帧率
if fps <= 0:
fps = 30 # 默认帧率
print(f"警告: 视频帧率无效,使用默认值 {fps}")
# 每3秒提取一帧
frame_interval = max(1, int(fps * 2)) # 确保至少为1
features = []
timestamps = []
for i in range(0, total_frames, frame_interval):
start_frame = i
cap.set(cv2.CAP_PROP_POS_FRAMES, start_frame)
ret, frame = cap.read() # 读取该位置的帧(图片)
if not ret:
break
try:
# 预处理帧
frame_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
# 提取特征
inputs = processor(images=frame_rgb, return_tensors="pt").to(device)
with torch.no_grad():
frame_features = model.get_image_features(**inputs)
# 保存结果
features.append(frame_features.cpu().numpy().squeeze()) # 去除batch维度,二维变一维(v_row维) array([ 9.67003047e-01, 7.20102668e-01, -6.19670749e-03, -1.22871208e+00, ...]
timestamps.append(start_frame / fps)
except Exception as e:
print(f"处理帧 {i} 时出错: {str(e)}")
continue
cap.release()
# 转换为numpy数组
if len(features) > 0:
features = np.vstack(features) # 形状: (n_frames, feature_dim)
timestamps = np.array(timestamps)
else:
features = np.empty((0, 512)) # 空数组
timestamps = np.array([])
return features, timestamps, total_frames, fps