Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
78 commits
Select commit Hold shift + click to select a range
fb333e7
feat: simplify preprocessing and add CLAHE enhancement for better cro…
aniket939 May 6, 2026
3e4c011
Merge pull request #53 from lucastargett/cm-sp4/Video-processing
MAYURA26-bot May 6, 2026
a6cc396
Test and finalize heatmap module for Sprint 4
chiranthgowdaxaus May 6, 2026
3a6586c
Merge pull request #56 from lucastargett/cm-sp4/heatmap
MAYURA26-bot May 6, 2026
c03d0f2
improve crowd movement tracking
mayuselva May 9, 2026
91abf6b
video upload & crowd results visuals in front-end integration
mayuselva May 9, 2026
a6b324a
Improve stadium-style heatmap visualization for match_02
chiranthgowdaxaus May 9, 2026
aadb5c5
Merge pull request #62 from lucastargett/cm-sp4/heatmap
MAYURA26-bot May 9, 2026
b7bcc69
Fix Docker test suite and async DB startup issue
Prabhnoor911 May 13, 2026
4f2c4f7
Fix auth and model imports for backend startup
WilliamHamilton22 May 13, 2026
0d7e0b4
FrontEnnd Integration
J4k3Ng0 May 14, 2026
e16fdb9
Merge pull request #69 from lucastargett/frontend-sp4/FrontEndIntegra…
lucastargett May 14, 2026
1047637
Merge branch 'backend-api-gateway' into backend-sp4/william
lucastargett May 14, 2026
f035006
Merge pull request #68 from lucastargett/backend-sp4/william
lucastargett May 14, 2026
1d3f1d2
Logo navigation
HirushaRukmal May 16, 2026
994c016
Add Player feature
HirushaRukmal May 17, 2026
5de86d6
Improve frontend auth error handling and secure token usage
HirushaRukmal May 17, 2026
b4250a7
Update tracking with jersey colour clustering
mcchamps2097 May 17, 2026
0e5859b
Updated README and SCHEMA files
ShivamSaini09 May 17, 2026
a4de102
Merge pull request #72 from lucastargett/cm-sp4/crowd-detection
ShivamSaini09 May 17, 2026
5a71a03
Test Detection Pipeline
ShivamSaini09 May 17, 2026
17d9b2e
Delete
ShivamSaini09 May 17, 2026
9395c9a
Merge pull request #67 from Prabhnoor911/backend-sp4/prabhnoor
TOMINJOSE88 May 17, 2026
083960a
Updated the README usage instructions to explain how to run the track…
mcchamps2097 May 17, 2026
ad7c537
Add player tracking output JSON and CSV files
mcchamps2097 May 17, 2026
a8114f7
Merge pull request #73 from lucastargett/player-tracking-ethan
lucastargett May 18, 2026
d3a6cee
Update readme file for plpayer tracking branch
quan-le May 18, 2026
6584404
Merge branch 'Player-Tracking' of https://github.com/lucastargett/red…
quan-le May 18, 2026
4e32b66
Add speed analysis and acceleration tracking
May 18, 2026
4f12e12
Merge pull request #74 from lucastargett/player-tracking-sp4/drew-spe…
quan-le May 18, 2026
73d9cd9
Update backend async database and integration config
lucastargett May 18, 2026
e349016
Merge remote-tracking branch 'origin/backend-api-gateway' into backen…
lucastargett May 18, 2026
78e664b
Final density zoning implementation
TolaniRidmini May 19, 2026
0d47605
Merge pull request #75 from lucastargett/cm-sp4/density-zoning
MAYURA26-bot May 19, 2026
bd6f872
Player Tracking with umpire detection
mjlew133 May 19, 2026
8fa9e24
Merge pull request #70 from lucastargett/frontend/Hirusha-addplayer-f…
J4k3Ng0 May 19, 2026
5b56933
Updated file to include acceleration in labels
mjlew133 May 20, 2026
735ba0a
Added acceleration to player labels
mjlew133 May 20, 2026
cc2cc06
Fix backend pipeline, mocks, tests, and service endpoints
TOMINJOSE88 May 20, 2026
fa2172d
Merge branch 'backend-api-gateway' of https://github.com/lucastargett…
TOMINJOSE88 May 20, 2026
d805859
Remove duplicate mock flags in config.py and debug print in jobs.py
TOMINJOSE88 May 20, 2026
ee53efe
Add player service Dockerfile and fix compose.yaml for full stack Docker
TOMINJOSE88 May 20, 2026
4ab1c4c
Add files via upload
Apaar-sc May 20, 2026
05ce4f4
Merge pull request #2 from Apaar-sc/Apaar-sc-patch-1
Apaar-sc May 20, 2026
41d2a6a
Merge pull request #76 from lucastargett/cm-sp4/crowd-detection
MAYURA26-bot May 20, 2026
e0315c1
Sprint 4: Multi-team AFL fixture risk analyzer for 2026 season
s225009786 May 20, 2026
fa552cd
Merge pull request #77 from lucastargett/cm-sp4/crowd-allocation-risk…
MAYURA26-bot May 20, 2026
f8174ff
Included acceleration in player labels
mjlew133 May 20, 2026
1058a13
Added acceleration to player labels and moved file to correct folder
mjlew133 May 20, 2026
1077f4b
Fix Docker build, auth model, and upload path bugs for full stack
TOMINJOSE88 May 20, 2026
a38074d
Updated player tracking file with acceleration and umpire detection
mjlew133 May 20, 2026
aaffed0
Update README file
mjlew133 May 20, 2026
ab5013f
Merge pull request #80 from mjlew133/tracking-sp2/matthew-player-trac…
quan-le May 20, 2026
9b767e9
Merge pull request #81 from mjlew133/readme-update
quan-le May 20, 2026
d53533b
Merge pull request #82 from Apaar-sc/main
quan-le May 20, 2026
28e3bf1
added frame width & height as density zone need it & made the crowd d…
mayuselva May 20, 2026
54cf9d3
chnaged deteced person count to get from detected_persons for density…
mayuselva May 20, 2026
6ce325c
removed test_detection_pipeline.py
mayuselva May 20, 2026
034ec94
Update tackle detection module
Shafqat1137 May 20, 2026
94edaf0
Merge pull request #83 from Shafqat1137/update-tackle-detection
quan-le May 20, 2026
0de2058
Merge branch 'main' into cm_sp4
MAYURA26-bot May 20, 2026
7402451
Create temp.py
sri-bandara May 20, 2026
f71089a
Create temp1.py
sri-bandara May 20, 2026
ff8baa4
Add files via upload
sri-bandara May 20, 2026
4a8e240
Create temp2.py
sri-bandara May 20, 2026
a4f5d72
Add files via upload
sri-bandara May 20, 2026
4b41e1b
Create temp3.py
sri-bandara May 20, 2026
37991cd
Add files via upload
sri-bandara May 20, 2026
b15b720
Merge pull request #86 from lucastargett/sri-modelling
quan-le May 20, 2026
eb158ac
PlayerTracking Integration(still unfinished)
J4k3Ng0 May 20, 2026
d28693e
Merge pull request #87 from lucastargett/frontend-sp4/FrontEndIntegra…
lucastargett May 21, 2026
7d9cba6
Merge pull request #85 from lucastargett/Player-Tracking
lucastargett May 21, 2026
bbf2eb2
Merge pull request #84 from lucastargett/cm_sp4
lucastargett May 21, 2026
c997d70
Merge branch 'main' into backend-sp4/lucas
lucastargett May 21, 2026
33df360
Merge remote-tracking branch 'origin/backend-api-gateway' into backen…
lucastargett May 21, 2026
c495409
Resolve jobs route merge conflict
lucastargett May 21, 2026
3977f91
Fix job_id UUID validation, path separators, and add volume mounts to…
TOMINJOSE88 May 24, 2026
d21c244
Resolve merge conflict in jobs.py — keep UUID validation and process_…
TOMINJOSE88 May 24, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file modified .DS_Store
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ RUN apt-get update && apt-get install -y \

