EyeDetection / app.py
Abbas133's picture
Update app.py
bf123e7 verified
import streamlit as st
import tensorflow as tf
import numpy as np
import cv2
from huggingface_hub import hf_hub_download
from tensorflow.keras.models import load_model
from io import BytesIO
from PIL import Image
import requests
# os module ki ab yahan directly zaroorat nahi hai, kyunki cache_dir specify nahi ho raha.
# IMPORTANT: Ensure your `requirements.txt` includes tensorflow==2.10.0 or 2.15.0.
# The `get_config` error often stems from incompatible TensorFlow versions.
# Download model from Hugging Face
repo_id = "Hammad712/closed_eye_detection"
filename = "Closed_Eye_Detection_98.h5"
try:
# Download the model to a local temporary file
# Removing cache_dir as Hugging Face handles caching internally
model_path = hf_hub_download(repo_id=repo_id, filename=filename)
# Load the downloaded model
model = load_model(model_path)
st.success("Model loaded successfully!")
except Exception as e:
st.error(f"Error loading model: {e}. Please ensure correct TensorFlow version in requirements.txt.")
st.stop() # Stop the app if there's an error
# Set image dimensions
img_height, img_width = 150, 150
# Custom CSS
def set_css(style):
"""
Function to apply custom CSS to the webpage.
"""
st.markdown(f"<style>{style}</style>", unsafe_allow_html=True)
combined_css = """
/* Main background and text colors */
.main, .sidebar .sidebar-content { background-color: #1c1c1c; color: #f0f2f6; }
/* Styling for the main content block */
.block-container { padding: 1rem 2rem; background-color: #333; border-radius: 10px; box-shadow: 0px 4px 10px rgba(0, 0, 0, 0.5); margin-bottom: 20px; }
/* Button styling */
.stButton>button, .stDownloadButton>button {
background: linear-gradient(135deg, #ff7e5f, #feb47b); /* Colorful gradient */
color: white;
border: none;
padding: 10px 24px;
text-align: center;
text-decoration: none;
display: inline-block;
font-size: 16px;
margin: 4px 2px;
cursor: pointer;
border-radius: 5px;
transition: all 0.3s ease; /* Smooth transition */
}
.stButton>button:hover, .stDownloadButton>button:hover {
opacity: 0.9;
transform: translateY(-2px); /* Lift slightly on hover */
}
/* Spinner color */
.stSpinner { color: #4CAF50; }
/* Title styling */
.title {
font-size: 3rem;
font-weight: bold;
display: flex;
align-items: center;
justify-content: center;
text-shadow: 2px 2px 5px rgba(0,0,0,0.7); /* Shadow on title */
margin-bottom: 20px;
}
/* Colorful text (gradient) */
.colorful-text {
background: -webkit-linear-gradient(135deg, #ff7e5f, #feb47b);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
/* Black-white text */
.black-white-text {
color: white; /* White color will look better */
margin-left: 10px; /* Give a little spacing */
}
/* Input field styling */
.small-input .stTextInput>div>input {
height: 2.5rem;
font-size: 1rem;
border-radius: 8px;
border: 1px solid #ff7e5f; /* Border matching gradient color */
background-color: #444;
color: #f0f2f6;
padding: 0 10px;
}
/* File uploader styling */
.small-file-uploader .stFileUploader>div>div {
height: 2.5rem;
font-size: 1rem;
}
/* Custom text (subtitle) */
.custom-text {
font-size: 1.2rem;
color: #feb47b;
text-align: center;
margin-top: -10px; /* Bring closer to title */
margin-bottom: 30px; /* More space at bottom */
}
/* Style for expander title */
.stExpander {
border: 1px solid #feb47b;
border-radius: 10px;
background-color: #282828;
}
.stExpander div[data-baseweb="button"] {
color: #feb47b !important;
font-weight: bold;
}
.stExpander > div > div > div > div > p {
color: #f0f2f6 !important;
}
"""
# Streamlit application
st.set_page_config(layout="centered", page_title="Eye Detection") # Center layout, add a page title
set_css(combined_css)
# Title and subtitle
st.markdown('<div class="title"><span class="colorful-text">آँख</span> <span class="black-white-text">डिटेक्शन मॉडल</span></div>', unsafe_allow_html=True)
st.markdown('<div class="custom-text">यह पहचानने के लिए एक छवि अपलोड करें या URL प्रदान करें कि आँखें खुली हैं या बंद।</div>', unsafe_allow_html=True)
# Input for image URL or path
with st.expander("इनपुट विकल्प", expanded=True):
url = st.text_input("छवि URL दर्ज करें", "")
uploaded_file = st.file_uploader("या एक छवि अपलोड करें", type=["jpg", "jpeg", "png"])
def load_image_from_url(url):
"""
Function to load an image from a URL.
"""
if not url:
return None
try:
response = requests.get(url, timeout=10) # Add a 10-second timeout
response.raise_for_status() # Raise an exception for HTTP errors
img = Image.open(BytesIO(response.content)).convert('RGB')
return np.array(img)
except requests.exceptions.Timeout:
st.error("Error: Timeout while downloading image from URL.")
return None
except requests.exceptions.RequestException as e:
st.error(f"Error fetching image from URL: {e}")
return None
except Exception as e:
st.error(f"Error processing image from URL: {e}")
return None
if uploaded_file is not None or url:
image = None
if uploaded_file is not None:
# Read the uploaded image
file_bytes = np.asarray(bytearray(uploaded_file.read()), dtype=np.uint8)
image = cv2.imdecode(file_bytes, 1) # OpenCV reads in BGR format
st.session_state['current_image'] = image # Save image to session state
elif url:
# Read the image from URL
with st.spinner('URL से छवि लोड हो रही है...'):
image = load_image_from_url(url)
if image is not None:
image = cv2.cvtColor(image, cv2.COLOR_RGB2BGR) # PIL gives RGB, OpenCV wants BGR
st.session_state['current_image'] = image # Save image to session state
else:
st.warning("No valid image loaded from URL.")
st.session_state['current_image'] = None
if st.session_state.get('current_image') is not None:
image_to_predict = st.session_state['current_image']
# Resize and preprocess the image
resized_image = cv2.resize(image_to_predict, (img_height, img_width))
# Reshape for model input (batch_size, height, width, channels)
input_image = resized_image.reshape((1, img_height, img_width, 3)) / 255.0
# Perform inference
with st.spinner('अनुमान लगाया जा रहा है...'):
predictions = model.predict(input_image)
prediction = predictions[0][0] # Get the single scalar value
def get_label(prediction_value):
"""
Get the label based on the prediction value.
"""
return "खुली आँख" if prediction_value >= 0.5 else "बंद आँख"
label = get_label(prediction)
# Display the image and prediction
st.image(image_to_predict, channels="BGR", caption='अपलोड की गई छवि' if uploaded_file is not None else 'URL से छवि', use_column_width=True)
# Predicted result in bold and larger font
st.markdown(f"### **अनुमान:** `{prediction:.4f}`")
st.markdown(f"### **लेबल:** <span class='{'colorful-text' if label == 'खुली आँख' else 'black-white-text'}' style='font-size: 2rem;'>{label}</span>", unsafe_allow_html=True)
# Download button for the uploaded image (optional)
img_byte_arr = BytesIO()
# Convert from OpenCV (BGR) to PIL (RGB) so PIL can save correctly
img_pil = Image.fromarray(cv2.cvtColor(image_to_predict, cv2.COLOR_BGR2RGB))
img_pil.save(img_byte_arr, format='JPEG')
img_byte_arr = img_byte_arr.getvalue()
st.download_button(
label="छवि डाउनलोड करें",
data=img_byte_arr,
file_name="processed_eye_image.jpg",
mime="image/jpeg"
)
else:
st.info("कृपया आगे बढ़ने के लिए एक छवि अपलोड करें या URL प्रदान करें।")