本文目录导读:

统计“马赛回旋”使用频率的实用脚本,通常用于足球技战术分析(如分析某球员或某场比赛)或视频集锦制作(自动剪辑高光时刻)。
由于“马赛回旋”在视频中属于视觉动作,如果只用Python脚本直接分析比赛视频,要识别出这个动作在技术上较为复杂(需要姿态估计模型)。
我为你提供三个不同层级的实用脚本方案,你可以根据你的场景(是统计球员报告,还是分析视频素材)选择最合适的一个:
用于“视频集锦”的MOT(多目标追踪)+ 姿态识别脚本(复杂,但自动)
如果你有一场比赛的录像,想要自动切出马赛回旋的片段,需要用到姿态估计(如OpenPose或MediaPipe)。
核心逻辑:马赛回旋(360度转身)的特征是髋部(质点)旋转超过270度,且球始终在脚边,脚本会检测人体关键点,计算髋部角度的变化。
import cv2
import mediapipe as mp
# 初始化姿态估计
mp_pose = mp.solutions.pose
pose = mp_pose.Pose()
mp_drawing = mp.solutions.drawing_utils
cap = cv2.VideoCapture('match.mp4')
fps = int(cap.get(cv2.CAP_PROP_FPS))
# 参数设置
TURN_THRESHOLD = 2.8 # 弧度阈值 (约160度以上视为转身)
COOLDOWN_FRAMES = fps * 2 # 事件冷却时间(2秒内不重复计数)
# 状态变量
prev_hip_angle = None
total_360 = 0
cooldown = 0
def get_hip_angle(landmarks):
# 计算双髋连线的向量角度
left_hip = landmarks[mp_pose.PoseLandmark.LEFT_HIP.value]
right_hip = landmarks[mp_pose.PoseLandmark.RIGHT_HIP.value]
# 计算相对于X轴的角度
import math
dx = right_hip.x - left_hip.x
dy = right_hip.y - left_hip.y
angle = math.atan2(dy, dx)
return angle
while cap.isOpened():
ret, frame = cap.read()
if not ret:
break
if cooldown > 0:
cooldown -= 1
# 转为RGB处理
rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
results = pose.process(rgb)
if results.pose_landmarks:
current_angle = get_hip_angle(results.pose_landmarks)
# 计算角度累积变化(处理角度跳变)
if prev_hip_angle is not None:
delta = abs(current_angle - prev_hip_angle)
# 处理超过180度跳变(环绕)
if delta > 3.14:
delta = 6.28 - delta
# 如果总旋转积累超过阈值且冷却结束
if delta > TURN_THRESHOLD and cooldown == 0:
total_360 += 1
print(f"检测到疑似马赛回旋! 第{cap.get(cv2.CAP_PROP_POS_FRAMES)/fps:.2f}秒")
# 这里可以加代码保存视频片段
cooldown = COOLDOWN_FRAMES
prev_hip_angle = current_angle
# 显示画面(可省略)
if results.pose_landmarks:
mp_drawing.draw_landmarks(frame, results.pose_landmarks, mp_pose.POSE_CONNECTIONS)
cv2.imshow('Analysis', frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
print(f"总计检测到 {total_360} 次马赛回旋")
缺点:准确率依赖模型,且无法分辨球权,可能会将无球的转圈误判为马赛回旋。
基于“热区图”的统计脚本(半自动,较准)
如果你有一批球员的多场比赛录像,但不需要实时识别,只想统计频率,你可以用脚本来加速人工标记。
核心逻辑:将视频按每0.5秒切帧,脚本自动将帧抽出并保存为图片,统计人员只需要看图片分类(是/否)后打标签,脚本自动计算总频率。
import os
import cv2
def extract_frames_for_labeling(video_path, output_dir, frames_per_sec=2):
"""将视频切成帧用于人工标记"""
if not os.path.exists(output_dir):
os.makedirs(output_dir)
cap = cv2.VideoCapture(video_path)
fps = cap.get(cv2.CAP_PROP_FPS)
frame_interval = int(fps / frames_per_sec)
frame_count = 0
saved_count = 0
while True:
ret, frame = cap.read()
if not ret:
break
if frame_count % frame_interval == 0:
# 提取时间戳
time_sec = frame_count / fps
filename = f"{os.path.basename(video_path).split('.')[0]}_{time_sec:.2f}s.jpg"
cv2.imwrite(os.path.join(output_dir, filename), frame)
saved_count += 1
frame_count += 1
cap.release()
print(f"提取了 {saved_count} 帧到 {output_dir}")
# 使用示例
extract_frames_for_labeling('player_analysis_4k.mp4', './frames')
统计脚本(简单计数): 你用图片查看器肉眼数出标记了“马赛”的帧数 ( N )。 假设每场比赛平均时长 ( T ) 分钟,你分析的比赛场数为 ( M )。 则频率公式为: [ Frequency = \frac{N}{T \times M} \text{ (次/分钟)} ] 这个方案最准确,且成本低。
针对“文本/数据统计”的爬虫脚本(实用)
如果你不是分析视频,而是统计论坛、新闻文本中提到“马赛回旋”的频率(比如舆情分析),可以用这个脚本。
import re
from collections import Counter
import jieba # 中文分词
def count_marseille_turns(text_list, keyword="马赛回旋"):
"""统计文本列表中指定关键词的频率"""
total_mentions = 0
detail_counter = Counter()
for text in text_list:
# 1. 统计总提及次数
occurrences = len(re.findall(keyword, text))
total_mentions += occurrences
# 2. 统计相关上下文中的球员名(比如统计谁最常用)
# 使用jieba分词
words = jieba.lcut(text)
# 找到关键词前三个词和后两个词
for i, word in enumerate(words):
if word == keyword:
context = words[max(0, i-3): i+2]
# 统计人名(这里简单找单字或双字的词)
for w in context:
if w not in [keyword, '的', '了', '在', '是'] and len(w) > 1:
detail_counter[w] += 1
return total_mentions, detail_counter
# 示例:从网页读取数据
# docs = ["齐达内使出马赛回旋过掉后卫!", "本泽马这球不像马赛回旋。"]
total, details = count_marseille_turns(docs)
print(f"Total mentions: {total}")
print(f"Context people: {details.most_common(5)}")
总结建议
- 做技术报告/球探报告:用方案二(人工辅助,最精准)。
- 做自动集锦/大数据分析:用方案一(但需提前训练或调好姿态模型)。
- 做媒体趋势分析:用方案三。
如果你希望,我可以帮你优化上面方案一的识别逻辑或补充如何用YOLO(目标检测)结合球的位置来排除无球干扰,请告诉我你具体的应用场景。