COPY Crowd_Monitoring/2026_T1/requirements.txt .

RUN pip install --no-cache-dir -r requirements.txt
RUN pip install --no-cache-dir torch torchvision --index-url https://download.pytorch.org/whl/cpu && \
pip install --no-cache-dir -r requirements.txt

COPY Crowd_Monitoring/2026_T1/ .

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,233 @@
#!/usr/bin/env python3
"""AFL 2026 Season Fixture Risk Analyzer - Multi-Team Support"""

import json
import csv
from afl_teams_config import *

# Sample 2026 fixtures for the 10 teams (Rounds 1-24)
# Format: (round, home_team, away_team, time_slot, is_public_holiday)
FIXTURES_2026 = [
# Round 1
(1, "Collingwood", "Sydney", "Friday Night", False),
(1, "Essendon", "Carlton", "Saturday Night", False),
(1, "Richmond", "Geelong", "Saturday Afternoon", False),
(1, "Melbourne", "Western Bulldogs", "Sunday Afternoon", False),
(1, "Brisbane", "Hawthorn", "Saturday Night", False),

# Round 2
(2, "Carlton", "Richmond", "Thursday Night", False),
(2, "Collingwood", "Essendon", "Friday Night", False), # Early season rivalry
(2, "Geelong", "Melbourne", "Saturday Afternoon", False),
(2, "Sydney", "Brisbane", "Saturday Night", False),
(2, "Western Bulldogs", "Hawthorn", "Sunday Afternoon", False),

# Round 3
(3, "Essendon", "Collingwood", "Friday Night", False),
(3, "Richmond", "Carlton", "Saturday Night", False),
(3, "Hawthorn", "Geelong", "Saturday Afternoon", False),
(3, "Brisbane", "Melbourne", "Sunday Afternoon", False),
(3, "Sydney", "Western Bulldogs", "Saturday Night", False),

# Round 4 - Easter Monday
(4, "Geelong", "Hawthorn", "Monday Afternoon", True), # Easter Monday special match

# Round 5
(5, "Collingwood", "Richmond", "Friday Night", False),
(5, "Carlton", "Essendon", "Saturday Night", False),
(5, "Melbourne", "Sydney", "Saturday Afternoon", False),
(5, "Western Bulldogs", "Brisbane", "Sunday Afternoon", False),

# Round 6 - ANZAC Day
(6, "Collingwood", "Essendon", "Friday Night", True), # ANZAC Day special match

# Round 7
(7, "Richmond", "Collingwood", "Saturday Night", False),
(7, "Carlton", "Geelong", "Thursday Night", False),
(7, "Hawthorn", "Melbourne", "Saturday Afternoon", False),

# Round 8
(8, "Essendon", "Richmond", "Friday Night", False),
(8, "Collingwood", "Carlton", "Saturday Night", False),
(8, "Brisbane", "Sydney", "Saturday Night", False),

# Round 9
(9, "Geelong", "Collingwood", "Friday Night", False),
(9, "Hawthorn", "Essendon", "Saturday Afternoon", False),

# Round 10 - Dreamtime
(10, "Essendon", "Richmond", "Saturday Night", True), # Dreamtime special match

# Round 11
(11, "Carlton", "Collingwood", "Friday Night", False),
(11, "Sydney", "Geelong", "Saturday Night", False),

# Round 12 - Queen's Birthday
(12, "Melbourne", "Collingwood", "Monday Afternoon", True), # Queen's Birthday special match

# Rounds 13-24 (additional fixtures to complete season)
(13, "Richmond", "Essendon", "Saturday Night", False),
(14, "Collingwood", "Geelong", "Friday Night", False),
(15, "Carlton", "Hawthorn", "Sunday Afternoon", False),
(16, "Essendon", "Collingwood", "Friday Night", False),
(17, "Richmond", "Carlton", "Thursday Night", False),
(18, "Hawthorn", "Collingwood", "Saturday Afternoon", False),
(19, "Geelong", "Essendon", "Saturday Night", False),
(20, "Melbourne", "Richmond", "Sunday Afternoon", False),
(21, "Collingwood", "Carlton", "Friday Night", False),
(22, "Essendon", "Geelong", "Saturday Night", False),
(23, "Richmond", "Hawthorn", "Saturday Afternoon", False),
(24, "Collingwood", "Melbourne", "Friday Night", False),
]

