- Update ASR, face, OCR, pose processors - Add release pre-flight check script - Add synonym generation, chunk processing scripts - Add face recognition, stamp search utilities
77 lines
2.2 KiB
Python
77 lines
2.2 KiB
Python
#!/opt/homebrew/bin/python3.11
|
|
"""
|
|
Scan full video frames for stamp-like regions (Blue+Red rectangles)
|
|
"""
|
|
|
|
import cv2
|
|
import numpy as np
|
|
import os
|
|
import glob
|
|
|
|
UUID = "384b0ff44aaaa1f1"
|
|
BASE_DIR = f"output/{UUID}/full_video_scans"
|
|
OUTPUT_DIR = f"output/{UUID}/stamp_candidates_full"
|
|
|
|
os.makedirs(OUTPUT_DIR, exist_ok=True)
|
|
|
|
print("🔍 Scanning full video frames for stamps...")
|
|
|
|
frames = sorted(glob.glob(os.path.join(BASE_DIR, "frame_*.jpg")))
|
|
print(f"Found {len(frames)} frames to scan.")
|
|
|
|
total_candidates = 0
|
|
|
|
for frame_path in frames:
|
|
img = cv2.imread(frame_path)
|
|
if img is None:
|
|
continue
|
|
|
|
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
|
|
|
|
# Detect Blue regions
|
|
blue_mask = cv2.inRange(hsv, np.array([90, 40, 40]), np.array([130, 255, 255]))
|
|
|
|
# Detect Red regions
|
|
red_mask1 = cv2.inRange(hsv, np.array([0, 40, 40]), np.array([10, 255, 255]))
|
|
red_mask2 = cv2.inRange(hsv, np.array([170, 40, 40]), np.array([179, 255, 255]))
|
|
red_mask = red_mask1 + red_mask2
|
|
|
|
# Find contours in blue areas
|
|
contours, _ = cv2.findContours(
|
|
blue_mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE
|
|
)
|
|
|
|
frame_candidates = 0
|
|
|
|
for contour in contours:
|
|
area = cv2.contourArea(contour)
|
|
if area < 200 or area > 30000:
|
|
continue
|
|
|
|
x, y, w, h = cv2.boundingRect(contour)
|
|
aspect_ratio = w / h if h > 0 else 0
|
|
|
|
# Stamps are roughly rectangular
|
|
if aspect_ratio < 0.5 or aspect_ratio > 2.0:
|
|
continue
|
|
|
|
# Check red content inside
|
|
roi_red = red_mask[y : y + h, x : x + w]
|
|
red_pixels = cv2.countNonZero(roi_red)
|
|
red_ratio = red_pixels / (w * h) if w * h > 0 else 0
|
|
|
|
if red_ratio > 0.08:
|
|
frame_candidates += 1
|
|
total_candidates += 1
|
|
|
|
# Save crop
|
|
crop = img[y : y + h, x : x + w]
|
|
basename = os.path.basename(frame_path).replace(".jpg", "")
|
|
crop_name = f"stamp_{basename}_{x}_{y}_red{int(red_ratio * 100)}.jpg"
|
|
cv2.imwrite(os.path.join(OUTPUT_DIR, crop_name), crop)
|
|
|
|
if frame_candidates > 0:
|
|
print(f" 📍 {os.path.basename(frame_path)}: {frame_candidates} candidates")
|
|
|
|
print(f"\n🏁 Done. Found {total_candidates} total candidates in {OUTPUT_DIR}")
|