#!/opt/homebrew/bin/python3.11 """ Find the Red Inverted Triangle Stamp using OpenCV Color & Shape Detection """ import cv2 import numpy as np import os UUID = "384b0ff44aaaa1f1" BASE_DIR = f"output/{UUID}/florence2_results" IMG_NAME = "frame_6756.jpg" # Frame at 112:36 IMG_PATH = os.path.join(BASE_DIR, IMG_NAME) OUT_PATH = os.path.join(BASE_DIR, "found_stamp_opencv.jpg") print(f"📷 Loading image: {IMG_PATH}") if not os.path.exists(IMG_PATH): print("❌ Image not found.") exit() img = cv2.imread(IMG_PATH) h, w, _ = img.shape print(f"📐 Image Size: {w}x{h}") # 1. Convert to HSV Color Space hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV) # 2. Define Red Color Range in HSV # Red wraps around 180, so we need two ranges # Lower Red: Hue 0-10 lower_red1 = np.array([0, 70, 50]) upper_red1 = np.array([10, 255, 255]) mask1 = cv2.inRange(hsv, lower_red1, upper_red1) # Upper Red: Hue 170-180 lower_red2 = np.array([170, 70, 50]) upper_red2 = np.array([180, 255, 255]) mask2 = cv2.inRange(hsv, lower_red2, upper_red2) # Combine Masks mask = mask1 + mask2 # 3. Find Contours in the Mask contours, _ = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) print(f"🔍 Found {len(contours)} red regions.") # 4. Filter for Triangles (Stamp Shape) found_stamps = [] for i, cnt in enumerate(contours): # Calculate perimeter for approximation accuracy peri = cv2.arcLength(cnt, True) approx = cv2.approxPolyDP(cnt, 0.04 * peri, True) # Check for triangle (3 vertices) if len(approx) == 3: area = cv2.contourArea(approx) # Filter by size (ignore noise, ignore huge red walls) # A stamp would likely be between 500 and 20000 pixels depending on zoom if 200 < area < 50000: # Get bounding box x, y, w_box, h_box = cv2.boundingRect(approx) found_stamps.append((x, y, w_box, h_box, approx)) print( f"✅ Potential Stamp #{len(found_stamps)}: Area={area}, Box=({x},{y})" ) # 5. Draw Results result_img = img.copy() for x, y, w_box, h_box, approx in found_stamps: # Draw Box cv2.rectangle(result_img, (x, y), (x + w_box, y + h_box), (0, 255, 0), 3) # Draw Contour cv2.drawContours(result_img, [approx], 0, (255, 0, 0), 2) # Label cv2.putText( result_img, "STAMP?", (x, y - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.8, (0, 255, 0), 2 ) if found_stamps: cv2.imwrite(OUT_PATH, result_img) print(f"🎨 Result saved to: {OUT_PATH}") else: print( "❌ No red triangles found. The stamp might not be visible or red in this frame." )