def calculate_risk_score(round_num, home_team, away_team, time_slot, is_public_holiday):
"""Calculate risk score (1-5) for a fixture"""
score = 1 # Base minimum score

# Time slot weight (Thursday/Friday night highest)
score += TIME_SLOT_WEIGHTS.get(time_slot, 0)

# Public holiday
if is_public_holiday:
score += 2

# Rivalry weight
score += get_rivalry_weight(home_team, away_team)

# Special match weight
special_weight, special_name = get_special_match_weight(home_team, away_team, round_num)
score += special_weight

# Away game (for crowd risk analysis - away fans increase risk)
# For neutral games, both teams' fans travel
score += 1 # Default away game risk

# Fan base risk (average of both teams)
fan_risk = (FAN_BASE_RISK.get(home_team, 1) + FAN_BASE_RISK.get(away_team, 1)) / 2
score += fan_risk

# Normalize to 1-5 scale
normalized = min(5, max(1, round(score / 3)))

return normalized

def get_risk_level(score):
"""Convert numeric score to risk level and emoji"""
if score >= 4:
return f"🔴 HIGH ({score})"
elif score == 3:
return f"🟡 MEDIUM ({score})"
else:
return f"🟢 LOW ({score})"

def analyze_all_fixtures():
"""Analyze all fixtures and return results"""
results = []

