테니스 영상 개인 코치
아마추어 선수의 연습 영상을 실행 가능한 리뷰로 변환합니다: 스트로크의 어떤 부분이 무너졌는지, 어떤 샷이 이를 증명하는지, 그리고 다음에 정확히 무엇을 연습해야 하는지. 벽, 볼 머신, 코치 또는 파트너와 연습하는 초급 및 중급 선수를 위해 제작되었습니다.
필요 사항: Python 3 및 ffmpeg를 실행하고 pip 패키지(ultralytics, opencv-python, numpy, scipy, Pillow)를 설치할 수 있는 환경. GPU가 있으면 좋지만 필수는 아닙니다.
0. 먼저 물어보세요 (이미 알고 있는 것만 빼고)
- 프레임에서 플레이어인 사람: 옷 색깔, 머리, 위치. 코치, 파트너, 옆 코트에 있는 사람들이 종종 화면에 잡힙니다.
- 지배적인 손과 백핸드가 한손인지 두손인지(또는 배우는 중이라면 둘 다).
- 레벨 및 목표: 테니스를 얼마나 쳤고 무엇을 달성하고 싶은지 (예: "연말까지 랠리하고 세트를 치는 것").
- 환경: 연습 벽 / 볼 머신 / 코치 피드 / 랠리; 실내 또는 실외.
- 카메라: 후면, 측면 또는 전면; 휴대폰 높이; 프레임 속도.
- 부상: 무릎, 어깨, 팔꿈치 또는 허리의 최근 통증. 그렇다면 풋워크와 착지에 더 주의를 기울입니다.
- 가장 해결하고 싶은 한 가지 문제 (예: "많은 공이 길게 날아감" 또는 "임팩트 포인트가 일정하지 않음"). 리포트는 이 질문에 가장 먼저 답해야 합니다.
- 이전 보고서(있는 경우) 비교용.
1. 리포트가 해야 할 일
- 결론으로 시작하세요. 가장 큰 문제와 가장 큰 개선점에 대한 한 문장, 그 다음에 세부 사항. 구체적이고 모든 비판을 증거로 뒷받침하세요; 칭찬만 하지 마세요. 이전 리뷰에서 잘못된 점이 있다면 명시적으로 말하세요.
- 모든 주장을 비디오로 뒷받침하세요. 각 사례에는 주석이 추가된 슬로우 모션 클립이 제공되며, 플레이어의 실제 영상 위에 그려집니다 (막대기 인물 애니메이션이 아님).
- 기본적으로 4개 카테고리 × 3개 샷: 최고 포핸드, 최악 포핸드, 최고 백핸드, 최악 백핸드 (12개 클립). 각 카테고리에는 3열 비교 표와 세 샷의 공통점에 대한 한 문장이 제공됩니다. 카테고리에 사용 가능한 샷이 3개 미만인 경우, 발견된 개수를 명시하세요.
- 한손 및 두손 백핸드를 분리하세요. 플레이어가 둘 다 연습하는 경우, 한손 백핸드는 자체 섹션을 가지며 두손 백핸드 통계에서 제외됩니다.
- 깨진 단계의 이름을 지정하세요: 백스윙 / 라켓 드롭 / 임팩트 포인트 / 팔로우 스루 방향 / 풋워크 / 준비 타이밍 / 높은 공 처리 / 포핸드-백핸드 결정.
- 항상 무릎과 풋워크를 확인하세요: 공중에서 치기, 한 다리로 착지하기, 잠긴 곧은 다리로 회전하기.
- 데이터의 한계를 명시하세요: 표본 크기, 읽을 수 없는 샷 수, 카메라 각도 편향. 볼 수 없는 것이 있다면 숫자를 추측하는 대신 그렇게 말하세요.
- 따를 수 있는 계획으로 마무리하세요: 반복 횟수 또는 시간이 포함된 2~4개의 드릴과 다음 단계로 넘어가기 위한 조건.
2. 파이프라인
2.1 트랜스코딩 및 오디오 추출
- 4K HEVC 휴대폰 영상은 무겁습니다. 960 너비 H.264 분석용 복사본을 만드세요:
ffmpeg -i IN.MOV -vf scale=960:-2 -r 30 -an -c:v libx264 -preset veryfast -crf 24 p.mp4(일부 휴대폰은 29.97fps로 녹화합니다. 30fps로 강제 설정하면 시간 변환이 간단해집니다.) - 임팩트 위치를 찾기 위해 오디오를 별도로 추출하세요:
ffmpeg -i IN.MOV -vn -ac 1 -ar 22050 a.wav - 시간 초과를 피하기 위해 긴 영상은 4~5분 청크로 처리하세요. 짧은 클립이 많은 경우, 먼저 각 클립에서 한 프레임을 가져와 개요 시트를 만들고, 어떤 클립이 플레이어 뒤 각도로 사용 가능한지, 어떤 클립이 너무 멀리 떨어져 있는지(기술만 보기 위해 사용) 결정하세요.
- 연습 벽 세션의 경우, 네트/아웃을 판단하기 위해 네트 라인 주변을 확대한 "벽" 복사본을 크롭하세요.
2.2 포즈 추정
- Ultralytics YOLO 포즈 모델 사용(
yolo11n-pose.pt; 더 높은 정확도를 위해yolo11m-pose.pt). 실내에서는 imgsz 640, conf 0.3에서 매 4번째 프레임이면 충분합니다. 실외에서는 사람이 더 작고 많으므로 매 2번째 프레임, imgsz 960, conf 0.25를 사용하세요. - 올바른 사람을 추적하세요. 프레임에 한 사람만 있는 경우 가장 큰 박스를 사용하세요. 코치나 다른 사람이 있는 경우, 각 감지를 옷으로 평가합니다: 몸통 다각형(어깨 + 엉덩이) 내부의 중간 HSV 밝기 및 채도, 그리고 반바지/바지의 엉덩이-무릎 영역 색상. 이전 프레임에서 멀리 떨어져 있으면 페널티를 추가하여 트랙이 사람을 전환하지 않도록 하세요.
- 이미지 x-좌표로 왼쪽과 오른쪽을 결정하세요. 모델의 왼쪽/오른쪽 레이블이 아닙니다. 뒤에서 볼 때 플레이어의 오른쪽은 이미지의 오른쪽입니다.
2.3 모든 스윙 찾기
- 스윙은 손목 속도의 피크입니다: 더 많이 움직이는 손목의 프레임 간 변위를 박스 높이로 나누고, 2개 샘플에 걸쳐 평활화하며, 임계값은 약 0.16입니다 (매 4번째 프레임 샘플링 기준; 더 조밀한 샘플링의 경우 비례하여 축소).
- 피크 사이에 최소 1.6초가 필요합니다. 1.0초 간격은 팔로우 스루 후 회복을 두 번째 스윙으로 계산합니다. 정상 리듬은 스윙당 3-4초입니다.
- 포핸드 또는 백핸드: 피크 1.1초 전부터 0.25초 전까지의 윈도우에서 두 손의 중간점이 엉덩이 중앙선의 어느 쪽에 있는지 확인합니다. 지배적인 손 쪽이 포핸드를 의미합니다. 일부는 틀릴 수 있습니다. 특징으로 사용할 샷은 프레임별로 확인하세요.
- 아래 모든 지표를 손목 속도 피크(이를 tp라고 함)에 고정하여 세션 간 비교 가능하게 유지하세요.
2.4 소리에서 임팩트 위치 찾기
- 1500Hz에서 하이패스; 110개 샘플 윈도우에 걸쳐 에너지 엔벨로프 계산; 주변 401개 윈도우의 중앙값보다 최소 10dB 높고 최소 50개 윈도우 떨어진 피크 찾기.
window_index × 110 / 22050을 사용하여 초로 변환하세요. 0.005를 곱하는 바로 가기는 4분마다 약 0.5초씩 드리프트하여 긴 비디오의 후반부를 망칩니다.- 연습 벽:
[tp−0.1, tp+0.55]초 내에서 배경보다 최소 15dB 높은 가장 큰 피크를 찾습니다(보통 tp 후 0.2–0.35초). tp 후 약 0.45초에 공이 벽에 맞는 소리도 큽니다. 그것을 선택하지 마세요. - 실외: 코치의 샷과 다른 코트 소리가 노이즈를 추가합니다.
[tp−0.45, tp+0.25]초를 검색합니다. 해당하는 것이 없으면 tp를 사용합니다. - 클립에 포함되는 모든 샷에 대해 실제 임팩트 프레임을 프레임을 보고 확인하세요.
2.5 한손 백핸드 감지 (플레이어가 배우는 중인 경우)
- 백핸드 중에서 tp 후 0.7초 이내의 최대 손목-손목 거리(몸통 길이로 나눔)를 취합니다. 두손 백핸드는 피니시까지 두 손을 함께 유지합니다(보통 1.5 미만). 한손 백핸드는 치지 않는 팔을 뒤로 벌립니다(보통 2.0–2.5). 차이가 명확합니다. 약 1.95의 임계값이 잘 작동합니다.
- 가까운 카메라 각도는 거짓 양성을 생성합니다. 모든 후보를 시각적으로 확인하세요.
- 각 한손 백핸드에 대해 기록: 백스윙에서 손이 머리 위로 올라가는지, 백스윙이 늦는지(두손 백핸드처럼 설정한 다음 마지막 순간에 끌어올림), 임팩트에서 팔이 곧은지, 팔로우 스루 높이, 결과.
- 한손 백핸드 체크리스트 (각 항목에 대해: 올바른 모습 / 이번 세션 / 판정): 지지 않는 손을 목에 대고 유닛 턴, 백스윙 높이는 가슴과 어깨 사이, 라켓 헤드는 뒤를 향함, 라켓이 낮게 떨어진 후 낮음에서 높음으로 스윙, 앞에서 임팩트, 곧은 팔, 치지 않는 팔이 뒤로 열림, 높게 피니시하고 가슴이 일찍 열리지 않도록 유지, 무릎 구부리고 안으로 스텝. 그립은 뒤에서 볼 수 없습니다. 코치와 확인하도록 제안하세요.
2.6 네트 / 아웃 카운팅 (공이 보일 때만)
- 연습 벽: 확대된 벽 비디오에서 네트 라인을 표시하세요. 각 샷에 대해 하나의 타일을 만듭니다: 임팩트 후 30프레임에 걸쳐 움직이는 노란색 블롭, 시간순으로 빨간색→녹색으로 표시, 네트 라인 위 커튼의 움직임을 두 번째 색상으로 추가. 각 타일을 눈으로 판단하세요: 커튼이 움직이거나 공이 라인 위에 맞으면 = 인; 공이 보드에 맞고 커튼이 움직이지 않으면 = 네트; 플레이어에게 막히면 = 읽을 수 없음. 완전 자동 판단은 인간과 약 60%만 일치하므로 힌트로만 사용하세요.
- 샘플링: 세션 전체에 걸쳐 고르게 분포된 100개의 샷을 판단하고, 읽을 수 없는 것은 제외하고, 포핸드 / 두손 / 한손을 별도로 보고하세요. 그런 다음 가장 의심스러운 나머지 20개의 샷을 검토하여 오류가 한 기간에 집중되는지 확인합니다(보통 피로가 나타난 후).
- 실외: 배경에 나무가 흔들리거나 주변에 많은 플레이어가 있는 경우, 색상 및 모션 기반 공 감지는 대부분 실패합니다. 비율을 보고하지 마세요. 리포트에 이유를 명시하고, 대신 기술적으로 최고/최악을 선택하고, 카운팅을 가능하게 하는 카메라 조언을 제공하세요.
2.7 기술 지표 (모든 스윙에 대해 측정)
| 지표 | 방법 | 의미하는 것 |
|---|---|---|
| 포핸드 손이 코 위 | [tp−1.1, tp−0.25]에서 타격 손목이 코 위에 있는 프레임 비율 | 백스윙 너무 높음, 루프 스윙 |
| 두 손이 어깨 위 | 같은 윈도우에서 두 손목이 어깨 중앙 위에 있는 비율 | 백핸드 라켓 너무 높이 듦 |
| 가장 깊은 무릎 굽힘 | [tp−0.6, tp+0.3]에서 앞쪽 다리의 최소 엉덩이-무릎-발목 각도, 스윙 간 중앙값 | 다리가 너무 곧음 (뒤에서 찍은 카메라는 앞쪽 굽힘을 과소평가합니다. 자신과만 비교하세요) |
| 스탠스 너비 | tp에서 수평 발목 거리 ÷ 몸통 길이 | 좁은 스탠스는 종종 점프와 함께 나타남 |
| 고정되고 곧음 | tp 후 0.7초 이내에 한 발목이 몸통 길이의 0.4 미만으로 움직이고, 해당 무릎이 155°보다 곧음 | 무릎에 비틀림 부하 (백핸드에서 회전할 때 흔함) |
| 임팩트 높이 | tp 전 0.07–0.2초에서 타격 손 위치를 엉덩이(0)와 어깨(1) 사이로 표시 | 얼마나 많은 공이 높은지와 플레이어가 위치를 조정하는지 |
| 점프 / 한 다리 착지 | 프레임별로 검토하는 샷에서 눈으로 계산 | 아직 신뢰할 수 있는 자동 지표 없음 |
- 긴 세션의 경우, 피로와 함께 무엇이 무너지는지 보기 위해 전반부와 후반부를 별도로 보고하세요.
- 카메라, 장소 또는 방법이 변경되면, 이전 비디오를 새로운 방식으로 다시 측정하거나 숫자를 비교할 수 없다고 명확히 말하세요.
2.8 최고 3개 및 최악 3개 선택
- 최고: 좋은 결과(네트를 편안하게 넘기고 깊게 떨어짐)와 완전한 스트로크(백스윙 위치, 라켓 헤드가 공 아래로 떨어짐, 완전한 피니시, 두 발이 땅에 닿음). 세션 전체에 걸쳐 분포시키세요.
- 최악: 네트, 하늘 공 또는 명백한 실수; 충분하지 않은 경우 기술적 결함이 가장 명확한 샷을 선택하세요. 다른 원인을 보여주거나 함께 하나의 공통 원인을 증명하는 샷을 선호하세요.
- 결과 타일에서 후보 목록을 작성한 다음, 프레임별 플레이어 시트(임팩트 전 0.9초 ~ 후 0.5초)에서 원인을 확인하세요. 최악의 백핸드를 선택할 때 한손 백핸드가 아닌지 확인하세요.
2.9 주석이 추가된 슬로우 모션 클립 렌더링
- 원본에서 약 3초 잘라내고(임팩트 전 1.1–1.5초부터 시작), 플레이어 주변을 약 16:10 비율로 크롭하고(플레이어가 프레임 높이의 약 60%), 1280 너비로 조정하세요.
- 모든 프레임에 포즈를 실행하세요. 손으로 네 개의 프레임을 선택하세요: 백스윙 탑, 임팩트, 그리고 그려진 경로의 시작과 끝(준비 자세와 회복 제외). 자동 임팩트 프레임은 종종 틀리므로 항상 시각적으로 확인하세요.
- 클립 구조:
- 실제 속도 한 번.
- 1/4 속도, 프레임별로 타격 손 경로 그리기 (포핸드 = 타격 손목; 두손 = 두 손목의 중간점; 한손 = 임팩트 전 중간점, 임팩트 후 타격 손목), 주황색→청록색 그라데이션, 하단에 각 단계별 캡션 포함.
- 백스윙 탑에서 약 3초 동안 정지, 원으로 표시 (녹색 = 올바름, 빨간색 = 문제)하고 짧은 제목 포함.
- 임팩트에서 약 3초 동안 정지: 임팩트 지점에 흰색 원(자동 위치는 종종 공을 놓치므로 손으로 설정), 앞 무릎에 노란색 원과 각도 표시 (한손 백핸드의 경우 다리가 옆으로 겹치므로 건너뜀).
- 전체 경로에서 정지. 최악의 클립에는 동일한 유형의 세션 최고 샷을 경로 시작부터 임팩트까지 오버레이하고, 몸통 길이로 스케일링하고 어깨 중앙에 정렬한 후, 검은색 외곽선이 있는 애니메이션 녹색 점선과 수정 방법에 대한 한 문장을 추가하세요.
- H.264, yuv420p, faststart, 960 너비, 클립당 약 1–2.5MB로 인코딩하세요. 각 클립에서 4개의 프레임으로 연락처 시트를 만들어 캡션이 아무것도 가리지 않고 원이 올바른 위치에 있는지 확인하세요.
- 캡션에서 ✓ 및 ✗를 피하세요. 많은 CJK 폰트에 없어서 상자로 표시됩니다.
3. 리포트 구조
HTML 페이지(또는 사용자가 요청한 형식)를 다음 순서로 생성합니다:
- 판정: 플레이어의 질문에 직접 답변; 가장 큰 개선점, 가장 큰 문제, 주요 수치; 이전 리뷰에 대한 수정 사항. 그 아래, 통계 스트립(스트로크별 스윙, 샘플링된 네트율 또는 "미계산"과 그 이유, 한두 가지 주요 지표).
- 원인: 문제를 2~3가지 원인으로 그룹화하고, 각각 타임스탬프가 있는 예시 포함.
- 최고 vs 최악: 4개 그룹, 각각 3개의 클립, 3열 표(백스윙, 드롭, 임팩트, 피니시, 발, 무릎 각도) 및 패턴에 대한 한 문장.
- 지난번과 비교: 최고 및 최악 샷에서 변경된 사항을 표와 나란히 클립으로 표시.
- 한손 백핸드(연습 중인 경우): 통계, 체크리스트, 좋은 클립 3개와 나쁜 클립 3개, 샷별 목록, 지금 훈련을 계속할지에 대한 조언.
- 무릎 및 풋워크: 지표 표와 "우선 순위 / 주시 / 개선 중"으로 분류된 위험 및 각각에 대한 수정 방법. 이것이 의학적 조언이 아님을 명확히 하고, 붓기, 잠김, 주저앉음 또는 일주일 이상 지속되는 통증에 대해서는 스포츠 의학 전문의를 만나도록 제안.
- 다음에 연습할 것: 섹션 5 참조.
- 카메라 조언(영상에 공백이 있는 경우).
- 바닥글: 데이터 출처, 표본 크기, 측정 정의, 카메라 한계.
선택적 디자인 방향: 테니스 팔레트, 메인 색상으로 하드 코트 블루, 주요 숫자와 하이라이트에만 볼 옐로우, "좋음"에 잔디 그린, "문제"에 클레이 레드. 스코어보드 느낌을 위해 압축 숫자 사용. 라이트 모드와 다크 모드 모두에서 읽기 쉽게 하고, 휴대폰에서 가로 스크롤이 없도록 합니다.
4. 일반적인 결함 및 수정 방법
먼저 이 표로 본 내용을 분류한 다음, 특정 샷으로 증명하세요.
| 증상 | 일반적인 원인 | 비디오에 나타나는 모습 | 수정 방법 |
|---|---|---|---|
| 포핸드 네트, 아래로 스윕 | 백스윙이 머리 위, 큰 루프, 라켓이 제때 떨어질 수 없음 | 타격 손이 코 위 ... |
| 증상 | 일반적인 원인 | 비디오에 나타나는 모습 | 수정 방법 |
|---|---|---|---|
| 포핸드가 길게 날아감 | 임팩트가 너무 늦음, 팔꿈치가 앞으로 나옴, 라켓 헤드가 볼을 지나침 | 타격 손목이 임팩트에서 볼보다 뒤에 있음 | 더 일찍 임팩트하기, 팔꿈치를 몸에 붙이기, 라켓 헤드를 볼보다 뒤에 두기 |
| 백핸드가 항상 네트 | 임팩트에서 라켓 헤드가 볼 아래로 떨어지지 않음 | 라켓 헤드가 임팩트 시점에 볼 위에 있음 | 라켓을 더 낮게 떨어뜨리고 낮음에서 높음으로 스윙하기 |
| 서브가 항상 네트 또는 길게 | 공 던지기가 일관되지 않음, 무릎을 사용하지 않음 | 던진 공의 위치가 크게 변함, 무릎이 곧게 펴짐 | 공 던지기 연습, 무릎을 구부리는 데 집중 |
5. 다음 연습 계획
각 계획에는 다음이 포함되어야 합니다:
- 구체적인 드릴: 이름과 간단한 설명.
- 반복 횟수 또는 시간: 예: "10분", "50회 반복".
- 다음 단계로 넘어가기 위한 조건: 예: "10회 중 8회 성공".
- 선택적 대안: 드릴이 너무 쉽거나 어려운 경우.
예시 계획
- 드릴: 접촉 지점 고정
- 설명: 천천히 던져진 공에 대해 무릎을 구부리고 앞에서 임팩트하는 데 집중합니다.
- 반복: 50회
- 조건: 10회 연속 성공 시 다음 단계로.
- 드릴: 낮은 백핸드
- 설명: 낮게 바운드되는 공에 대해 라켓을 공 아래로 떨어뜨리고 낮음에서 높음으로 스윙합니다.
- 시간: 10분
- 조건: 10회 중 7회 성공.
6. 제한 사항
- 이 스킬은 코칭 조언을 제공하지만 전문 코치를 대체할 수는 없습니다.
- 측정은 카메라 각도, 조명 조건 및 플레이어의 위치에 따라 달라질 수 있습니다.
- 자동 감지(네트/아웃, 스윙 분류)는 완벽하지 않으며 주요 샷에 대해서는 수동으로 확인해야 합니다.
- 이 리포트의 의학적 조언은 검증된 의료 전문가의 조언을 대체할 수 없습니다.