mxivideo/scripts/test_scene_detection.py

230 lines
7.8 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env python3
"""
测试场景检测功能的脚本
比较PySceneDetect和OpenCV的检测效果
"""
import sys
import os
import time
from pathlib import Path
# 添加项目根目录到Python路径
project_root = Path(__file__).parent.parent
sys.path.insert(0, str(project_root))
from python_core.services.media_manager import MediaManager
def find_test_videos():
"""查找测试视频文件"""
print("🔍 查找测试视频文件...")
# 可能的视频文件位置
search_paths = [
Path("/root/.mixvideo/temp/video_segments"),
Path("/root/.mixvideo/temp/original_videos"),
project_root / "assets" / "templates",
]
video_files = []
for search_path in search_paths:
if search_path.exists():
print(f"📁 搜索目录: {search_path}")
if search_path.is_file() and search_path.suffix.lower() in ['.mp4', '.avi', '.mov', '.mkv']:
video_files.append(str(search_path))
elif search_path.is_dir():
# 递归查找视频文件
for video_file in search_path.rglob("*"):
if video_file.is_file() and video_file.suffix.lower() in ['.mp4', '.avi', '.mov', '.mkv', '.wmv', '.flv']:
video_files.append(str(video_file))
if len(video_files) >= 5: # 限制数量
break
print(f"📊 找到 {len(video_files)} 个视频文件")
for i, video in enumerate(video_files[:5]):
file_size = Path(video).stat().st_size / 1024 / 1024
print(f" {i+1}. {Path(video).name} ({file_size:.1f} MB)")
return video_files[:3] # 只返回前3个用于测试
def test_scene_detection_methods(video_path: str):
"""测试不同的场景检测方法"""
print(f"\n🎬 测试视频: {Path(video_path).name}")
print("-" * 50)
media_manager = MediaManager()
# 获取视频基本信息
try:
video_info = media_manager._get_video_info(video_path)
print(f"📊 视频信息:")
print(f" 时长: {video_info['duration']:.2f}")
print(f" 分辨率: {video_info['width']}x{video_info['height']}")
print(f" 帧率: {video_info['fps']:.2f} fps")
print(f" 文件大小: {video_info['file_size']/1024/1024:.1f} MB")
except Exception as e:
print(f"❌ 获取视频信息失败: {e}")
return
# 测试不同的阈值
thresholds = [20.0, 30.0, 40.0]
for threshold in thresholds:
print(f"\n🔧 测试阈值: {threshold}")
# 测试PySceneDetect方法
try:
start_time = time.time()
scene_changes = media_manager._detect_scene_changes(video_path, threshold)
pyscene_time = time.time() - start_time
print(f"✅ PySceneDetect: {len(scene_changes)-1} 个场景变化 (耗时: {pyscene_time:.2f}s)")
if scene_changes:
print(f" 时间点: {[f'{t:.2f}s' for t in scene_changes[:10]]}") # 只显示前10个
except Exception as e:
print(f"❌ PySceneDetect失败: {e}")
# 测试OpenCV方法
try:
start_time = time.time()
opencv_changes = media_manager._detect_scene_changes_opencv(video_path, threshold)
opencv_time = time.time() - start_time
print(f"✅ OpenCV: {len(opencv_changes)-1} 个场景变化 (耗时: {opencv_time:.2f}s)")
if opencv_changes:
print(f" 时间点: {[f'{t:.2f}s' for t in opencv_changes[:10]]}") # 只显示前10个
except Exception as e:
print(f"❌ OpenCV失败: {e}")
def test_scene_detection_accuracy():
"""测试场景检测的准确性"""
print("\n🎯 场景检测准确性测试")
print("=" * 50)
video_files = find_test_videos()
if not video_files:
print("❌ 没有找到测试视频文件")
print("\n💡 建议:")
print("1. 先导入一些视频素材")
print("2. 或者将测试视频文件放到以下目录:")
print(" - /root/.mixvideo/temp/video_segments/")
print(" - /root/.mixvideo/temp/original_videos/")
return
for video_path in video_files:
try:
test_scene_detection_methods(video_path)
except Exception as e:
print(f"❌ 测试视频 {video_path} 失败: {e}")
continue
def benchmark_performance():
"""性能基准测试"""
print("\n⚡ 性能基准测试")
print("=" * 50)
video_files = find_test_videos()
if not video_files:
print("❌ 没有找到测试视频文件")
return
media_manager = MediaManager()
# 选择一个中等大小的视频进行测试
test_video = None
for video in video_files:
try:
size = Path(video).stat().st_size / 1024 / 1024 # MB
if 5 < size < 50: # 5-50MB的视频
test_video = video
break
except:
continue
if not test_video:
test_video = video_files[0] # 使用第一个视频
print(f"🎬 性能测试视频: {Path(test_video).name}")
methods = [
("PySceneDetect", media_manager._detect_scene_changes),
("OpenCV", media_manager._detect_scene_changes_opencv)
]
for method_name, method_func in methods:
try:
print(f"\n🔧 测试 {method_name}...")
# 多次运行取平均值
times = []
results = []
for i in range(3):
start_time = time.time()
scene_changes = method_func(test_video, 30.0)
end_time = time.time()
times.append(end_time - start_time)
results.append(len(scene_changes) - 1)
print(f" 运行 {i+1}: {end_time - start_time:.2f}s, {len(scene_changes)-1} 个场景")
avg_time = sum(times) / len(times)
avg_scenes = sum(results) / len(results)
print(f"{method_name} 平均性能:")
print(f" 平均耗时: {avg_time:.2f}s")
print(f" 平均场景数: {avg_scenes:.1f}")
except Exception as e:
print(f"{method_name} 性能测试失败: {e}")
def show_recommendations():
"""显示使用建议"""
print("\n💡 使用建议")
print("=" * 50)
print("🎯 选择合适的阈值:")
print("- 阈值 10-20: 高敏感度,适合检测细微的场景变化")
print("- 阈值 25-35: 中等敏感度,适合大多数情况 (推荐)")
print("- 阈值 40-50: 低敏感度,只检测明显的场景变化")
print("\n⚡ 性能考虑:")
print("- PySceneDetect: 更准确,但处理时间较长")
print("- OpenCV: 处理速度快,但准确性较低")
print("- 建议: 对重要视频使用PySceneDetect批量处理时使用OpenCV")
print("\n🔧 优化建议:")
print("- 对于长视频,可以先用低敏感度快速分割")
print("- 然后对重要片段使用高敏感度精细分割")
print("- 定期检查分割结果,调整阈值参数")
def main():
"""主函数"""
print("🎬 场景检测功能测试")
print("=" * 50)
try:
# 1. 测试场景检测准确性
test_scene_detection_accuracy()
# 2. 性能基准测试
benchmark_performance()
# 3. 显示使用建议
show_recommendations()
print("\n✅ 测试完成!")
except Exception as e:
print(f"❌ 测试过程中出现错误: {e}")
import traceback
traceback.print_exc()
if __name__ == "__main__":
main()