for fixture in FIXTURES_2026:
round_num, home_team, away_team, time_slot, is_public_holiday = fixture

risk_score = calculate_risk_score(round_num, home_team, away_team, time_slot, is_public_holiday)

# Get special match name if applicable
_, special_name = get_special_match_weight(home_team, away_team, round_num)

results.append({
"round": round_num,
"home_team": home_team,
"away_team": away_team,
"time_slot": time_slot,
"is_public_holiday": is_public_holiday,
"special_match": special_name,
"risk_score": risk_score,
"risk_level": get_risk_level(risk_score)
})

return results

def print_summary(results):
"""Print console summary of risk analysis"""
print("\n" + "="*80)
print("🏉 AFL 2026 SEASON FIXTURE RISK ANALYSIS")
print("="*80)

# Sort by risk score (highest first)
sorted_results = sorted(results, key=lambda x: x["risk_score"], reverse=True)

print("\n🔴 HIGHEST RISK FIXTURES (Top 10):")
print("-"*80)
for i, fixture in enumerate(sorted_results[:10], 1):
special = f" - {fixture['special_match']}" if fixture['special_match'] else ""
print(f"{i:2}. R{fixture['round']}: {fixture['home_team']} vs {fixture['away_team']} ({fixture['time_slot']}){special} → Score: {fixture['risk_score']}/5")

# Team risk summary
print("\n📊 TEAM RISK SUMMARY:")
print("-"*80)

team_high_risk = {}
for fixture in results:
if fixture["risk_score"] >= 4:
for team in [fixture["home_team"], fixture["away_team"]]:
team_high_risk[team] = team_high_risk.get(team, 0) + 1

sorted_teams = sorted(team_high_risk.items(), key=lambda x: x[1], reverse=True)
for team, count in sorted_teams[:10]:
bar = "█" * min(count, 10)
print(f" {team:20} : {count} high risk games {bar}")

# Overall statistics
high_risk = [f for f in results if f["risk_score"] >= 4]
medium_risk = [f for f in results if f["risk_score"] == 3]
low_risk = [f for f in results if f["risk_score"] <= 2]

print(f"\n📈 OVERALL STATISTICS:")
print(f" Total fixtures analyzed: {len(results)}")
print(f" 🔴 High risk (4-5): {len(high_risk)}")
print(f" 🟡 Medium risk (3): {len(medium_risk)}")
print(f" 🟢 Low risk (1-2): {len(low_risk)}")
print(f" 📊 Average risk score: {sum(f['risk_score'] for f in results)/len(results):.2f}/5.0")

print("\n💾 Output saved to:")
print(" - afl_2026_risk_matrix.json")
print(" - afl_2026_risk_matrix.csv")

def save_to_json(results, filename="afl_2026_risk_matrix.json"):
"""Save results to JSON file"""
output = {
"season": 2026,
"total_fixtures": len(results),
"fixtures": results,
"summary": {
"high_risk": len([f for f in results if f["risk_score"] >= 4]),
"medium_risk": len([f for f in results if f["risk_score"] == 3]),
"low_risk": len([f for f in results if f["risk_score"] <= 2]),
"average_risk": sum(f["risk_score"] for f in results) / len(results)
}
}

with open(filename, "w") as f:
json.dump(output, f, indent=2)
print(f" - {filename}")

def save_to_csv(results, filename="afl_2026_risk_matrix.csv"):
"""Save results to CSV file"""
with open(filename, "w", newline="") as f:
writer = csv.DictWriter(f, fieldnames=["round", "home_team", "away_team", "time_slot", "special_match", "risk_score", "risk_level"])
writer.writeheader()
for fixture in results:
writer.writerow({
"round": fixture["round"],
"home_team": fixture["home_team"],
"away_team": fixture["away_team"],
"time_slot": fixture["time_slot"],
"special_match": fixture["special_match"] or "",
"risk_score": fixture["risk_score"],
"risk_level": fixture["risk_level"]
})
print(f" - {filename}")

