import cv2 import numpy as np def find_white_tab_bounds(video_path): cap = cv2.VideoCapture(video_path) cap.set(cv2.CAP_PROP_POS_FRAMES, 30 * cap.get(cv2.CAP_PROP_FPS)) ret, frame = cap.read() cap.release() if not ret: return None scale = 1280 / frame.shape[1] frame = cv2.resize(frame, (1280, int(frame.shape[0] * scale))) gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) # Calculate row-wise mean brightness row_means = np.mean(gray, axis=1) # We are looking for the white paper background which has brightness > 230 on average # Wait, notes and black lines reduce the mean of a row. # A single black horizontal line on white reduces mean by (255 - 0) * (width/width) -> It drops to ~180 if it's thick. # Let's say any row with mean > 180 is part of the white strip. is_white_row = row_means > 180 # Find contiguous blocks of True # Pad with False to handle edges cleanly padded = np.concatenate(([False], is_white_row, [False])) diffs = np.diff(padded.astype(int)) starts = np.where(diffs == 1)[0] ends = np.where(diffs == -1)[0] best_start, best_end, max_len = 0, 0, 0 for s, e in zip(starts, ends): length = e - s if length > max_len: max_len = length best_start = s best_end = e return best_start, best_end, frame.shape[0] if __name__ == "__main__": video_path = "output/サカナクション/新宝島(エレキギターTAB) 難易度★★★ sakanaction shintakarajima.mp4" bounds = find_white_tab_bounds(video_path) if bounds: s, e, h = bounds print(f"Mathematically found White Tab Strip: Y_START={s}, Y_END={e}. Total Height={h}") else: print("Failed to find bound")