本文目录导读:

要统计篮球比赛中"假动作晃过防守"的次数,需要先明确统计口径,因为脚本能自动识别的和人工判断的差别很大,下面给你一个可落地的方案,分两种场景。
先定义"假动作晃过防守"的判定标准
建议用可量化的规则,否则统计会主观:
| 条件 | 说明 |
|---|---|
| ① 持球人做出假动作 | 投篮假动作 / 突破假动作 / 传球假动作 |
| ② 防守人重心或位置发生明显偏移 | 被晃起跳、被晃失位、后退 |
| ③ 持球人随后向反方向移动 | 突破、投篮、传球成功 |
| ④ 时间窗口 | 假动作到摆脱在 1.5 秒内 |
满足 ①②③ 记 1 次。
方案 A:人工标注 + 脚本统计(推荐,最实用)
你只需要边看录像边打时间戳,脚本负责汇总。
标注文件 labels.csv:
quarter,time,player,type,result 1,08:32,库里,投篮假动作,突破成功 1,06:15,库里,突破假动作,跳投命中 2,03:44,汤普森,传球假动作,被识破
统计脚本 count.py:
import csv
from collections import Counter, defaultdict
# 只有这些 result 算"晃过"
SUCCESS = {"突破成功", "跳投命中", "传球成功", "造成犯规"}
stats = defaultdict(Counter)
total = Counter()
with open("labels.csv", encoding="utf-8") as f:
for row in csv.DictReader(f):
player = row["player"]
total[player] += 1
if row["result"] in SUCCESS:
stats[player][row["type"]] += 1
print(f"{'球员':<10}{'总假动作':<10}{'晃过成功':<10}{'成功率':<8}")
print("-" * 40)
for p in total:
succ = sum(stats[p].values())
rate = succ / total[p] * 100 if total[p] else 0
print(f"{p:<10}{total[p]:<10}{succ:<10}{rate:.1f}%")
print("\n按类型细分:")
for p in stats:
for t, c in stats[p].items():
print(f" {p} - {t}: {c} 次")
输出示例:
球员 总假动作 晃过成功 成功率
----------------------------------------
库里 12 7 58.3%
汤普森 8 3 37.5%
按类型细分:
库里 - 投篮假动作: 5 次
库里 - 突破假动作: 2 次
方案 B:用姿态识别自动检测(进阶,坑多)
如果想从视频自动识别,需要 人体姿态估计 + 轨迹分析。
技术栈:
pip install mediapipe opencv-python numpy
核心思路:
import cv2, mediapipe as mp, numpy as np
mp_pose = mp.solutions.pose
pose = mp_pose.Pose()
def detect_fake(prev_kp, curr_kp, defender_kp_prev, defender_kp_curr):
"""
简化逻辑:
1. 持球人躯干/头部先向A方向偏移,再向B方向移动
2. 防守人重心(髋部)向A方向偏移
"""
# 持球人方向突变
atk_dir_prev = prev_kp[mp_pose.PoseLandmark.LEFT_SHOULDER].x - prev_kp[mp_pose.PoseLandmark.RIGHT_SHOULDER].x
atk_dir_curr = curr_kp[mp_pose.PoseLandmark.LEFT_SHOULDER].x - curr_kp[mp_pose.PoseLandmark.RIGHT_SHOULDER].x
# 防守人髋部横移
def_hip_prev = (defender_kp_prev[23].x + defender_kp_prev[24].x) / 2
def_hip_curr = (defender_kp_curr[23].x + defender_kp_curr[24].x) / 2
defender_moved = abs(def_hip_curr - def_hip_prev) > 0.05
attacker_reversed = np.sign(atk_dir_curr) != np.sign(atk_dir_prev)
return defender_moved and attacker_reversed
cap = cv2.VideoCapture("game.mp4")
count = 0
while cap.isOpened():
ret, frame = cap.read()
if not ret: break
result = pose.process(cv2.cvtColor(frame, cv2.COLOR_BGR2RGB))
# ... 与上一帧对比调用 detect_fake
但要注意:
- 实战中遮挡严重、多人重叠,MediaPipe 单人模式容易崩
- "假动作"和"正常变向"很难自动区分,误报率高
- 需要先做球员追踪 ID(如 ByteTrack / BoT-SORT)
- 实际项目里通常还是人工标注 + 脚本汇总
建议
| 你的需求 | 推荐方案 |
|---|---|
| 分析几场球赛、要准确 | 方案 A:边看边标 CSV |
| 做产品/论文、要自动化 | 方案 B + 人工校验 |
| 快速试一下 | 直接抄方案 A 脚本 |
如果你告诉我:
- 是真人比赛视频还是游戏画面(如 2K)?
- 数据现在是CSV/Excel 还是视频?
我可以给你一份更贴合的具体脚本。