本文目录导读:

我来帮你创建一个Python案例来统计"撞墙式配合"(也就是二过一配合)的次数,这个统计通常用于足球比赛分析。
方案1:基于比赛事件数据的统计
def count_wall_pass_events(events):
"""
统计撞墙式配合(二过一配合)的次数
撞墙式配合的判定条件:
1. 两个球员之间的连续传球
2. 传球过程中有防守球员被过掉
3. 传球和接球发生的区域变化
参数:
events: 比赛事件列表,每个事件包含时间、球员、类型、位置等信息
返回:
wall_pass_count: 撞墙式配合的次数
"""
wall_pass_count = 0
potential_wall_passes = [] # 存储潜在的配合事件
# 遍历所有传球事件
for i in range(len(events) - 2):
event1 = events[i]
event2 = events[i+1]
event3 = events[i+2]
# 检查是否是连续的传球事件(球员A传给B,B马上传回给A)
if (event1['type'] == 'pass' and
event2['type'] == 'pass' and
event3['type'] == 'pass'):
# 检查是否是撞墙式配合
if (event1['to'] == event2['from'] and # A传给B
event2['to'] == event1['from'] and # B传回给A
abs(event1['timestamp'] - event2['timestamp']) < 3.0): # 3秒内完成
# 检查是否有防守球员在附近
if has_defender_nearby(event1, event2):
wall_pass_count += 1
potential_wall_passes.append({
'player_a': event1['from'],
'player_b': event2['from'],
'timestamp': event1['timestamp'],
'area': get_area(event1, event2)
})
return wall_pass_count, potential_wall_passes
def has_defender_nearby(event1, event2, threshold=5.0):
"""
检查传球过程中是否有防守球员在附近
threshold: 防守球员距离的阈值(米)
"""
# 这里需要根据实际数据判断
# 可以检查传球角度、防守球员位置等
return True # 简化处理
def get_area(event1, event2):
"""
确定配合发生的区域
"""
# 根据球场位置划分区域
avg_x = (event1['x'] + event2['x']) / 2
avg_y = (event1['y'] + event2['y']) / 2
if avg_x < 34:
return 'defensive_third'
elif avg_x < 68:
return 'middle_third'
else:
return 'offensive_third'
# 示例数据
sample_events = [
{'timestamp': 10.5, 'type': 'pass', 'from': 'PlayerA', 'to': 'PlayerB', 'x': 50, 'y': 30},
{'timestamp': 11.2, 'type': 'pass', 'from': 'PlayerB', 'to': 'PlayerA', 'x': 55, 'y': 35},
{'timestamp': 11.8, 'type': 'pass', 'from': 'PlayerA', 'to': 'PlayerC', 'x': 60, 'y': 40},
{'timestamp': 13.0, 'type': 'pass', 'from': 'PlayerC', 'to': 'PlayerB', 'x': 65, 'y': 25},
{'timestamp': 15.5, 'type': 'pass', 'from': 'PlayerD', 'to': 'PlayerE', 'x': 70, 'y': 30},
{'timestamp': 16.2, 'type': 'pass', 'from': 'PlayerE', 'to': 'PlayerD', 'x': 75, 'y': 35},
]
# 执行统计
count, details = count_wall_pass_events(sample_events)
print(f"撞墙式配合完成次数: {count}")
print(f"详细记录: {details}")
方案2:基于比赛数据文件的统计分析
import pandas as pd
from datetime import datetime
class WallPassAnalyzer:
def __init__(self):
self.wall_passes = []
self.combinations = {} # 统计不同球员组合的配合次数
def analyze_match(self, match_data):
"""
分析整场比赛的撞墙式配合
参数:
match_data: DataFrame,包含所有传球事件
返回:
total_wall_passes: 总次数
detailed_stats: 详细统计信息
"""
# 预处理数据
match_data = match_data.sort_values('time')
match_data['pass_pair'] = match_data.apply(
lambda x: tuple(sorted([x['passer'], x['receiver']])), axis=1
)
# 找出潜在的配合事件
wall_pass_events = []
for idx in range(len(match_data) - 1):
current_pass = match_data.iloc[idx]
next_pass = match_data.iloc[idx + 1]
# 检查时间间隔(通常撞墙式配合在1-3秒内完成)
time_diff = (next_pass['time'] - current_pass['time']).total_seconds()
if time_diff > 3.0: # 时间间隔太长,不是撞墙式配合
continue
# 检查是否是来回传球
if (current_pass['receiver'] == next_pass['passer'] and
current_pass['passer'] == next_pass['receiver']):
# 计算区域变化
area_change = self.calculate_area_change(
current_pass['x'], current_pass['y'],
next_pass['x'], next_pass['y']
)
# 检查是否向前推进
if area_change > 0: # 向前推进
wall_pass_events.append({
'player1': current_pass['passer'],
'player2': current_pass['receiver'],
'time': current_pass['time'],
'area': self.get_zone(current_pass['x'], current_pass['y']),
'effectiveness': self.evaluate_effectiveness(
current_pass, next_pass
),
'distance': self.calculate_distance(
current_pass['x'], current_pass['y'],
next_pass['x'], next_pass['y']
)
})
# 更新统计
self.wall_passes.extend(wall_pass_events)
# 统计组合次数
for wp in wall_pass_events:
combo = tuple(sorted([wp['player1'], wp['player2']]))
if combo in self.combinations:
self.combinations[combo] += 1
else:
self.combinations[combo] = 1
return len(wall_pass_events), wall_pass_events
def calculate_area_change(self, x1, y1, x2, y2):
"""
计算区域变化,正值表示向前推进
"""
return x2 - x1
def get_zone(self, x, y):
"""
根据坐标系判断球场区域
"""
# 假设球场长度为105米,划分为3个区域
if x < 35:
return "防守三区"
elif x < 70:
return "中场"
else:
return "进攻三区"
def evaluate_effectiveness(self, pass1, pass2):
"""
评估配合效果
返回:
'successful', 'neutral', 'failed'
"""
# 根据后续事件判断配合效果
return 'successful'
def calculate_distance(self, x1, y1, x2, y2):
"""
计算传球距离
"""
return ((x2 - x1)**2 + (y2 - y1)**2)**0.5
def generate_report(self, match_name):
"""
生成统计报告
"""
report = f"\n{'='*50}\n"
report += f"比赛名称: {match_name}\n"
report += f"总计撞墙式配合: {len(self.wall_passes)} 次\n"
report += f"{'='*50}\n\n"
# 按组合统计
report += "球员组合统计:\n"
for combo, count in sorted(self.combinations.items(), key=lambda x: -x[1]):
report += f" {combo[0]} + {combo[1]}: {count} 次\n"
# 按区域统计
zone_stats = {}
for wp in self.wall_passes:
zone = wp['area']
zone_stats[zone] = zone_stats.get(zone, 0) + 1
report += "\n区域分布:\n"
for zone, count in zone_stats.items():
report += f" {zone}: {count} 次\n"
# 计算成功率
successful = sum(1 for wp in self.wall_passes if wp['effectiveness'] == 'successful')
if self.wall_passes:
success_rate = (successful / len(self.wall_passes)) * 100
report += f"\n成功率: {success_rate:.1f}%\n"
report += f"{'='*50}\n"
return report
# 使用示例
if __name__ == "__main__":
# 创建示例数据
data = {
'time': [
datetime(2024, 1, 1, 15, 0, 0),
datetime(2024, 1, 1, 15, 0, 2),
datetime(2024, 1, 1, 15, 0, 5),
datetime(2024, 1, 1, 15, 0, 7),
],
'passer': ['PlayerA', 'PlayerB', 'PlayerA', 'PlayerC'],
'receiver': ['PlayerB', 'PlayerA', 'PlayerC', 'PlayerB'],
'x': [50, 55, 60, 65],
'y': [30, 35, 40, 25]
}
match_df = pd.DataFrame(data)
# 进行分析
analyzer = WallPassAnalyzer()
count, details = analyzer.analyze_match(match_df)
print(f"分析完成!撞墙式配合次数: {count}")
print(analyzer.generate_report("示例比赛"))
方案3:实时视频分析(进阶版本)
import cv2
import numpy as np
class RealtimeWallPassDetector:
def __init__(self):
self.player_positions = {}
self.passing_events = []
self.wall_pass_count = 0
def process_frame(self, frame, player_detections):
"""
处理视频帧,实时检测撞墙式配合
参数:
frame: 当前视频帧
player_detections: 该帧检测到的球员位置
"""
# 更新球员位置
for player_id, position in player_detections.items():
if player_id in self.player_positions:
# 计算移动速度
last_pos = self.player_positions[player_id]['position']
speed = self.calculate_speed(last_pos, position)
self.player_positions[player_id]['speed'] = speed
self.player_positions[player_id]['position'] = position
else:
self.player_positions[player_id] = {
'position': position,
'speed': 0,
'trajectory': []
}
# 检测传球事件
current_passes = self.detect_passes(frame)
self.passing_events.extend(current_passes)
# 分析撞墙式配合
self.analyze_wall_passes()
# 在视频上标注结果
self.annotate_frame(frame)
return frame
def detect_passes(self, frame):
"""
检测传球事件
"""
passes = []
# 实现具体的传球检测算法
# 可以基于:球的速度变化、球员手臂动作、球的方向等
return passes
def analyze_wall_passes(self):
"""
分析最近的传球事件,检测撞墙式配合
"""
if len(self.passing_events) >= 2:
last_two = self.passing_events[-2:]
# 检查是否是来回传球
if (last_two[0]['from'] == last_two[1]['to'] and
last_two[0]['to'] == last_two[1]['from']):
# 检查时间间隔
time_diff = last_two[1]['timestamp'] - last_two[0]['timestamp']
if time_diff < 3.0: # 3秒内完成
self.wall_pass_count += 1
# 触发提醒
self.trigger_alert(last_two)
def trigger_alert(self, wall_pass):
"""
触发撞墙式配合提醒
"""
print(f"检测到撞墙式配合!")
print(f"球员: {wall_pass[0]['from']} -> {wall_pass[0]['to']} -> {wall_pass[1]['to']}")
print(f"时间: {wall_pass[1]['timestamp']}")
def annotate_frame(self, frame):
"""
在视频帧上标注撞墙式配合信息
"""
# 显示统计数据
cv2.putText(frame, f"Wall Passes: {self.wall_pass_count}",
(10, 30), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2)
return frame
def calculate_speed(self, pos1, pos2):
"""
计算球员移动速度
"""
distance = np.linalg.norm(np.array(pos2) - np.array(pos1))
return distance
这些代码示例提供了不同层次的撞墙式配合统计方法,你可以根据实际需求选择:
- 简单版本:基于事件数据的统计分析
- 中级版本:包含数据预处理和详细统计报告
- 进阶版本:实时视频分析
需要根据你的具体数据格式和需求进行调整。