anamjafar6's picture
Update app.py
3c0351e verified
raw
history blame
9.74 kB
# ---- PAGE CONFIG ----
st.set_page_config(
page_title="Digit Recognition App",
page_icon="✍️",
layout="wide"
)
# ---- CUSTOM CSS STYLING ----
st.markdown("""
<style>
/* Import Google Fonts */
@import url('https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;600;700&display=swap');
/* Global Styles */
.stApp {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
font-family: 'Poppins', sans-serif;
}
/* Main container */
.main-container {
background: rgba(255, 255, 255, 0.95);
backdrop-filter: blur(10px);
border-radius: 20px;
padding: 2rem;
margin: 1rem;
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.1);
border: 1px solid rgba(255, 255, 255, 0.2);
}
/* Header styling */
.app-header {
text-align: center;
background: linear-gradient(135deg, #667eea, #764ba2);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
font-size: 3rem;
font-weight: 700;
margin-bottom: 1rem;
text-shadow: 2px 2px 4px rgba(0,0,0,0.1);
}
.app-subtitle {
text-align: center;
color: #666;
font-size: 1.1rem;
font-weight: 400;
margin-bottom: 2rem;
}
/* Sidebar styling */
.css-1d391kg {
background: linear-gradient(180deg, #667eea 0%, #764ba2 100%);
}
.sidebar-content {
background: rgba(255, 255, 255, 0.1);
backdrop-filter: blur(10px);
border-radius: 15px;
padding: 1.5rem;
margin: 1rem 0;
border: 1px solid rgba(255, 255, 255, 0.2);
}
.sidebar-header {
color: white;
font-size: 1.3rem;
font-weight: 600;
margin-bottom: 1rem;
text-align: center;
}
.sidebar-text {
color: rgba(255, 255, 255, 0.9);
font-size: 0.95rem;
line-height: 1.6;
}
/* Upload section */
.upload-section {
background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);
padding: 2rem;
border-radius: 20px;
margin: 2rem 0;
text-align: center;
box-shadow: 0 15px 30px rgba(240, 147, 251, 0.3);
}
.upload-title {
color: white;
font-size: 1.5rem;
font-weight: 600;
margin-bottom: 1rem;
}
/* Results section */
.results-container {
background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%);
padding: 2rem;
border-radius: 20px;
margin: 1rem 0;
box-shadow: 0 15px 30px rgba(79, 172, 254, 0.3);
}
.prediction-result {
background: white;
color: #333;
font-size: 2.5rem;
font-weight: 700;
text-align: center;
padding: 1rem;
border-radius: 15px;
margin: 1rem 0;
box-shadow: 0 10px 20px rgba(0,0,0,0.1);
border-left: 5px solid #4facfe;
}
/* Image container */
.image-container {
background: white;
padding: 1.5rem;
border-radius: 20px;
box-shadow: 0 10px 25px rgba(0,0,0,0.1);
text-align: center;
margin: 1rem 0;
border: 3px solid #667eea;
}
/* Chart styling */
.chart-container {
background: white;
padding: 1.5rem;
border-radius: 20px;
margin-top: 1rem;
box-shadow: 0 10px 25px rgba(0,0,0,0.1);
border-left: 5px solid #f093fb;
}
.chart-title {
color: #333;
font-size: 1.3rem;
font-weight: 600;
margin-bottom: 1rem;
text-align: center;
}
/* Footer */
.app-footer {
text-align: center;
color: #666;
font-size: 1rem;
margin-top: 3rem;
padding: 2rem;
background: rgba(255, 255, 255, 0.1);
backdrop-filter: blur(10px);
border-radius: 15px;
border: 1px solid rgba(255, 255, 255, 0.2);
}
/* Divider */
.custom-divider {
height: 3px;
background: linear-gradient(90deg, #667eea, #764ba2, #f093fb);
border: none;
border-radius: 2px;
margin: 2rem 0;
}
/* Animation for elements */
.fade-in {
animation: fadeIn 0.6s ease-in;
}
@keyframes fadeIn {
from { opacity: 0; transform: translateY(20px); }
to { opacity: 1; transform: translateY(0); }
}
/* Button styling */
.stButton > button {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
border: none;
border-radius: 25px;
padding: 0.75rem 2rem;
font-weight: 600;
font-size: 1rem;
transition: all 0.3s ease;
box-shadow: 0 5px 15px rgba(102, 126, 234, 0.3);
}
.stButton > button:hover {
transform: translateY(-2px);
box-shadow: 0 10px 25px rgba(102, 126, 234, 0.4);
}
/* Hide Streamlit elements */
#MainMenu {visibility: hidden;}
footer {visibility: hidden;}
header {visibility: hidden;}
/* File uploader styling */
.uploadedFile {
border-radius: 15px;
overflow: hidden;
}
</style>
""", unsafe_allow_html=True)
# ---- HEADER ----
st.markdown('<div class="main-container fade-in">', unsafe_allow_html=True)
st.markdown("<h1 class='app-header'>πŸ–ŠοΈ Handwritten Digit Recognizer</h1>", unsafe_allow_html=True)
st.markdown("<p class='app-subtitle'>Upload an image of a digit (0–9) and watch our AI model predict it with stunning accuracy!</p>", unsafe_allow_html=True)
st.markdown('<hr class="custom-divider">', unsafe_allow_html=True)
# ---- SIDEBAR ----
with st.sidebar:
st.markdown('<div class="sidebar-content">', unsafe_allow_html=True)
st.markdown("<h2 class='sidebar-header'>πŸ“Œ How to Use</h2>", unsafe_allow_html=True)
st.markdown("""
<div class='sidebar-text'>
<strong>Step 1:</strong> Upload a clear image of a single digit (PNG/JPG)<br><br>
<strong>Step 2:</strong> Wait for our AI model to process your image<br><br>
<strong>Step 3:</strong> View the predicted digit and confidence scores<br><br>
<em>πŸ’‘ Tip: Use images with good contrast for best results!</em>
</div>
""", unsafe_allow_html=True)
st.markdown('</div>', unsafe_allow_html=True)
st.markdown('<hr class="custom-divider">', unsafe_allow_html=True)
st.markdown('<div class="sidebar-content">', unsafe_allow_html=True)
st.markdown("<h3 class='sidebar-header'>πŸš€ About This App</h3>", unsafe_allow_html=True)
st.markdown("""
<div class='sidebar-text'>
This application uses a deep learning neural network trained on the MNIST dataset to recognize handwritten digits with high accuracy.
<br><br>
<strong>Technologies:</strong><br>
β€’ Streamlit for the interface<br>
β€’ TensorFlow for AI predictions<br>
β€’ Computer Vision processing<br>
<br>
Built with ❀️ for digit recognition
</div>
""", unsafe_allow_html=True)
st.markdown('</div>', unsafe_allow_html=True)
# ---- FILE UPLOAD ----
st.markdown('<div class="upload-section fade-in">', unsafe_allow_html=True)
st.markdown("<h2 class='upload-title'>πŸ“‚ Upload Your Digit Image</h2>", unsafe_allow_html=True)
uploaded_file = st.file_uploader("Choose an image file", type=["png", "jpg", "jpeg"], label_visibility="collapsed")
st.markdown('</div>', unsafe_allow_html=True)
if uploaded_file is not None:
col1, col2 = st.columns([1,2]) # image left, results right
with col1:
st.markdown('<div class="image-container fade-in">', unsafe_allow_html=True)
st.image(uploaded_file, caption="πŸ“Έ Your Uploaded Image", width=150)
st.markdown('</div>', unsafe_allow_html=True)
with col2:
# Preprocess (keeping original logic intact)
img = Image.open(uploaded_file).convert('L')
img = img.resize((28,28))
img_array = np.array(img) / 255.0
img_array = img_array.reshape(1,28,28,1)
# Predict (keeping original logic intact)
pred = model.predict(img_array)
pred_label = np.argmax(pred)
confidence = np.max(pred) * 100
# ---- SHOW RESULT ----
st.markdown('<div class="results-container fade-in">', unsafe_allow_html=True)
st.markdown(f"<div class='prediction-result'>🎯 Predicted Digit: {pred_label}</div>", unsafe_allow_html=True)
st.markdown(f"<p style='text-align: center; color: white; font-size: 1.2rem; margin-top: 1rem;'>Confidence: {confidence:.1f}%</p>", unsafe_allow_html=True)
st.markdown('</div>', unsafe_allow_html=True)
# Chart with custom styling
st.markdown('<div class="chart-container fade-in">', unsafe_allow_html=True)
st.markdown("<h3 class='chart-title'>πŸ“Š Prediction Probabilities</h3>", unsafe_allow_html=True)
st.bar_chart(pred[0]) # visualize probabilities (keeping original logic)
st.markdown('</div>', unsafe_allow_html=True)
# ---- FOOTER ----
st.markdown('<hr class="custom-divider">', unsafe_allow_html=True)
st.markdown("""
<div class='app-footer fade-in'>
<h3 style='color: #667eea; margin-bottom: 1rem;'>✨ Thank you for using our Digit Recognition App!</h3>
<p>Powered by cutting-edge AI technology β€’ Built with ❀️ using Streamlit & TensorFlow</p>
<p style='font-size: 0.9rem; opacity: 0.8; margin-top: 1rem;'>
πŸ”¬ Continuously learning and improving β€’ 🌟 Accuracy rates above 95%
</p>
</div>
""", unsafe_allow_html=True)
st.markdown('</div>', unsafe_allow_html=True)