48 lines
1.5 KiB
Python
48 lines
1.5 KiB
Python
import cv2
|
|
import numpy as np
|
|
import glob
|
|
|
|
videos = glob.glob('output/*.mp4')
|
|
cap = cv2.VideoCapture(videos[0])
|
|
cap.set(cv2.CAP_PROP_POS_FRAMES, 500)
|
|
ret, frame = cap.read()
|
|
cap.release()
|
|
|
|
def _find_white_tab_strip(bgr: np.ndarray):
|
|
gray = cv2.cvtColor(bgr, cv2.COLOR_BGR2GRAY)
|
|
_, binary = cv2.threshold(gray, 200, 255, cv2.THRESH_BINARY)
|
|
h, w = binary.shape
|
|
row_white_counts = np.sum(binary, axis=1) / 255
|
|
threshold = w * 0.1
|
|
white_rows = np.where(row_white_counts > threshold)[0]
|
|
if len(white_rows) < 2: return None
|
|
return white_rows[0], white_rows[-1]
|
|
|
|
strip = _find_white_tab_strip(frame)
|
|
if strip:
|
|
y1, y2 = strip
|
|
roi = frame[y1:y2, :]
|
|
|
|
gray_roi = np.max(roi, axis=2)
|
|
_, binary = cv2.threshold(gray_roi, 200, 255, cv2.THRESH_BINARY)
|
|
|
|
col_sums = np.sum(binary, axis=0) / 255
|
|
h_roi = y2 - y1
|
|
|
|
# Relaxed to 40% to survive hand occlusions. Note stems max out at ~20-30%.
|
|
bars = np.where(col_sums > h_roi * 0.4)[0]
|
|
|
|
clean_bars = []
|
|
for x in bars:
|
|
if not clean_bars or x - clean_bars[-1] > 20: # 20px min distance
|
|
clean_bars.append(int(x))
|
|
|
|
# Include 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"Top: {y1}, Bottom: {y2}, Height: {h_roi}")
|
|
print(f"Detected Clean Measure Bars: {clean_bars}")
|
|
else:
|
|
print("Could not find tab strip.")
|