import cv2 import numpy as np import glob video_path = glob.glob('output/*.mp4')[0] cap = cv2.VideoCapture(video_path) cap.set(cv2.CAP_PROP_POS_FRAMES, 500) # jump to a frame with chords and hand ret, frame = cap.read() cap.release() if not ret: print("Cannot read video frame.") exit() gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) _, binary = cv2.threshold(gray, 200, 255, cv2.THRESH_BINARY) # White text, black background # Morphological horizontal line detection horizontal_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (40, 1)) detect_horizontal = cv2.morphologyEx(binary, cv2.MORPH_OPEN, horizontal_kernel, iterations=2) # Morphological vertical line detection vertical_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (1, 30)) detect_vertical = cv2.morphologyEx(binary, cv2.MORPH_OPEN, vertical_kernel, iterations=2) # Find staves row_sums = np.sum(detect_horizontal, axis=1) / 255 y_staves = np.where(row_sums > binary.shape[1] * 0.4)[0] if len(y_staves) > 0: print(f"Top staff line Y: {y_staves[0]}") print(f"Bottom staff line Y: {y_staves[-1]}") # Restrict vertical detection to within the staff lines staff_crop = detect_vertical[y_staves[0]:y_staves[-1], :] col_sums = np.sum(staff_crop, axis=0) / 255 bars = np.where(col_sums > (y_staves[-1] - y_staves[0]) * 0.6)[0] # Filter bars that are too close (thickness) clean_bars = [] for x in bars: if not clean_bars or x - clean_bars[-1] > 10: clean_bars.append(x) print(f"Measure bars X: {clean_bars}") else: print("No staves detected.") cv2.imwrite("C:/Users/Certes/Desktop/guitar_score/debug_morph_horiz.png", detect_horizontal) cv2.imwrite("C:/Users/Certes/Desktop/guitar_score/debug_morph_vert.png", detect_vertical)