update yolov26

This commit is contained in:
2026-01-30 12:08:36 +08:00
parent 99b2a40035
commit c01b1f41be
4 changed files with 95 additions and 10 deletions

2
.gitignore vendored
View File

@@ -1 +1,3 @@
.DS_Store .DS_Store
debug_detections
debug_detectionso

55
compare_dirs.py Normal file
View File

@@ -0,0 +1,55 @@
import os
import sys
import argparse
def compare_directories(dir_a, dir_b):
if not os.path.isdir(dir_a):
print(f"错误: 目录 '{dir_a}' 不存在。")
return
if not os.path.isdir(dir_b):
print(f"错误: 目录 '{dir_b}' 不存在。")
return
def get_prefix(filename):
if "_frame_" in filename:
return filename.split("_frame_")[0]
return filename
# 获取文件名到前缀的映射
files_a_map = {get_prefix(f): f for f in os.listdir(dir_a) if os.path.isfile(os.path.join(dir_a, f))}
files_b_map = {get_prefix(f): f for f in os.listdir(dir_b) if os.path.isfile(os.path.join(dir_b, f))}
prefixes_a = set(files_a_map.keys())
prefixes_b = set(files_b_map.keys())
only_in_a_prefixes = sorted(list(prefixes_a - prefixes_b))
only_in_b_prefixes = sorted(list(prefixes_b - prefixes_a))
both_prefixes = sorted(list(prefixes_a & prefixes_b))
print(f"目录 A: {dir_a} (前缀总数: {len(prefixes_a)})")
print(f"目录 B: {dir_b} (前缀总数: {len(prefixes_b)})")
print("-" * 30)
print(f"只出现在 A 的文件前缀 ({len(only_in_a_prefixes)} 个):")
if only_in_a_prefixes:
for p in only_in_a_prefixes:
print(f" - {files_a_map[p]}")
else:
print(" (无)")
print(f"\n只出现在 B 的文件前缀 ({len(only_in_b_prefixes)} 个):")
if only_in_b_prefixes:
for p in only_in_b_prefixes:
print(f" - {files_b_map[p]}")
else:
print(" (无)")
print(f"\n共同出现的前缀: {len(both_prefixes)}")
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="对比两个目录的文件名差异")
parser.add_argument("dir_a", help="第一个目录路径")
parser.add_argument("dir_b", help="第二个目录路径")
args = parser.parse_args()
compare_directories(args.dir_a, args.dir_b)

View File

@@ -1,6 +1,7 @@
import os import os
import sys import sys
import subprocess import subprocess
import time
import cv2 import cv2
import numpy as np import numpy as np
from pathlib import Path from pathlib import Path
@@ -14,7 +15,7 @@ except ImportError:
sys.exit(1) sys.exit(1)
class VideoCleaner: class VideoCleaner:
def __init__(self, model_path='yolov8n.pt', brightness_threshold=25, age_days=30): def __init__(self, model_path='yolo26n.pt', brightness_threshold=25, age_days=30):
print(f"Initializing YOLO model: {model_path}...") print(f"Initializing YOLO model: {model_path}...")
try: try:
self.model = YOLO(model_path) self.model = YOLO(model_path)
@@ -87,8 +88,8 @@ class VideoCleaner:
# Following your rules: "If it's night and no lights, delete". # Following your rules: "If it's night and no lights, delete".
# So we only need to detect humans to justify keeping the video. # So we only need to detect humans to justify keeping the video.
small_frame = cv2.resize(frame, (640, 360)) small_frame = cv2.resize(frame, (640, 360))
results = self.model(small_frame, classes=[0], verbose=False, conf=0.5) results = self.model(small_frame, classes=[0], verbose=False, conf=0.7)
debugmode=False debugmode=True
if len(results[0].boxes) > 0: if len(results[0].boxes) > 0:
if is_color: if is_color:
# --- DEBUG: Save the frame that triggered detection --- # --- DEBUG: Save the frame that triggered detection ---
@@ -119,7 +120,7 @@ class VideoCleaner:
video_path = Path(video_path).resolve() video_path = Path(video_path).resolve()
mtime = datetime.fromtimestamp(os.path.getmtime(video_path)) mtime = datetime.fromtimestamp(os.path.getmtime(video_path))
if datetime.now() - mtime < self.age_limit: if datetime.now() - mtime < self.age_limit:
return return False # 表示因为时间太新没处理
keep, reason = self.should_keep_video(video_path) keep, reason = self.should_keep_video(video_path)
if keep: if keep:
@@ -128,6 +129,7 @@ class VideoCleaner:
else: else:
print(f"Action: DELETE {video_path.name} - Reason: {reason}") print(f"Action: DELETE {video_path.name} - Reason: {reason}")
os.remove(video_path) os.remove(video_path)
return True # 表示处理了
def move_to_processed(self, video_path, processed_base_dir, input_base_dir): def move_to_processed(self, video_path, processed_base_dir, input_base_dir):
rel_path = video_path.relative_to(input_base_dir) rel_path = video_path.relative_to(input_base_dir)
@@ -140,17 +142,43 @@ class VideoCleaner:
input_path = Path(input_dir).resolve() input_path = Path(input_dir).resolve()
if not input_path.exists(): return if not input_path.exists(): return
processed_dir = input_path.parent / "processed" processed_dir = input_path.parent / "processed"
print(f"Scanning {input_path}...")
while True:
all_videos = []
# 每次循环都获取最新列表
for root, dirs, files in os.walk(input_path): for root, dirs, files in os.walk(input_path):
if "processed" in dirs: dirs.remove("processed") if "processed" in dirs: dirs.remove("processed")
for file in files: for file in files:
if file.lower().endswith(self.supported_extensions): if file.lower().endswith(self.supported_extensions):
self.process_video_file(Path(root) / file, processed_dir, input_path) full_path = Path(root) / file
all_videos.append(full_path)
if not all_videos:
print("No more files to process. Exiting.")
break
# 按修改时间排序,取最旧的一个
all_videos.sort(key=lambda x: os.path.getmtime(x))
processed_in_this_loop = False
for target_file in all_videos:
if self.process_video_file(target_file, processed_dir, input_path):
processed_in_this_loop = True
break # 处理了一个,重新获取列表
if not processed_in_this_loop:
# 如果列表里剩下的所有文件都还没到 30 天,那就退出
print("All remaining files are newer than the age limit. Exiting.")
break
if __name__ == "__main__": if __name__ == "__main__":
import argparse import argparse
parser = argparse.ArgumentParser() parser = argparse.ArgumentParser()
parser.add_argument("dir", help="Target directory") parser.add_argument("dir", help="Target directory")
parser.add_argument("--days", type=int, default=30) parser.add_argument("--days", type=int, default=30)
parser.add_argument("--model", type=str, default='yolo26n.pt', help="Path to YOLO model or model name")
args = parser.parse_args() args = parser.parse_args()
cleaner = VideoCleaner(age_days=args.days) cleaner = VideoCleaner(model_path=args.model, age_days=args.days)
cleaner.scan_and_process(args.dir) cleaner.scan_and_process(args.dir)

BIN
yolo26n.pt Normal file

Binary file not shown.