230 lines
7.8 KiB
Python
230 lines
7.8 KiB
Python
#!/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()
|