- HSV-aware _trim_to_content (white ratio 30-97%) - pHash cluster dedup: dHash 32x32(1024bit), max_hamming=20 - Panoramic stitching: template matching scroll offset detection - 4-stage pipeline: MSE -> Panorama -> pHash - 1080p download priority + MAX_FRAME_WIDTH=1280 cap - test_pipeline.py with YouTube URLs and --download mode - 3 new known-issues documented - devlog + STATUS.md updated
76 lines
2.6 KiB
Python
76 lines
2.6 KiB
Python
"""video_2 진단: 왜 0 프레임인지 각 단계별 확인"""
|
|
import sys
|
|
sys.stdout.reconfigure(encoding="utf-8", errors="replace")
|
|
|
|
import cv2
|
|
import numpy as np
|
|
from pathlib import Path
|
|
import importlib.util
|
|
|
|
spec = importlib.util.spec_from_file_location("p", "youtube_tab_to_pdf.py")
|
|
p = importlib.util.module_from_spec(spec)
|
|
spec.loader.exec_module(p)
|
|
|
|
mp4 = Path("output") / "サカナクション/新宝島(エレキギターTAB) 難易度★★★ sakanaction shintakarajima.mp4"
|
|
cap = cv2.VideoCapture(str(mp4))
|
|
total = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
|
|
fps = cap.get(cv2.CAP_PROP_FPS)
|
|
|
|
# 10개 프레임 샘플
|
|
indices = np.linspace(total * 0.1, total * 0.8, 10, dtype=int)
|
|
for idx in indices:
|
|
cap.set(cv2.CAP_PROP_POS_FRAMES, idx)
|
|
ret, frame = cap.read()
|
|
if not ret:
|
|
continue
|
|
|
|
h, w = frame.shape[:2]
|
|
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
|
|
|
|
# 행별 밝기
|
|
margin_x = int(w * 0.1)
|
|
row_br = np.mean(gray[:, margin_x:w-margin_x], axis=1)
|
|
|
|
strip = p._find_white_tab_strip(frame)
|
|
has_tab = False
|
|
if strip:
|
|
top, bottom = strip
|
|
crop = frame[top:bottom, :]
|
|
has_tab = p._has_tab_content(crop)
|
|
|
|
print(f"Frame {idx:5d}: strip={strip}, has_tab={has_tab}, "
|
|
f"top_br={np.mean(row_br[:h//3]):.0f}, "
|
|
f"mid_br={np.mean(row_br[h//3:2*h//3]):.0f}, "
|
|
f"bot_br={np.mean(row_br[2*h//3:]):.0f}")
|
|
|
|
# strip이 있지만 has_tab=False인 경우 상세 진단
|
|
if strip and not has_tab:
|
|
top, bottom = strip
|
|
crop = frame[top:bottom, :]
|
|
g = cv2.cvtColor(crop, cv2.COLOR_BGR2GRAY)
|
|
ch, cw = g.shape
|
|
_, binary = cv2.threshold(g, 180, 255, cv2.THRESH_BINARY_INV)
|
|
horiz_k = cv2.getStructuringElement(cv2.MORPH_RECT, (max(cw//3, 30), 1))
|
|
horiz = cv2.morphologyEx(binary, cv2.MORPH_OPEN, horiz_k)
|
|
lines = cv2.HoughLinesP(horiz, 1, np.pi/180, threshold=40,
|
|
minLineLength=cw//4, maxLineGap=20)
|
|
nlines = 0 if lines is None else len(lines)
|
|
ys = []
|
|
if lines is not None:
|
|
for l in lines:
|
|
x1,y1,x2,y2 = l[0]
|
|
if abs(y2-y1) < max(5, abs(x2-x1)*0.05):
|
|
ys.append((y1+y2)/2)
|
|
ys.sort()
|
|
clusters = []
|
|
for y in ys:
|
|
if not clusters or y - clusters[-1] > ch * 0.02:
|
|
clusters.append(y)
|
|
print(f" → 크롭크기: {cw}x{ch}, 라인수: {nlines}, "
|
|
f"수평ys: {len(ys)}, 클러스터: {len(clusters)}")
|
|
|
|
# 디버그: 크롭 저장
|
|
cv2.imwrite(f"output/raw_dump/v2_diag_{idx}.png", crop)
|
|
|
|
cap.release()
|