Spaces:
Runtime error
Runtime error
| import streamlit as st | |
| import pandas as pd | |
| import os | |
| import hashlib | |
| import sqlite3 # Kept for potential local debugging, though we use CSV for persistence | |
| from datetime import datetime | |
| from pathlib import Path | |
| from huggingface_hub import CommitScheduler | |
| from localization_eval import evaluate_submission | |
| from PIL import Image | |
| # --- CONFIGURATION & SETUP --- | |
| st.set_page_config( | |
| page_title="AI Benchmark Arena", | |
| page_icon="π", | |
| layout="wide", | |
| initial_sidebar_state="expanded" | |
| ) | |
| # --- HUGGING FACE PERSISTENCE SETUP --- | |
| DATA_DIR = Path("data") | |
| DATA_DIR.mkdir(exist_ok=True) | |
| SUBMISSIONS_CSV = DATA_DIR / "submissions.csv" | |
| USERS_CSV = DATA_DIR / "users.csv" | |
| # Change 'your-username/your-dataset-name' to your actual repo ID | |
| repo_id = "your-username/your-private-dataset" | |
| scheduler = CommitScheduler( | |
| repo_id=repo_id, | |
| repo_type="dataset", | |
| folder_path=DATA_DIR, | |
| path_in_repo="data", | |
| every=5, | |
| token=os.getenv("HF_TOKEN") | |
| ) | |
| def init_db(): | |
| """Initializes the CSV files if they do not exist in the data directory.""" | |
| if not USERS_CSV.exists(): | |
| pd.DataFrame(columns=["username", "password"]).to_csv(USERS_CSV, index=False) | |
| if not SUBMISSIONS_CSV.exists(): | |
| pd.DataFrame(columns=["username", "bbox_mAP", "bbox_AP50", "segm_mAP", "segm_AP50", "timestamp"]).to_csv(SUBMISSIONS_CSV, index=False) | |
| def make_hashes(password): | |
| return hashlib.sha256(str.encode(password)).hexdigest() | |
| def add_user(username, password): | |
| with scheduler.lock: | |
| df = pd.read_csv(USERS_CSV) | |
| if username in df['username'].values: | |
| return False | |
| new_user = pd.DataFrame([{"username": username, "password": make_hashes(password)}]) | |
| df = pd.concat([df, new_user], ignore_index=True) | |
| df.to_csv(USERS_CSV, index=False) | |
| return True | |
| def login_user(username, password): | |
| if not USERS_CSV.exists(): | |
| return [] | |
| df = pd.read_csv(USERS_CSV) | |
| user_match = df[(df['username'] == username) & (df['password'] == make_hashes(password))] | |
| return user_match.values.tolist() | |
| def save_submission(username, bbox_mAP, bbox_AP50, segm_mAP, segm_AP50): | |
| with scheduler.lock: | |
| df = pd.read_csv(SUBMISSIONS_CSV) | |
| new_row = { | |
| "username": username, | |
| "bbox_mAP": bbox_mAP, | |
| "bbox_AP50": bbox_AP50, | |
| "segm_mAP": segm_mAP, | |
| "segm_AP50": segm_AP50, | |
| "timestamp": datetime.now().strftime("%Y-%m-%d %H:%M:%S") | |
| } | |
| df = pd.concat([df, pd.DataFrame([new_row])], ignore_index=True) | |
| df.to_csv(SUBMISSIONS_CSV, index=False) | |
| def get_leaderboard_data(): | |
| if not SUBMISSIONS_CSV.exists(): | |
| return pd.DataFrame() | |
| df = pd.read_csv(SUBMISSIONS_CSV) | |
| if df.empty: | |
| return df | |
| # Logic: Get the highest segm_mAP per user, then the earliest timestamp if tied | |
| df['timestamp'] = pd.to_datetime(df['timestamp']) | |
| df = df.sort_values(by=['segm_mAP', 'timestamp'], ascending=[False, True]) | |
| df_best = df.drop_duplicates(subset='username', keep='first') | |
| df_best = df_best.rename(columns={'segm_mAP': 'Best_segm_mAP', 'timestamp': 'last_submission'}) | |
| return df_best | |
| # --- User Interface --- | |
| def ui_login_signup(): | |
| st.title("Welcome to Benchmark Arena π") | |
| tab1, tab2 = st.tabs(["Login", "Sign Up"]) | |
| with tab1: | |
| st.subheader("Sign In") | |
| username = st.text_input("Username", key="login_user") | |
| password = st.text_input("Password", type='password', key="login_pass") | |
| if st.button("Login"): | |
| if login_user(username, password): | |
| st.session_state['logged_in'] = True | |
| st.session_state['username'] = username | |
| st.rerun() | |
| else: | |
| st.error("Username or Password incorrect") | |
| with tab2: | |
| st.subheader("Create New Account") | |
| new_user = st.text_input("Username", key="new_user") | |
| new_pass = st.text_input("Password", type='password', key="new_pass") | |
| if st.button("Sign Up"): | |
| if add_user(new_user, new_pass): | |
| st.success("Account created! Please navigate to Login.") | |
| else: | |
| st.warning("Username already exists.") | |
| def main_app(): | |
| # Sidebar Navigation | |
| st.sidebar.title(f"Hi, {st.session_state['username']}!") | |
| menu = ["Submit Model", "Leaderboard"] | |
| choice = st.sidebar.radio("Navigation", menu) | |
| st.sidebar.markdown("---") | |
| if st.sidebar.button("Logout"): | |
| st.session_state['logged_in'] = False | |
| st.session_state['username'] = None | |
| st.rerun() | |
| with st.expander("βΉοΈ Overview of the AI Benchmark Arena"): | |
| st.markdown( | |
| """ | |
| A natural application of computer vision is to assist blind people, whether that may be to overcome their daily visual challenges or break down their social accessibility barriers. BIV-Priv is proposed to preserve a blind person's visual privacy to ensure they can access visual-related tools safely. | |
| VizWiz Challenge 2025 is the 1th edition of the Few-Shot Private Object Localization Challenge on the BIV-Priv dataset. To participate in the challenge, you can find instructions on the Challenge website. | |
| Note: All the timings on the EvalAI platform are local to your timezone. | |
| """ | |
| ) | |
| try: | |
| overview_image = Image.open("src/overview_image.png").resize((600, 600)) | |
| st.image(overview_image, caption="Example of an object localization task") | |
| except FileNotFoundError: | |
| st.warning("Overview image not found in src/ folder.") | |
| with st.expander("π How is the Score Calculated?"): | |
| st.markdown( | |
| """ | |
| **Terms and Conditions** | |
| The images and annotations in this dataset belong to the VizWiz team and are licensed under a Commons Attribution 4.0 International License. | |
| """ | |
| ) | |
| st.markdown("---") | |
| if choice == "Submit Model": | |
| st.header("π Submit your Predictions") | |
| col1, col2 = st.columns([2, 1]) | |
| with col1: | |
| uploaded_file = st.file_uploader("Choose a JSON file", type="json") | |
| if uploaded_file is not None: | |
| save_path = f"./{uploaded_file.name}" | |
| with open(save_path, "wb") as f: | |
| f.write(uploaded_file.getbuffer()) | |
| if st.button("Evaluate"): | |
| with st.spinner('Calculating score against Ground Truth...'): | |
| # Using your custom evaluation function | |
| bbox_mAP, bbox_AP50, segm_mAP, segm_AP50 = evaluate_submission("src/biv_query.json", save_path) | |
| if all(v is not None for v in [bbox_mAP, bbox_AP50, segm_mAP, segm_AP50]): | |
| st.success(f"Results: bbox_mAP: {bbox_mAP:.2f}, bbox_AP50: {bbox_AP50:.2f}, segm_mAP: {segm_mAP:.2f}, segm_AP50: {segm_AP50:.2f}") | |
| save_submission(st.session_state['username'], bbox_mAP, bbox_AP50, segm_mAP, segm_AP50) | |
| st.balloons() | |
| st.success("Submission Successful!") | |
| else: | |
| st.error("Evaluation failed. Please check your JSON format.") | |
| elif choice == "Leaderboard": | |
| st.header("π Leaderboard") | |
| st.write("Rankings based on the highest segmentation mAP score achieved.") | |
| df_leaderboard = get_leaderboard_data() | |
| if not df_leaderboard.empty: | |
| df_leaderboard.insert(0, 'Rank', range(1, len(df_leaderboard) + 1)) | |
| st.dataframe( | |
| df_leaderboard, | |
| column_config={ | |
| "Rank": st.column_config.Column("Rank", width="small"), | |
| "username": "Participant", | |
| "Best_segm_mAP": st.column_config.NumberColumn("segm_mAP (Primary)", format="%.4f"), | |
| "bbox_mAP": st.column_config.NumberColumn("bbox_mAP", format="%.4f"), | |
| "bbox_AP50": st.column_config.NumberColumn("bbox_AP50", format="%.4f"), | |
| "segm_AP50": st.column_config.NumberColumn("segm_AP50", format="%.4f"), | |
| "last_submission": st.column_config.DatetimeColumn("Last Active Submission", format="D MMM YYYY, h:mm a"), | |
| }, | |
| use_container_width=True, | |
| hide_index=True, | |
| ) | |
| else: | |
| st.info("No submissions yet. Be the first to submit your model!") | |
| if __name__ == '__main__': | |
| init_db() | |
| if 'logged_in' not in st.session_state: | |
| st.session_state['logged_in'] = False | |
| st.session_state['username'] = None | |
| if not st.session_state['logged_in']: | |
| ui_login_signup() | |
| else: | |
| main_app() |