#!/opt/homebrew/bin/python3.11 """ Object search using YOLO metadata """ import json import time import psycopg2 YOLO_FILE = "/Users/accusys/test_video/Old_Time_Movie_Show_-_Charade_1963.HD.yolo.json" VIDEO_UUID = "39567a0eb16f39fd" POSTGRES_CONFIG = { "host": "localhost", "port": 5432, "user": "accusys", "password": "Test3200", "database": "momentry", } def load_yolo_data(): """Load YOLO JSON data""" print(f"Loading YOLO data from {YOLO_FILE}...") with open(YOLO_FILE) as f: data = json.load(f) print(f"Loaded {len(data['frames'])} frames") return data def get_object_time_ranges(yolo_data, object_name, min_confidence=0.3): """Get time ranges where an object appears""" time_ranges = [] for frame_num, frame_data in yolo_data["frames"].items(): for det in frame_data.get("detections", []): if det["class_name"].lower() == object_name.lower(): if det["confidence"] >= min_confidence: time_ranges.append( { "start": frame_data["time_seconds"], "end": frame_data["time_seconds"] + 0.5, # Assume ~0.5s per frame "confidence": det["confidence"], } ) break # One detection per frame is enough return time_ranges def search_chunks_by_object_postgres(object_name): """Search PostgreSQL chunks by object using JSON query""" conn = psycopg2.connect(**POSTGRES_CONFIG) cur = conn.cursor() # Query chunks that have YOLO metadata containing the object query = """ SELECT chunk_id, start_time, end_time, metadata FROM chunks WHERE uuid = %s AND chunk_type = 'sentence' AND metadata IS NOT NULL AND metadata->'yolo' IS NOT NULL """ cur.execute(query, (VIDEO_UUID,)) rows = cur.fetchall() matching_chunks = [] for chunk_id, start_time, end_time, metadata in rows: yolo_data = metadata.get("yolo", {}) objects = yolo_data.get("objects", []) if any(obj.lower() == object_name.lower() for obj in objects): matching_chunks.append( { "chunk_id": chunk_id, "start_time": start_time, "end_time": end_time, } ) cur.close() conn.close() return matching_chunks def test_object_search_by_time(): """Test object search by matching timestamps""" yolo_data = load_yolo_data() test_objects = ["person", "car", "clock", "tie", "chair"] results = {} for obj in test_objects: start = time.time() # Get time ranges from YOLO time_ranges = get_object_time_ranges(yolo_data, obj) if not time_ranges: results[obj] = {"ms": 0, "chunks": 0, "frames": 0} continue # Get chunks from PostgreSQL that overlap with these time ranges conn = psycopg2.connect(**POSTGRES_CONFIG) cur = conn.cursor() # Find chunks that have any overlap with YOLO detections query = """ SELECT COUNT(DISTINCT c.chunk_id) FROM chunks c WHERE c.uuid = %s AND c.chunk_type = 'sentence' AND c.start_time <= %s AND c.end_time >= %s """ total_matches = 0 # Sample time ranges to avoid too many queries import random sample_ranges = random.sample(time_ranges, min(100, len(time_ranges))) for tr in sample_ranges: cur.execute(query, (VIDEO_UUID, tr["end"], tr["start"])) total_matches += cur.fetchone()[0] or 0 cur.close() conn.close() elapsed = (time.time() - start) * 1000 results[obj] = { "ms": round(elapsed, 2), "chunks": total_matches, "frames": len(time_ranges), } print( f"Object '{obj}': {elapsed:.2f}ms, {len(time_ranges)} frames, {total_matches} chunks" ) return results def main(): print("=" * 60) print("Object Search Test (Priority c)") print("=" * 60) results = test_object_search_by_time() print("\n" + "=" * 60) print("Summary") print("=" * 60) print(f"\n{'Object':<20} | {'Time (ms)':<12} | {'Frames':<10} | {'Chunks'}") print("-" * 60) for obj, data in results.items(): print( f"{obj:<20} | {data['ms']:<12.1f} | {data['frames']:<10} | {data['chunks']}" ) if __name__ == "__main__": main()