if __name__ == "__main__":
results = analyze_all_fixtures()
print_summary(results)
save_to_json(results)
save_to_csv(results)
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
"""AFL Teams Configuration for Risk Matrix - Sprint 4"""

# Top 10 teams for Sprint 4
TEAMS = [
"Collingwood",
"Essendon",
"Carlton",
"Richmond",
"Geelong",
"Hawthorn",
"Melbourne",
"Western Bulldogs",
"Sydney",
"Brisbane"
]

# Fan base risk (size and intensity) - 1 to 3 scale
FAN_BASE_RISK = {
"Collingwood": 3,
"Essendon": 2,
"Carlton": 2,
"Richmond": 2,
"Geelong": 2,
"Hawthorn": 2,
"Melbourne": 1,
"Western Bulldogs": 1,
"Sydney": 1,
"Brisbane": 1,
}

# Historical rivalries (significant high-risk matchups)
HISTORICAL_RIVALRIES = [
("Collingwood", "Essendon"),
("Collingwood", "Carlton"),
("Collingwood", "Richmond"),
("Essendon", "Carlton"),
("Essendon", "Richmond"),
("Geelong", "Hawthorn"),
("Geelong", "Collingwood"),
("Carlton", "Richmond"),
]

# Special matches with extra weight
SPECIAL_MATCHES = {
("Collingwood", "Essendon"): {"name": "ANZAC Day", "weight": 4, "round": 6},
("Essendon", "Richmond"): {"name": "Dreamtime at the 'G", "weight": 4, "round": 10},
("Geelong", "Hawthorn"): {"name": "Easter Monday", "weight": 3, "round": 4},
("Melbourne", "Collingwood"): {"name": "Queen's Birthday", "weight": 3, "round": 12},
}

# Time slot risk weights (Thursday/Friday night highest)
TIME_SLOT_WEIGHTS = {
"Thursday Night": 2,
"Friday Night": 2,
"Saturday Night": 1,
"Saturday Afternoon": 0,
"Saturday Twilight": 0,
"Sunday Afternoon": 0,
"Sunday Twilight": 0,
}

def get_rivalry_weight(team1, team2):
"""Get rivalry weight between two teams"""
if (team1, team2) in HISTORICAL_RIVALRIES or (team2, team1) in HISTORICAL_RIVALRIES:
return 2
return 0

def get_special_match_weight(team1, team2, round_num):
"""Get special match weight if applicable"""
# Check both orders
for (t1, t2), match_info in SPECIAL_MATCHES.items():
if ((team1 == t1 and team2 == t2) or (team1 == t2 and team2 == t1)) and match_info["round"] == round_num:
return match_info["weight"], match_info["name"]
return 0, None
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,7 @@ def detect_behaviour_events(
if features["avg_density"] <= 0.20 and zones:
event_flags.append("crowd_dispersing")

if anomaly_summary.get("running_track_ids"):
event_flags.append("running_detection")
elif tracking_summary.get("running_track_count", 0) > 0:
if tracking_summary.get("running_track_count", 0) > 0:
event_flags.append("running_detection")

if tracking_summary.get("walking_track_count", 0) > 0:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,13 +46,9 @@ def analyze_behaviour(input_data):
artifact_paths = []
if heatmap and heatmap.get("image_path"):
artifact_paths.append(heatmap["image_path"])
merged_tracking_summary = dict(tracking_summary)
merged_running_ids = set(tracking_summary.get("running_track_ids", []))
merged_running_ids.update(anomaly_summary.get("running_track_ids", []))
merged_tracking_summary["running_track_ids"] = sorted(merged_running_ids)
merged_tracking_summary["running_track_count"] = len(merged_running_ids)
frame_activity_series = build_frame_activity_series(frame_tracks, merged_tracking_summary)
artifact_paths.extend(save_motion_annotations(frame_tracks, merged_tracking_summary, video_id))
# Keep displayed movement states aligned with tracker/pose output.
frame_activity_series = build_frame_activity_series(frame_tracks, tracking_summary)
artifact_paths.extend(save_motion_annotations(frame_tracks, tracking_summary, video_id))

vision_metrics = dict(vision_features)
vision_metrics["tracking"] = tracking_summary
Expand Down
Loading
Loading