实用脚本统计假动作晃过防守几次?

wen 实用脚本 3

统计"假动作晃过防守"次数的脚本方案

先说明:没有通用的现成脚本能直接统计"假动作",因为这需要识别动作语义,下面给你一套可落地的实现思路 + 可运行示例代码,按你的数据源选择。

实用脚本统计假动作晃过防守几次?


先明确你的数据源(决定方案)

数据源 可行性 说明
手动标注视频(推荐入门) 用脚本做计数+时长统计,人工打点
姿态估计(MediaPipe/OpenPose) 可识别变向、重心晃动,误报较多
专业追踪数据(SportVU/Hawk-Eye) 有坐标轨迹,可做速度/方向突变检测
纯录像无标注 需训练动作识别模型,成本高

方案A:手动打点 + 脚本统计(最实用)

适合教练/分析师边看录像边按键标记。

# fake_move_counter.py
# 用法:播放视频时按 F 记录一次假动作,按 Q 退出,自动输出统计
import cv2, time, json, os
from datetime import datetime
VIDEO = "game.mp4"
OUT = "fake_move_log.json"
cap = cv2.VideoCapture(VIDEO)
fps = cap.get(cv2.CAP_PROP_FPS) or 30
records = []
frame_id = 0
print("按 F = 记录假动作 | 按 S = 撤销上一条 | 按 Q = 结束")
while True:
    ret, frame = cap.read()
    if not ret:
        break
    frame_id += 1
    t = frame_id / fps
    cv2.putText(frame, f"t={t:.1f}s  count={len(records)}",
                (20, 40), cv2.FONT_HERSHEY_SIMPLEX, 1, (0,255,0), 2)
    cv2.imshow("video", frame)
    key = cv2.waitKey(1) & 0xFF
    if key == ord('f'):
        records.append({"time_sec": round(t,2), "frame": frame_id,
                        "wall": datetime.now().isoformat()})
        print(f"[+] 记录 #{len(records)} @ {t:.1f}s")
    elif key == ord('s') and records:
        print(f"[-] 撤销 {records.pop()}")
    elif key == ord('q'):
        break
cap.release()
cv2.destroyAllWindows()
# 输出统计
result = {
    "video": VIDEO,
    "total_fake_moves": len(records),
    "events": records,
    "intervals_sec": [round(records[i+1]["time_sec"]-records[i]["time_sec"],2)
                      for i in range(len(records)-1)]
}
with open(OUT, "w", encoding="utf-8") as f:
    json.dump(result, f, ensure_ascii=False, indent=2)
print(f"\n✅ 共 {len(records)} 次假动作,已保存 {OUT}")

优点:100%准确(人工判断);缺点:需人工观看。


方案B:姿态估计自动检测"变向/重心晃动"

用 MediaPipe 提取髋部/肩部关键点,检测短时间内横向速度反向作为假动作候选。

# auto_fake_move.py  (需: pip install mediapipe opencv-python numpy)
import cv2, numpy as np, json
import mediapipe as mp
VIDEO = "game.mp4"
WINDOW = 8          # 平滑窗口(帧)
REVERSE_THRESH = 0.03  # 归一化横向速度反向阈值
MIN_GAP = 15        # 两次假动作最小间隔(帧)
mp_pose = mp.solutions.pose
cap = cv2.VideoCapture(VIDEO)
fps = cap.get(cv2.CAP_PROP_FPS) or 30
xs, frame_ids, events = [], [], []
with mp_pose.Pose(min_detection_confidence=0.5) as pose:
    fid = 0
    while cap.isOpened():
        ret, frame = cap.read()
        if not ret: break
        fid += 1
        rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
        res = pose.process(rgb)
        if res.pose_landmarks:
            h = res.pose_landmarks.landmark[mp_pose.PoseLandmark.LEFT_HIP]
            r = res.pose_landmarks.landmark[mp_pose.PoseLandmark.RIGHT_HIP]
            xs.append((h.x + r.x) / 2)
            frame_ids.append(fid)
x = np.array(xs)
if len(x) > WINDOW:
    v = np.diff(x)                          # 横向速度
    vs = np.convolve(v, np.ones(WINDOW)/WINDOW, 'same')  # 平滑
    last_event = -MIN_GAP
    for i in range(1, len(vs)):
        if vs[i-1] > REVERSE_THRESH and vs[i] < -REVERSE_THRESH:
            if frame_ids[i] - last_event >= MIN_GAP:
                events.append({"frame": frame_ids[i],
                               "time_sec": round(frame_ids[i]/fps, 2)})
                last_event = frame_ids[i]
cap.release()
print(json.dumps({"total": len(events), "events": events},
                 ensure_ascii=False, indent=2))

注意:这是候选检测,含误报(正常变向也会触发),需人工复核或调阈值 REVERSE_THRESH。


方案C:如果有逐帧坐标数据(轨迹)

直接对 (x, y) 轨迹做方向突变检测,比姿态估计更准:

def count_fakes(traj_xy, fps=30, angle_thresh=60, min_disp=0.5):
    """traj_xy: [(x,y),...] 单位米;返回假动作候选时间点"""
    import numpy as np
    p = np.array(traj_xy)
    v = np.diff(p, axis=0) * fps
    speed = np.linalg.norm(v, axis=1)
    angles = []
    for i in range(1, len(v)):
        a, b = v[i-1], v[i]
        na, nb = np.linalg.norm(a), np.linalg.norm(b)
        if na < min_disp or nb < min_disp: continue
        cos = np.clip(np.dot(a,b)/(na*nb), -1, 1)
        ang = np.degrees(np.arccos(cos))
        if ang > angle_thresh:
            angles.append(i/fps)
    return angles

建议

  1. 先从方案A做起——脚本简单、结果可信,跑通流程。
  2. 需要自动化再上方案B/C,并保留人工复核环节。
  3. 若要做"假动作 vs 正常变向"的语义区分,最终需标注数据 + 训练分类模型(如 ST-GCN / SlowFast),不是几行脚本能解决的。

需要我针对你的具体数据格式(视频/CSV坐标/传感器)把脚本改写成可直接跑的版本吗?告诉我数据长什么样即可。

上一篇这个实用脚本怎么看这次攻守转换速度?

下一篇当前分类已是最新一篇

抱歉,评论功能暂时关闭!

友情链接攻略窝 · 礼包窝 · 配置窝 · 换算窝 · 算法窝 · 查文窝 · 手册窝 · 问答窝 · 全文搜 · 手册库
相关站点礼包窝 · 查文窝