본 저장소는 소비자용 스마트폰 2대(front: 포수 뒤, side: 1루 측) 만으로 야구공의 3D 궤적을 복원하고 KBO ABS 2-plane 규칙으로 Strike/Ball을 판정하는 feasibility prototype의 코드와 재현 자료를 담는다.
front/side 두 영상에서 공을 검출하고, 홈플레이트를 기준물체로 카메라를 보정한 뒤, 두 시점을 시간 동기화하여 2-view triangulation으로 3D 점을 복원하고, polyfit으로 궤적을 적합하여 KBO 2-plane 규칙으로 판정한다. 파이프라인 단계:
- (선택) 원본 영상 → 프레임 추출
- TrackNetV4 기반 공 검출 (heatmap)
- DARK 기반 sub-pixel heatmap 디코딩 + 프레임별 불확실성 σ
- 홈플레이트 5-corner 기반 OpenCV
solvePnP캘리브레이션 - front/side ray-miss 최소화 시간 동기화
- 2-view triangulation → 3D 점
- polyfit 궤적 적합 (x는 z의 1차, y는 z의 2차) — 최종 판정 baseline
- KBO 2-plane 판정
- 시스템 판정 vs 3인 합의(human consensus) 비교
- 보고서 핵심 표(CSV) 재생성
src/: 검출·디코딩·캘리·동기화·삼각측량·3D궤적생성(make_traj3d)·궤적적합·판정·QC·검출채점(score_detection)·평가 코드scripts/: 핵심 결과 재현용 쉘 스크립트(reproduce_core·reproduce_figures·reproduce_from_video)configs/: 카메라 설정, KBO 존 파라미터, 임계값, 데이터 경로data/: 경량 메타데이터, 라벨, 캘리 파일, 3D 궤적, 인간 합의 라벨, 결과 CSVfigures/: 보고서 대표 그림outputs/: 재현 스크립트 실행 결과(생성물; gitignore)
대용량 파일은 저장소에 포함하지 않는다. 아래 Google Drive에서 받는다:
https://drive.google.com/drive/folders/1FtAQDvngMueJrikUK0oZUtI-ubVlODJu
다운로드 후 배치:
data/raw/
├─ models/ best.keras # TrackNetV4 체크포인트 (검출)
├─ clips/ # 투구 구간으로 잘린 클립(권장: 영상부터 전체 재현용)
│ ├─ front_p062.mp4 front_p066.mp4 front_p071.mp4 front_p076.mp4 front_p077.mp4
│ └─ side_p046.mp4 side_p047.mp4 side_p048.mp4 side_p050.mp4 side_p051.mp4
├─ front/ *.mp4 # (대안) front 원본 1개 — 아래 구간으로 직접 잘라 clips/ 생성
└─ side/ *.mp4 # (대안) side 원본 1개
- 클립 이름은
pitch_manifest.csv의front_clip/side_clip과 동일해야 한다. - 긴 원본 1개씩만 있으면,
pitch_manifest.csv의*_start_frame/*_end_frame구간을 채운 뒤src/video_to_frames.py(또는 ffmpeg)로 위 이름의 클립을 만든다. - 제공된 CSV/JSON만 사용하면 원본 영상 없이도 핵심 판정 표를 재현할 수 있다(§5, Tier 1).
- best.keras + 원본 영상이 있으면 검출부터 표·그림까지 한 번에 재현한다(§5.1, Tier 2).
git clone https://github.com/wlsdn66597/portable-abs-smartphone.git
cd portable-abs-smartphone
python -m venv .venv
source .venv/bin/activate # Windows: .venv\Scripts\activate
pip install -r requirements.txt
# 또는 conda: conda env create -f environment.yml && conda activate portable-abs권장 Python: 3.9 또는 3.10. (TensorFlow는 검출 단계(Tier 2)에만 필요.)
bash scripts/reproduce_core.sh스크립트는 검출 성능표 → KBO 2-plane 판정(traj3d → polyfit → 판정) → hold-out 외삽 → 타자 신장 민감도(170~190 cm 재판정) → QC → 3인 합의 비교 → 기준표 대조를 수행한다.
예상 생성물:
outputs/
├─ detection_stats.csv
├─ abs_decision_2plane.csv
├─ holdout_extrap.csv
├─ height_sensitivity.csv
├─ qc_summary.csv
└─ human_reference_eval.csv
생성물은 data/results/의 기준 CSV와 일치해야 한다.
그림(시각화)도 CSV만으로 재생성한다(영상 불요):
bash scripts/reproduce_figures.sh # -> outputs/figures/ (존 산점도·궤적·hold-out·신장 민감도)best.keras 와 §3 의 클립 영상을 data/raw/ 에 배치하면, 검출 → 3D 복원 → KBO 판정 →
표·그림 전 과정을 한 번에 재현한다:
bash scripts/reproduce_from_video.sh
# 경로 변경: MODEL=path/best.keras CLIPS=path/clips DECODER=dark bash scripts/reproduce_from_video.sh파이프라인 단계:
src/run_tracknet.py— 각 클립 영상 → per-clip 예측 CSV(DARK 디코딩)src/make_traj3d.py— 예측 + 투구별 캘리 + sync →data/trajectories/traj3d_*.csvscripts/reproduce_core.sh구성 단계 → 표(2-plane 판정/hold-out/신장/QC/인간합의)scripts/reproduce_figures.sh→ 그림src/score_detection.py— (선택) 라벨 대비 검출 지표
재현 단위 주의:
- Tier 2 는 검출을 다시 돌리고 sync 를 서브프레임으로 정렬하므로, 판정/이유는 표3과
동일하지만
mid/end좌표는 약 ±2 cm 흔들린다. 그래서 대조는--tol 2.5(cm)로 한다. 바이트 단위로 동일한 표3 가 필요하면 제공 CSV(Tier 1)를 쓴다. - 검출 지표 표(F1 등)는 완전 재현 불가: 저장소에 front 라벨이 비어 있고 WASB 베이스라인
예측이 없다. 동일 분할 라벨·WASB 출력이 있으면
src/score_detection.py로 계산된다.
- 상단 = 신장 × 55.75%, 하단 = 신장 × 27.04%
- 좌우 폭 = 홈플레이트 폭 43.18 cm + 좌우 각 2 cm = 47.18 cm (반폭 ±23.59 cm)
- Strike 조건(셋 다 충족): ① 중간면 X가 좌우 존 내부 ② 중간면 Y가 상하 존 내부 ③ 끝면 Y가 상하 존 내부. 하나라도 벗어나면 Ball.
공식 ABS 출력이나 심판 ground truth를 확보할 수 없어, 프로젝트 구성원 3인이 모델 출력을
보지 않고 원본 front/side 영상만으로 독립 판정한 뒤 **다수결(majority vote)**을 합의 기준으로
삼았다. 이는 절대 ground truth가 아니며, 시스템 판정이 인간의 시각 판단과 일치하는지를
점검하는 **보조 기준(supplementary reference)**으로만 사용한다.
(data/references/human_consensus_reference.csv는 템플릿이며 평가값은 저자가 입력한다.)
- 상용 ABS 수준의 정확도를 주장하지 않는다. 본 시스템은 feasibility prototype이다.
- 검출 train/test 분할은 frame-level이다. 따라서 검출 지표는 내부 모델 선택 결과로 해석해야 하며, 투구 독립·경기 독립 일반화 성능이 아니다.
- 캘리브레이션 오차는 캘리에 사용한 동일 홈플레이트 코너점에 대한 fitting error이며 독립 공간 정확도가 아니다(체커보드 미사용, 왜곡 0 가정).
- 최종 Strike/Ball 판정은 polyfit 궤적 baseline을 사용한다.
- DARK 불확실성과 physics 기반 smoothing은 신뢰도 해석 전용이며 판정을 바꾸지 않는다.
- p048은 Ball이며 주된 이유는 끝면 높이가 아니라 중간면 X가 좌우 존 밖
(
decision_reason = mid_x_outside)이기 때문이다. - p050은 Strike, p051은 Strike이지만 약 295 cm 외삽이 필요한
long-extrapolation borderline 사례로
notes에 표시된다.
무거운 영상(GB) 대신, 복원된 3D 궤적과 스트라이크 존을 마우스로 회전·확대해 볼 수 있는 자족형 HTML 한 개(Plotly 인라인, 약 4 MB)를 예시로 포함한다. 실촬영 footage가 아니라 좌표 기반 시각화라 인물 노출이 없다.
- 보기: 파일을 내려받아 브라우저로 열면 된다(인터넷 불요).
- GitHub는 HTML을 바로 렌더하지 않으므로(소스로 표시), 온라인에서 바로 보려면
GitHub Pages를 켜거나
media/interactive_3d.html을 다운로드해 연다. - front/side 트래킹 오버레이·중계 reel 등 footage 기반 영상은 용량 때문에 포함하지 않으며, 원본 영상(Drive, §3)으로 재생성한다.