import cv2 import numpy as np import os from PIL import Image from image_module import analyze_image def analyze_video(video_path, num_samples=10): """ 使用 OpenCV 对视频进行均匀抽帧,并复用图像引擎进行鉴别 :param video_path: 视频文件的路径 :param num_samples: 准备抽取的代表性帧数(默认 10 帧) """ # 1. 打开视频文件 cap = cv2.VideoCapture(video_path) if not cap.isOpened(): return {"error": "无法打开视频文件"} # 2. 获取视频的基础信息 total_frames = int(cap.get(cv2.CAP_PROP_FRAME_COUNT)) fps = cap.get(cv2.CAP_PROP_FPS) # 3. 计算均匀抽帧的索引 (比如从 300 帧里均匀选 10 个时间点) if total_frames < num_samples: num_samples = total_frames # 如果视频太短,有几帧抽几帧 intervals = np.linspace(0, total_frames - 1, num_samples, dtype=int) frame_scores = [] # 4. 开始逐帧提取 for frame_idx in intervals: cap.set(cv2.CAP_PROP_POS_FRAMES, frame_idx) # 跳转到指定帧 ret, frame = cap.read() if ret: # OpenCV 默认读取的是 BGR 格式,我们需要转成正常的 RGB 格式 frame_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) pil_img = Image.fromarray(frame_rgb) # 临时保存为图片文件,喂给咱们之前写好的图像模块 temp_path = f"temp_frame_{frame_idx}.jpg" pil_img.save(temp_path) try: # 🌟 核心:直接调用咱们炼好的图像鉴别引擎! result = analyze_image(temp_path) frame_scores.append(result['final_probability']) finally: # 阅后即焚,清理临时文件 if os.path.exists(temp_path): os.remove(temp_path) cap.release() if not frame_scores: return {"error": "未能成功提取任何视频帧"} # 5. 综合计算这 10 张图的得分 avg_score = np.mean(frame_scores) max_score = np.max(frame_scores) # 记录最可疑的一帧 return { "avg_probability": avg_score, "max_probability": max_score, "sampled_frames": num_samples, "total_frames": total_frames, "fps": fps }