Spaces:
Sleeping
Sleeping
Update pages/player_comparison_images.py
Browse files
pages/player_comparison_images.py
CHANGED
@@ -0,0 +1,170 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import streamlit as st
|
2 |
+
import pandas as pd
|
3 |
+
import numpy as np
|
4 |
+
import joblib
|
5 |
+
import cv2
|
6 |
+
from PIL import Image
|
7 |
+
import plotly.express as px
|
8 |
+
import plotly.graph_objects as go
|
9 |
+
|
10 |
+
# -------------------------------
|
11 |
+
# 1. Setup
|
12 |
+
# -------------------------------
|
13 |
+
st.set_page_config(page_title="Cricket Player Comparision", layout="centered")
|
14 |
+
st.title("π Cricket Player Comparision Tool")
|
15 |
+
|
16 |
+
# -------------------------------
|
17 |
+
# 2. Load Data & Models
|
18 |
+
# -------------------------------
|
19 |
+
@st.cache_data
|
20 |
+
def load_dataset():
|
21 |
+
return pd.read_csv("cric_final.csv")
|
22 |
+
|
23 |
+
@st.cache_resource
|
24 |
+
def load_assets():
|
25 |
+
model = joblib.load("svc_face_classifier.pkl")
|
26 |
+
encoder = joblib.load("label_encoder.pkl")
|
27 |
+
detector = cv2.CascadeClassifier(cv2.data.haarcascades + "haarcascade_frontalface_default.xml")
|
28 |
+
return model, encoder, detector
|
29 |
+
|
30 |
+
df = load_dataset()
|
31 |
+
model, encoder, detector = load_assets()
|
32 |
+
formats = ["Test", "ODI", "T20", "IPL"]
|
33 |
+
|
34 |
+
# -------------------------------
|
35 |
+
# 3. Player Detection from Image
|
36 |
+
# -------------------------------
|
37 |
+
def detect_player(image_file, model, encoder, detector):
|
38 |
+
try:
|
39 |
+
img = Image.open(image_file).convert("RGB")
|
40 |
+
img_np = np.array(img)
|
41 |
+
gray = cv2.cvtColor(img_np, cv2.COLOR_RGB2GRAY)
|
42 |
+
faces = detector.detectMultiScale(gray, 1.3, 5)
|
43 |
+
if not len(faces):
|
44 |
+
return None, "No face detected"
|
45 |
+
x, y, w, h = faces[0]
|
46 |
+
face = cv2.resize(gray[y:y+h, x:x+w], (64, 64)).flatten().reshape(1, -1)
|
47 |
+
label = model.predict(face)[0]
|
48 |
+
name = encoder.inverse_transform([label])[0]
|
49 |
+
return name, None
|
50 |
+
except Exception as e:
|
51 |
+
return None, str(e)
|
52 |
+
|
53 |
+
# -------------------------------
|
54 |
+
# 4. Player Stats Summary
|
55 |
+
# -------------------------------
|
56 |
+
def get_summary(player_row, formats):
|
57 |
+
return {
|
58 |
+
"Total Runs": sum(player_row.get(f'batting_Runs_{f}', 0) for f in formats),
|
59 |
+
"Total Wickets": sum(player_row.get(f'bowling_{f}_Wickets', 0) for f in formats),
|
60 |
+
"Best Strike Rate": max(player_row.get(f'batting_SR_{f}', 0) for f in formats)
|
61 |
+
}
|
62 |
+
|
63 |
+
# -------------------------------
|
64 |
+
# 5. Upload Player Images
|
65 |
+
# -------------------------------
|
66 |
+
col1, col2 = st.columns(2)
|
67 |
+
with col1:
|
68 |
+
img1 = st.file_uploader("Upload Player 1 Image", type=["jpg", "png", "jpeg"], key="img1")
|
69 |
+
with col2:
|
70 |
+
img2 = st.file_uploader("Upload Player 2 Image", type=["jpg", "png", "jpeg"], key="img2")
|
71 |
+
|
72 |
+
p1_name, p2_name = None, None
|
73 |
+
|
74 |
+
if img1:
|
75 |
+
p1_name, err1 = detect_player(img1, model, encoder, detector)
|
76 |
+
if err1:
|
77 |
+
st.error(f"Player 1 Error: {err1}")
|
78 |
+
else:
|
79 |
+
col1.image(img1, caption=f"Player 1: {p1_name}", width=200)
|
80 |
+
|
81 |
+
if img2:
|
82 |
+
p2_name, err2 = detect_player(img2, model, encoder, detector)
|
83 |
+
if err2:
|
84 |
+
st.error(f"Player 2 Error: {err2}")
|
85 |
+
else:
|
86 |
+
col2.image(img2, caption=f"Player 2: {p2_name}", width=200)
|
87 |
+
|
88 |
+
if not (p1_name and p2_name):
|
89 |
+
st.warning("Upload images for both players to load the data.")
|
90 |
+
st.stop()
|
91 |
+
|
92 |
+
if p1_name not in df["Player"].values or p2_name not in df["Player"].values:
|
93 |
+
st.error("One or both players are not in the dataset.")
|
94 |
+
st.stop()
|
95 |
+
|
96 |
+
# -------------------------------
|
97 |
+
# 6. Stats Extraction
|
98 |
+
# -------------------------------
|
99 |
+
player1 = df[df["Player"] == p1_name].iloc[0]
|
100 |
+
player2 = df[df["Player"] == p2_name].iloc[0]
|
101 |
+
stats1 = get_summary(player1, formats)
|
102 |
+
stats2 = get_summary(player2, formats)
|
103 |
+
|
104 |
+
# -------------------------------
|
105 |
+
# 7. Display Summary Stats
|
106 |
+
# -------------------------------
|
107 |
+
st.subheader("π Player Summary")
|
108 |
+
col1, col2 = st.columns(2)
|
109 |
+
for col, stats in zip([col1, col2], [stats1, stats2]):
|
110 |
+
col.metric("Total Runs", stats["Total Runs"])
|
111 |
+
col.metric("Total Wickets", stats["Total Wickets"])
|
112 |
+
col.metric("Best SR", round(stats["Best Strike Rate"], 2))
|
113 |
+
|
114 |
+
# -------------------------------
|
115 |
+
# 8. Visual Comparisons
|
116 |
+
# -------------------------------
|
117 |
+
st.markdown("## π Visual Comparison")
|
118 |
+
|
119 |
+
# Batting
|
120 |
+
bat_df = pd.DataFrame({
|
121 |
+
"Format": formats,
|
122 |
+
p1_name: [player1.get(f'batting_Runs_{f}', 0) for f in formats],
|
123 |
+
p2_name: [player2.get(f'batting_Runs_{f}', 0) for f in formats]
|
124 |
+
})
|
125 |
+
st.plotly_chart(px.bar(bat_df, x="Format", y=[p1_name, p2_name], barmode="group", title="Batting Runs"))
|
126 |
+
|
127 |
+
# Bowling
|
128 |
+
bowl_df = pd.DataFrame({
|
129 |
+
"Format": formats,
|
130 |
+
p1_name: [player1.get(f'bowling_{f}_Wickets', 0) for f in formats],
|
131 |
+
p2_name: [player2.get(f'bowling_{f}_Wickets', 0) for f in formats]
|
132 |
+
})
|
133 |
+
st.plotly_chart(px.bar(bowl_df, x="Format", y=[p1_name, p2_name], barmode="group", title="Bowling Wickets"))
|
134 |
+
|
135 |
+
# -------------------------------
|
136 |
+
|
137 |
+
# Strike Rate Comparison
|
138 |
+
sr_df = pd.DataFrame({
|
139 |
+
"Format": formats,
|
140 |
+
p1_name: [player1.get(f'batting_SR_{f}', 0) for f in formats],
|
141 |
+
p2_name: [player2.get(f'batting_SR_{f}', 0) for f in formats]
|
142 |
+
})
|
143 |
+
st.plotly_chart(px.bar(sr_df, x="Format", y=[p1_name, p2_name], barmode="group", title="Strike Rate Comparison"))
|
144 |
+
|
145 |
+
#---------------------------------
|
146 |
+
# 9. Match Distribution
|
147 |
+
# -------------------------------
|
148 |
+
for name, row, col, key_suffix in zip(
|
149 |
+
[p1_name, p2_name],
|
150 |
+
[player1, player2],
|
151 |
+
[col1, col2],
|
152 |
+
["player1", "player2"]
|
153 |
+
):
|
154 |
+
values = [row.get(f"Matches_{f}", 0) for f in formats]
|
155 |
+
fig = px.pie(
|
156 |
+
values=values,
|
157 |
+
names=formats,
|
158 |
+
title=f"{name}'s Match Distribution"
|
159 |
+
)
|
160 |
+
col.plotly_chart(fig, key=f"pie_chart_{key_suffix}") # π Unique key
|
161 |
+
|
162 |
+
# 10. Milestones
|
163 |
+
# -------------------------------
|
164 |
+
st.subheader("π Milestones")
|
165 |
+
for fmt in formats:
|
166 |
+
st.markdown(f"### {fmt}")
|
167 |
+
col1, col2 = st.columns(2)
|
168 |
+
for m in ["50s", "100s", "200s"]:
|
169 |
+
col1.metric(f"{p1_name} {m}", player1.get(f"batting_{m}_{fmt}", 0))
|
170 |
+
col2.metric(f"{p2_name} {m}", player2.get(f"batting_{m}_{fmt}", 0))
|