import cv2
import numpy as np
import glob

videos = glob.glob('output/*.mp4')
cap = cv2.VideoCapture(videos[0])

# Collect 30 continuous frames
frames = []
cap.set(cv2.CAP_PROP_POS_FRAMES, 500)
for _ in range(30):
    ret, frame = cap.read()
    if not ret: break
    frames.append(frame)
cap.release()

if len(frames) == 30:
    median_frame = np.median(frames, axis=0).astype(np.uint8)
    gray = np.max(median_frame, axis=2)
    _, binary = cv2.threshold(gray, 200, 255, cv2.THRESH_BINARY)
    
    row_sums = np.sum(binary, axis=1) / 255
    y_staff = np.where(row_sums > binary.shape[1] * 0.4)[0]
    
    if len(y_staff) > 0:
        y_top = y_staff[0]
        y_bottom = y_staff[-1]
        staff_h = y_bottom - y_top
        
        roi = binary[y_top:y_bottom, :]
        
        # 1. Bridge vertical gaps (like the gap between standard notation and tab)
        # kernel of 20px will bridge gaps up to 19px without increasing horizontal width
        bridge_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (1, 20))
        bridged = cv2.dilate(roi, bridge_kernel)
        
        # 2. Erase everything that isn't a continuous vertical line of at least 80% staff height
        # Note stems are short, so they get erased even after bridging!
        open_height = int(staff_h * 0.8)
        open_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (1, open_height))
        isolated_bars = cv2.morphologyEx(bridged, cv2.MORPH_OPEN, open_kernel)
        
        # 3. The isolated_bars image now contains ONLY thick, pure measure bars. Get their X coords.
        col_sums = np.sum(isolated_bars, axis=0) / 255
        
        # Even 1 pixel of the filtered bar is enough, but let's use a tiny threshold
        bars = np.where(col_sums > open_height * 0.5)[0]
        
        clean_bars = []
        for x in bars:
            if not clean_bars or x - clean_bars[-1] > 20:
                clean_bars.append(int(x))
                
        # Inject edges
        if not clean_bars or clean_bars[0] > 50: clean_bars.insert(0, 0)
        if clean_bars[-1] < binary.shape[1] - 50: clean_bars.append(binary.shape[1])
                
        print(f"Gap-Bridged Morphology Measure Boundaries: {clean_bars}")
        cv2.imwrite("C:/Users/Certes/Desktop/guitar_score/debug_gap_bridged.png", isolated_bars)
else:
    print("Not enough frames.")
