상태: 초안 (2026-10-13), 실측 반영. 표의 숫자는 2026-10-13 에 받아 둔 데이터셋 사본을 읽기 전용 임시 파드(CPU, GPU 없음)에서 ffprobe 와 파이썬 표준 라이브러리로 직접 센 값입니다. 압축 파일은 풀지 않고 안의 목록과 라벨 파일만 읽었습니다. 논문이나 공식 페이지의 숫자는 「공식」으로 따로 적었습니다. 스크립트와 원출력은 저장소
docs/experiments/2026-10-13-tt-dataset-stats/에 있습니다. 작성 규칙: 실측 데이터가 기본이고, 못 잰 것은 「미실측」으로 표시합니다.
목차
- 1. 왜 직접 세나
- 2. 한눈에
- 3. OpenTTGames: 평가의 바탕
- 4. Extended OpenTTGames: 랠리가 어떻게 끝났나
- 5. T3Set: 소리와 센서가 있는 훈련 영상
- 6. TT Sounds: 깨끗한 충돌음
- 7. RacketVision: 라켓 다섯 점(탁구 부분)
- 8. LATTE-MV: 국제 중계와 자동 추적
- 9. 덤: BlurBall 학습 데이터(공개분)
- 10. 라이선스와 우리의 방침
- 11. 다시 세는 법
- 참고
1. 왜 직접 세나
논문의 데이터셋 표는 한 번 쓰이고 나면 다시 확인되지 않습니다. 그런데 모델의 숫자는 데이터의 성질을 그대로 물려받습니다. 「공이 없다」고 표시된 프레임에 공이 보이면 정밀도가 거짓으로 떨어지고, fps 가 섞여 있으면 「프레임당 이동량」 같은 기준이 클립마다 다른 뜻이 됩니다. 그래서 쓰기 전에 직접 셉니다. 세다 보면 라벨의 함정이 드러납니다.
2. 한눈에
| 데이터셋 | 무엇 | 규모(직접 셈) | 해상도 · fps | 공 라벨 | 소리 | 라이선스 |
|---|---|---|---|---|---|---|
| OpenTTGames | 한 체육관, 옆면 고정 카메라 경기 | 영상 12편, 644,199프레임, 89.5분 | 1920×1080 · 120 | 이벤트 근처 프레임만 | 없음 | CC BY-NC-SA 4.0 |
| Extended OpenTTGames | 위 12편에 타구·랠리 종료 원인 | 랠리 종료 281, 타구 1,456 | (같은 영상) | 원본 그대로 | 없음 | CC BY-NC-SA 4.0 |
| T3Set | 아마추어 다구 훈련, 영상 + 라켓 센서 + 코치 음성 | 선수 32, 라운드 폴더 387, 영상 734개(26.9GB) | 1080p · 60(공식) | 없음(센서의 타구 시각) | 있음 | CC BY-NC-SA 4.0 |
| TT Sounds | 라켓·테이블·바닥 충돌음 | 15ms 표본 wav 6,037, 라벨 5,702, 원녹음 149 | 소리만 | — | 소리만 | CC BY-NC 4.0 |
| RacketVision(탁구만) | 국제 중계에 공·라켓 5점 | 클립 780, 50경기, 170,027프레임 | 1920×1080 · 25/30/50/59.94/60 섞임 | 있음(드문드문) | — | 카드 MIT, 원 중계 권리 불명 |
| LATTE-MV | 국제 중계 랠리 클립 + 자동 추적 결과 | 812경기, 클립 23,781 | 640×360 · 30 또는 29 | 자동 추적(사람 라벨 아님) | 없음 | 카드 Apache-2.0, 원 중계 권리 불명 |
| BlurBall 학습 데이터(공개분) | 온라인 경기 영상에 번짐 라벨 | 영상 463, 표식 66,595행 | 대부분 1280×720 · 대부분 25 | 번짐 가운데 + 각도·길이 | 일부 | 표기 없음 |
3. OpenTTGames: 평가의 바탕
TTNet 논문(arXiv 2004.09927)과 함께 공개된 데이터셋으로, TT Score 의 정확도 숫자는 거의 모두 이 위에서 나왔습니다.
영상
| 구분 | 편 | 프레임 | 길이 |
|---|---|---|---|
| 학습(game_1–5) | 5 | 542,079 | 4,517초(75.3분) |
| 시험(test_1–7) | 7 | 102,120 | 851초(14.2분) |
모두 H.264, 1920×1080, 120fps 이고 소리 트랙이 없습니다(ffprobe 로 12편 모두 영상 스트림 하나). 학습 영상 하나가 3.9–10.8GB 입니다. 휴대폰 실시간은 60fps 가 상한이라, 우리는 짝수 프레임만 써서 60fps 로 줄여 평가합니다.
라벨
경기마다 zip 하나에 세 가지가 들어 있습니다.
ball_markup.json:{"프레임": {"x": …, "y": …}}. x·y 가 −1 이면 「공 없음」.events_markup.json:{"프레임": "bounce" | "net" | "empty_event"}.segmentation_masks/*.png: 사람·테이블·점수판을 채널로 칠한 마스크. 공 표식이 있는 프레임과 정확히 같은 수가 들어 있습니다.
| 경기 | 공 표식 프레임 | 공 보임 | 공 없음 | bounce | net | empty_event |
|---|---|---|---|---|---|---|
| game_1 | 6,799 | 6,721 | 78 | 227 | 182 | 195 |
| game_2 | 17,444 | 17,275 | 169 | 591 | 430 | 536 |
| game_3 | 7,275 | 7,161 | 114 | 240 | 187 | 173 |
| game_4 | 7,073 | 6,971 | 102 | 231 | 187 | 176 |
| game_5 | 7,406 | 7,056 | 350 | 248 | 184 | 19 |
| test_1 | 887 | 880 | 7 | 31 | 24 | 1 |
| test_2 | 779 | 773 | 6 | 28 | 21 | 1 |
| test_3 | 805 | 798 | 7 | 31 | 18 | 6 |
| test_4 | 1,319 | 1,305 | 14 | 46 | 29 | 29 |
| test_5 | 1,018 | 1,008 | 10 | 34 | 26 | 5 |
| test_6 | 1,308 | 1,300 | 8 | 41 | 38 | 1 |
| test_7 | 874 | 770 | 104 | 29 | 24 | 2 |
| 합 | 52,987 | 52,018 | 969 | 1,777 | 1,350 | 1,144 |
이벤트 합 4,271 은 공식 페이지의 「이벤트 4,271개」와 정확히 맞습니다. 세는 방법이 맞다는 확인입니다.
함정
- 표식이 없는 프레임은 「공 없음」이 아니라 「모름」이다. 공 표식은 이벤트 앞 4프레임부터 뒤 12프레임까지만 있습니다(공식). 전체 644,199프레임 중 52,987프레임, 8.2% 입니다. 표식 없는 프레임을 「공 없음」으로 세면, 모델이 찾은 진짜 공이 모두 오답이 되어 정밀도가 거짓으로 크게 떨어집니다. 우리 로더(
ttscore/data/openttgames.py)는 둘을 갈라 담습니다. - test_7 의 「공 없음」은 믿을 수 없다. 다른 시험 경기의 「공 없음」은 6–14개인데 test_7 만 104개입니다. 그중 41곳은 공이 실제로 보입니다(6장을 눈으로 확인). 이 때문에 BlurBall 의 test_7 정밀도가 0.882 로 나왔고, 41곳을 빼면 0.9937 입니다(2편).
- 「net」은 대부분 네트에 닿은 것이 아니다. 이름과 달리 공이 네트 위를 지나는 순간에 달린 표식이 대부분입니다. 그 앞뒤 가로 속도 비가 0.75–1.01 로, 공이 거의 느려지지 않았습니다(5편). 네트에 「걸린」 공을 찾으려면 Extended 의 net 종료 라벨을 써야 합니다.
- empty_event 의 분포가 경기마다 크게 다르다. game_2 는 536개인데 game_5 는 19개입니다. 쓰기 전에 뜻을 확인해야 하는 라벨이라 우리는 쓰지 않습니다.
4. Extended OpenTTGames: 랠리가 어떻게 끝났나
같은 12편에 타구와 랠리 종료 원인을 붙인 확장입니다(arXiv 2512.19327, github moamal01/table_tennis_data). 우리 심판 엔진의 정답지입니다.
라벨은 경기마다 JSON 하나, {"120fps 프레임": "값"} 입니다. 값은 세 종류가 한 파일에 섞여 있습니다.
| 종류 | 예 | 직접 센 수 |
|---|---|---|
| 원래 이벤트 | bounce, net, empty_event |
3,206(원본보다 적다 — 아래 함정 1) |
| 타구 | left_forehand_serve neutral left_foot_lifted |
1,456. loop 583 · serve 290 · push 279 · block 187 · flick 65 · chop 30 · smash 12 · lob 10 |
| 랠리 종료 | right_out |
281. out 140 · net 83 · winner 34 · not_hitting_ball 10 · miss_on_own_side 10 · double_bounce 4 |
| 알 수 없음 | point, xright_… |
2 |
논문은 랠리 종료 282개를 보고했는데 원인별 합은 281 입니다. 직접 센 값도 281 이었습니다. 이 가운데 「누가 서브했는지」까지 알 수 있는 랠리 275개를 평가에 씁니다.
함정
- 같은 프레임에 두 라벨을 달면 하나가 사라진다. JSON 의 키가 프레임 번호라, 바운드가 있던 프레임에 종료 라벨을 달면 바운드가 덮입니다(실례: test_4 4530 프레임의 bounce 가 right_net 으로). test_2 에는 원래 이벤트가 아예 없습니다. 그래서 바운드·네트 정답은 이 파일이 아니라 원래 OpenTTGames 의
events_markup.json에서 읽습니다. - 접두어가 누구인지가 원인마다 다르다. README 는 접두어가 「끝을 만든 선수」라고 합니다. winner 와 double_bounce 는 접두어 선수가 점수를 따고, 나머지는 접두어 선수가 잃습니다. 직전 타구 쪽과 대조해 확인했고(winner 34개 중 30, out 140개 중 129 일치), not_hitting_ball 은 10개 중 8개가 받지 못한 선수 쪽이었습니다.
- README 의 기술 목록은 여섯인데 데이터에는 여덟이 있다. smash 와 chop 이 더 있습니다.
- 왼손잡이. test_3·test_7 에 한 명씩, test_5 에 두 명 있습니다(README). 포핸드·백핸드를 화면 방향으로 추론하면 틀립니다.
5. T3Set: 소리와 센서가 있는 훈련 영상
아마추어 다구 훈련을 두 대의 카메라와 라켓 센서(9축 IMU, 100Hz), 코치 음성으로 기록한 데이터셋입니다(KDD 2025, Zenodo). 28GB 를 분할 zip(.zip + .z01–.z38)으로 받는데, 우리는 합치거나 풀지 않고 마지막 조각의 중앙 디렉터리만 읽어 목록을 셌습니다.
| 항목 | 직접 셈 | 공식 |
|---|---|---|
| 선수 | 32 | 32 |
| 라운드 | 387 폴더 | 380 |
| 기술(라운드 폴더 수) | topspin 90 · push 89 · pendulum 43 · short 42 · block 41 · attack 41 · flick 41 | 7종 |
| 영상 | 734개(mkv 699, mp4 35), 26.9GB | 1080p 60fps 두 대 |
| 코치 음성 mp3 | 1,014 | — |
| JSON(자세·센서 정렬·코치 조언) | 2,689 | — |
영상 파일(mkv)에는 소리(AAC 44.1kHz)가 같은 컨테이너로 붙어 있습니다(2026-10-11 확인). 영상·소리·센서가 함께 있는 드문 데이터라 6편의 소리 실험에 썼습니다.
함정
- 카메라 폴더 이름에 오타가 있다. 대부분
remote(376)와right(354)인데,romote1,rIGHT2,rIght1 이 섞여 있습니다. 폴더 이름으로 카메라를 고르면 4개가 조용히 빠집니다. - 라운드 수가 공식과 다르다. 387 대 380. 빈 라운드나 중복이 있을 수 있어 쓰기 전에 확인해야 합니다(원인 미확인).
- 센서 시계와 영상의 어긋남이 라운드마다 다르다. 영상 파일 이름(초 단위)과 센서 시각의 어긋남이 −1.5초에서 +3초였습니다. 「센서의 타구 시각 ±30ms」 같은 정렬은 그대로 믿을 수 없습니다.
- 공 좌표 라벨이 없다. 공 검출의 정밀도는 눈으로만 볼 수 있었고, 다구 훈련이라 바닥과 바구니에 쉬는 공이 검출의 29% 였습니다(120장 중 35장). 「경기 중인 공」만 세면 정밀도가 0.54 였습니다.
6. TT Sounds: 깨끗한 충돌음
튀빙겐 대학이 공개한 라켓·공 충돌음 데이터셋입니다(arXiv 2409.11760). zip 하나(845MB)에 원녹음과 15ms 조각이 들어 있습니다.
| 항목 | 직접 셈 |
|---|---|
| 원녹음 wav / 15ms 조각 wav | 149 / 6,037 |
라벨 표(full.csv) 행 |
5,702(train/test 80/20 분할 표도 있음) |
| 표면 | 라켓 3,396 · 테이블 777 · 바닥 290 · 기타 1,239 |
| 라켓 종류 | 10가지(공격형·수비형 블레이드, 스펀지 두께, 평면·롱핌플 러버). 표본 207–892개 |
| 라켓 표본의 회전 | 무회전 1,879 · 백스핀 991 · 톱스핀 526(README 표와 같음) |
| 라벨 표가 가리키는 원녹음 | 115개 |
함정
- 조각 수와 라벨 수가 다르다. wav 6,037 개 중 라벨 표에 있는 것은 5,702 개이고, 원녹음 149 개 중 라벨 표가 가리키는 것은 115 개입니다. 폴더의 파일을 모두 쓰면 라벨 없는 소리가 섞입니다.
- 제공된 분할은 같은 녹음을 양쪽에 나눈다. 이웃한 15ms 조각이 학습과 시험에 함께 들어가 점수가 부풉니다. 원녹음 단위로 나누면 0.1–0.8%p 낮아졌습니다(6편).
- 라켓이 아닌 표본 311개에도 회전 라벨이 있다. 회전 열의 전체 합이 README 표와 다른 이유입니다. 「회전 있음 = 라켓 소리」로 가정하면 안 됩니다.
- 조용한 곳의 근접 녹음이다. 휴대폰 마이크와 탁구장 울림과는 다릅니다. 6편에서 본 것처럼 실제 녹음에서는 효과가 확인되지 않았습니다.
7. RacketVision: 라켓 다섯 점(탁구 부분)
탁구·테니스·배드민턴 국제 중계에 공 위치와 라켓 상자·다섯 점을 단 데이터셋입니다(arXiv 2511.17045, AAAI 2026). 세 종목 합은 클립 1,672, 435,179프레임입니다(데이터셋 메타). 우리는 탁구 부분만 받았습니다. 라켓 주석의 자세한 모양은 4편에 있습니다.
| 항목 | 직접 셈 |
|---|---|
| 클립 / 경기 / 분할 | 780 / 50 / 학습 625 · 검증 69 · 시험 86 |
| 프레임 / 길이 | 170,027 / 3,878초, 클립 길이 중앙 5.0초(1.7–5.16) |
| 해상도 | 모두 1920×1080 |
| fps | 25(209) · 60(201) · 50(191) · 30(112) · 59.94(67) |
| 공 CSV 행 / 보임 | 19,495 / 16,961 |
| 라켓이 있는 주석 프레임 / 라켓 수 | 6,648 / 8,060 |
함정
- fps 가 다섯 가지로 섞여 있다. 같은 「프레임당 이동량」이 클립마다 다른 속도를 뜻합니다. 우리도 받을 때 남긴 메모에 「60fps」라고 적었다가, 이번에 세어 보고 틀렸음을 알았습니다. 시간 기반 규칙(바운드 간격 0.12초 같은)을 쓰려면 클립마다 fps 를 읽어야 합니다.
- 메타데이터의 주석 수 필드가 비어 있다.
dataset_info.json의ball_annotated_frames·racket_annotated_frames가 탁구 780 클립 모두 0 입니다. 실제 주석은 클립별 주석 파일에 있습니다. - 주석이 드문드문하다. 주석 프레임 간격 중앙이 10프레임입니다. 매 프레임 정답이 아닙니다.
- 영상 권리. 주석은 MIT 로 표기되지만 영상은 YouTube 의 프로 경기 중계에서 잘라 낸 것입니다. 우리는 내부 연구에만 쓰고 프레임을 공개하지 않습니다.
8. LATTE-MV: 국제 중계와 자동 추적
국제 경기 중계에서 랠리를 잘라 공·라켓·탁구대·선수 3D 자세를 자동으로 추적한 데이터셋입니다(arXiv 2503.20936, CVPR 2025). 공식으로는 중계 약 800시간에서 거른 랠리 교환 73,222개, 약 26.7시간입니다.
| 항목 | 직접 셈 |
|---|---|
| 경기 / 클립(mp4) | 812 / 23,781(영상만 3.75GB) |
| 클립마다 | 영상, 공 CSV(Frame, Visibility, X, Y), 라켓 CSV, 탁구대 모서리, 선수 2D·3D 키포인트, 장면 복원 배열(프레임 × 91 × 3), 메타 JSON |
| 해상도 · fps(무작위 30클립, ffprobe) | 640×360 30클립 모두 · 30fps 21, 29fps 9 |
| 복원 배열의 fps · 길이(무작위 300클립) | 30fps 229, 29fps 71 · 프레임 중앙 109, 「쓸 수 있는 프레임」 중앙 70 |
| 소리 트랙(30클립) | 없음 |
함정
- 공 좌표는 사람 라벨이 아니다. 그 데이터 파이프라인의 추적 결과입니다. 공이 가려져도 Visibility 가 1 이고 좌표가 채워져 있습니다(BlurBall 이 「놓친」 20장 중 14장은 공이 보이지 않았습니다).
- 번짐 자국의 끝을 가리킨다. BlurBall 과 다르다고 채점된 40장 중 25장은 같은 자국의 다른 끝이었습니다(2편). 라벨 규칙이 다른 데이터로 모델을 재면 그 차이가 오차로 보입니다.
- 복제된 프레임. 직전 프레임과 거의 같은 프레임이 클립 중앙 27% 였습니다(2026-10-11 실측). 실제 fps 가 30보다 낮을 수 있습니다.
- 영상 권리 불명. 데이터 카드는 Apache-2.0 이지만 원 중계 영상의 권리는 적혀 있지 않습니다. 내부 시험에만 씁니다.
9. 덤: BlurBall 학습 데이터(공개분)
2편의 BlurBall 이 무엇을 보고 배웠는지 궁금해 공개분을 세었습니다.
| 항목 | 직접 셈 | 공식(논문) |
|---|---|---|
| 녹화 / 영상 | 폴더 26 / 영상 463 | 녹화 26편, 클립 443(학습 363 + 시험 80) |
| 프레임(표식 행) | 66,595(공 보임 58,547) | 64,119 |
| 해상도 | 1280×720 363 · 1266×720 60 · 1920×1080 40 | — |
| fps | 25 222 · 30/29.97 139 · 60/59.94 67 · 23.98 10 · 그 밖 25 | — |
| 표식 열 | Frame, Visibility, X, Y, theta, l | 번짐 가운데 + 방향 + 반길이 |
학습 영상의 절반 가까이가 25fps 입니다. 셔터가 길고 공이 많이 번지는 영상에서 배웠다는 뜻이고, 「번짐 가운데」 라벨이 왜 필요했는지와 맞닿아 있습니다. 영상 수와 프레임 수가 논문과 조금 다른 이유는 확인하지 못했습니다. 이 영상 목록이 공개 분할과 같은지, OpenTTGames 와 겹치는지도 모릅니다. 그래서 OpenTTGames 위의 BlurBall 숫자를 일반화 성능으로 읽지 않습니다.
10. 라이선스와 우리의 방침
| 조건 | 데이터 |
|---|---|
| CC BY-NC-SA 4.0(비상업, 출처 표기, 같은 조건) | OpenTTGames, Extended OpenTTGames, T3Set |
| CC BY-NC 4.0(비상업, 출처 표기) | TT Sounds |
| 주석은 허용적이나 원 영상 권리 불명 | RacketVision(MIT), LATTE-MV(Apache-2.0) |
| 표기 없음 | BlurBall 학습 데이터 |
TT Lab 은 비상업 서비스입니다. 그래서 비상업 조건 데이터로 배운 모델도 쓸 수 있습니다. 대신 모델마다 어떤 비상업 데이터로 배웠는지 기록하고, 방침이 바뀌면 우리 데이터로 다시 학습합니다. 같은 조건(SA) 데이터를 고쳐 공개할 때는 같은 라이선스로 공개합니다. 원 영상 권리가 불명한 데이터는 내부 시험에만 쓰고, 그 프레임을 화면이나 글에 싣지 않습니다. 이 글에 데이터셋의 프레임 그림이 없는 이유이기도 합니다.
11. 다시 세는 법
# 저장소 docs/experiments/2026-10-13-tt-dataset-stats/
python3 dataset_stats.py <데이터셋 뿌리> > results/dataset_stats_YYYY-MM-DD.txt # ffprobe, numpy 필요
python3 label_stats.py <라벨 뿌리> > results/label_stats_YYYY-MM-DD.json # 표준 라이브러리만
압축 파일을 풀지 않고 목록과 라벨 파일만 읽으므로 메모리 1GB 안에서 끝났습니다. 분할 zip(T3Set)은 표준 zipfile 이 여러 조각에 걸친 zip 을 읽지 못해, 마지막 조각의 중앙 디렉터리만 직접 해석하는 작은 도구(experiments/sound/splitzip.py)를 씁니다.
티티 한마디. 「공 없음」이라고 적힌 곳에 공이 보이면, 모델이 맞혀도 틀렸다고 채점돼요. 데이터를 직접 세 보는 건 귀찮지만, 모델을 믿기 전에 정답지부터 믿을 수 있는지 봐야 해요.
참고
- OpenTTGames: https://lab.osai.ai/, TTNet https://arxiv.org/abs/2004.09927
- Extended OpenTTGames: https://arxiv.org/abs/2512.19327, https://github.com/moamal01/table_tennis_data
- T3Set: https://zenodo.org/records/15516144, https://github.com/jima-cs/t3set
- TT Sounds: https://github.com/cogsys-tuebingen/tt_sounds
- RacketVision: https://arxiv.org/abs/2511.17045, https://huggingface.co/datasets/linfeng302/RacketVision
- LATTE-MV: https://arxiv.org/abs/2503.20936, https://huggingface.co/datasets/ember-lab-berkeley/LATTE-MV
- BlurBall: https://arxiv.org/abs/2509.18387