import streamlit as st import os from openai import OpenAI from PIL import Image import io import base64 import pandas as pd import plotly.express as px import plotly.graph_objects as go import numpy as np st.set_page_config( page_title="Baseball Analytics Hub", layout="wide", initial_sidebar_state="expanded" ) # Custom CSS for baseball theme def apply_custom_css(): st.markdown(""" """, unsafe_allow_html=True) def initialize_session_state(): if 'history' not in st.session_state: st.session_state.history = [] if 'player_stats' not in st.session_state: st.session_state.player_stats = { 'batting_avg': [], 'hits': [], 'home_runs': [], 'games': [] } def encode_image_to_base64(image): buffered = io.BytesIO() image.save(buffered, format="PNG") return base64.b64encode(buffered.getvalue()).decode('utf-8') def analyze_image(image, question, api_key): try: client = OpenAI(api_key=api_key) base64_image = encode_image_to_base64(image) # Add baseball-specific context to the prompt baseball_context = "Analyze this baseball-related image. Consider aspects like player stance, pitch mechanics, field positioning, and game situation. " enhanced_question = baseball_context + question completion = client.chat.completions.create( model="gpt-4o-mini", messages=[ { "role": "user", "content": [ {"type": "text", "text": enhanced_question}, { "type": "image_url", "image_url": { "url": f"data:image/png;base64,{base64_image}" } }, ], } ], max_tokens=500 ) return completion.choices[0].message.content except Exception as e: return f"Error: {str(e)}" def plot_strike_zone(): fig = go.Figure() fig.add_shape( type="rect", x0=-0.85, x1=0.85, y0=1.5, y1=3.5, line=dict(color="red", width=2), fillcolor="rgba(255, 0, 0, 0.1)" ) fig.add_trace(go.Scatter( x=np.random.uniform(-1, 1, 10), y=np.random.uniform(1, 4, 10), mode='markers', marker=dict(size=10, color='blue'), name='Pitches' )) fig.update_layout( title="Strike Zone Analysis", xaxis_title="Horizontal Location (ft)", yaxis_title="Height (ft)", template="plotly_white" ) return fig def main(): apply_custom_css() initialize_session_state() # Sidebar Configuration with st.sidebar: st.markdown('", unsafe_allow_html=True) # Main Content st.markdown('

⚾ Baseball Vision Analytics

', unsafe_allow_html=True) # Create tabs for different features tab1, tab2 = st.tabs(["Image Analysis", "Performance Analytics"]) with tab1: # Image Upload Section col1, col2, col3 = st.columns([1, 2, 1]) with col2: st.markdown('
', unsafe_allow_html=True) uploaded_file = st.file_uploader( "Upload baseball image for analysis", type=['png', 'jpg', 'jpeg'], help="Upload images of batting, pitching, or fielding" ) st.markdown('
', unsafe_allow_html=True) if uploaded_file: image = Image.open(uploaded_file) # Image Display and Analysis Section col1, col2 = st.columns([1, 1]) with col1: st.image(image, use_container_width=True, caption="Uploaded Baseball Image") with col2: st.markdown('
', unsafe_allow_html=True) question = st.text_input( "Analysis Focus:", value=selected_prompt, key="question_input" ) if st.button("🔍 Analyze", use_container_width=True): if not api_key: st.error("⚠️ Please enter your OpenAI API key in the sidebar.") else: with st.spinner("🔄 Analyzing baseball technique..."): response = analyze_image(image, question, api_key) st.markdown("### 📝 Analysis Result:") st.write(response) st.session_state.history.append({ "question": question, "response": response, "timestamp": pd.Timestamp.now().strftime("%Y-%m-%d %H:%M:%S") }) st.markdown('
', unsafe_allow_html=True) with tab2: # Performance Analytics Section col1, col2 = st.columns(2) with col1: st.markdown('
', unsafe_allow_html=True) st.subheader("Strike Zone Analysis") fig = plot_strike_zone() st.plotly_chart(fig, use_container_width=True) st.markdown('
', unsafe_allow_html=True) with col2: st.markdown('
', unsafe_allow_html=True) st.subheader("Key Metrics") metrics_col1, metrics_col2 = st.columns(2) with metrics_col1: st.metric("Pitch Accuracy", "68%", "+2%") st.metric("Avg Exit Velocity", "92 mph", "-1 mph") with metrics_col2: st.metric("Strike Rate", "65%", "+5%") st.metric("Spin Rate", "2400 rpm", "+100 rpm") st.markdown('
', unsafe_allow_html=True) # History Section if st.session_state.history: st.markdown("### 📜 Previous Analyses") for item in reversed(st.session_state.history[-5:]): with st.expander(f"Q: {item['question'][:50]}..."): st.write(item['response']) st.caption(f"Analyzed on: {item['timestamp']}") # Footer st.markdown("---") st.markdown( """

Powered by Advanced Baseball Analytics and OpenAI Vision API

© 2024 Baseball Vision Analytics

""", unsafe_allow_html=True ) if __name__ == "__main__": main()