anamjafar6 commited on
Commit
e9929d4
Β·
verified Β·
1 Parent(s): 3147f21

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +91 -34
app.py CHANGED
@@ -1,62 +1,119 @@
 
 
1
  import streamlit as st
2
  import numpy as np
 
3
  from PIL import Image
4
  from tensorflow.keras.models import load_model
 
 
 
 
 
 
 
 
5
 
6
- # Load trained model (placed in same directory as app.py)
7
- @st.cache_resource # cache so model loads only once
 
 
 
 
 
 
 
 
 
 
 
 
8
  def load_cnn_model():
9
  return load_model("mnist_cnn.h5")
10
 
11
  model = load_cnn_model()
12
 
13
- # ---- PAGE CONFIG ----
14
- st.set_page_config(
15
- page_title="Digit Recognition App",
16
- page_icon="✍️",
17
- layout="wide"
18
  )
19
-
20
- # ---- HEADER ----
21
- st.markdown("<h1 style='text-align: center; color: #4CAF50;'>πŸ–ŠοΈ Handwritten Digit Recognizer</h1>", unsafe_allow_html=True)
22
- st.write("Upload an image of a digit (0–9) and the model will predict it.")
23
  st.markdown("---")
24
 
25
- # ---- SIDEBAR ----
26
  st.sidebar.header("πŸ“Œ Instructions")
27
  st.sidebar.info(
28
- "1. Upload a clear image of a single digit (PNG/JPG).\n"
29
- "2. Wait for the model to process.\n"
30
- "3. See the predicted digit and probabilities."
31
  )
32
 
33
  st.sidebar.markdown("---")
34
- st.sidebar.write("πŸ‘©β€πŸ’» **About**: Built with ❀️ using Streamlit & TensorFlow")
35
-
36
- # ---- FILE UPLOAD ----
37
- uploaded_file = st.file_uploader("πŸ“‚ Upload your digit image", type=["png", "jpg", "jpeg"])
38
 
39
- if uploaded_file is not None:
40
- col1, col2 = st.columns([1,2]) # image left, results right
 
 
 
 
41
 
42
- with col1:
43
- st.image(uploaded_file, caption="Uploaded Image", width=150)
 
44
 
45
- with col2:
46
- # Preprocess
47
- img = Image.open(uploaded_file).convert('L')
48
- img = img.resize((28,28))
49
  img_array = np.array(img) / 255.0
50
- img_array = img_array.reshape(1,28,28,1)
51
 
52
- # Predict
53
  pred = model.predict(img_array)
54
  pred_label = np.argmax(pred)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
55
 
56
- # ---- SHOW RESULT ----
57
- st.markdown(f"<h2 style='color: #FF5733;'>Predicted Digit: {pred_label}</h2>", unsafe_allow_html=True)
58
- st.bar_chart(pred[0]) # visualize probabilities
 
 
 
 
 
 
59
 
60
- # ---- FOOTER ----
 
 
 
61
  st.markdown("---")
62
- st.markdown("<p style='text-align: center;'>Built with ❀️ using Streamlit & TensorFlow</p>", unsafe_allow_html=True)
 
 
 
 
1
+
2
+ # ---- Import Libraries ----
3
  import streamlit as st
4
  import numpy as np
5
+ import cv2
6
  from PIL import Image
7
  from tensorflow.keras.models import load_model
8
+ from streamlit_drawable_canvas import st_canvas
9
+
10
+ # ---- Page Config ----
11
+ st.set_page_config(
12
+ page_title="Digit Recognition App",
13
+ page_icon="πŸ”’",
14
+ layout="wide"
15
+ )
16
 
17
+ # ---- Custom Background with CSS ----
18
+ st.markdown(
19
+ """
20
+ <style>
21
+ .stApp {
22
+ background: linear-gradient(to right, #f8f9fa, #e3f2fd);
23
+ }
24
+ </style>
25
+ """,
26
+ unsafe_allow_html=True
27
+ )
28
+
29
+ # ---- Load Model ----
30
+ @st.cache_resource
31
  def load_cnn_model():
32
  return load_model("mnist_cnn.h5")
33
 
34
  model = load_cnn_model()
35
 
36
+ # ---- Header ----
37
+ st.markdown(
38
+ "<h1 style='text-align: center; color: #0D47A1;'> πŸ”’ Handwritten Digit Recognizer </h1>",
39
+ unsafe_allow_html=True
 
40
  )
41
+ st.write("Upload or draw a digit (0–9), and the model will predict it.")
 
 
 
42
  st.markdown("---")
43
 
44
+ # ---- Sidebar ----
45
  st.sidebar.header("πŸ“Œ Instructions")
46
  st.sidebar.info(
47
+ "1. Upload a clear image of a single digit (PNG/JPG), **or draw your digit below**.\n"
48
+ "2. The image will be preprocessed automatically.\n"
49
+ "3. The model predicts the digit and confidence level."
50
  )
51
 
52
  st.sidebar.markdown("---")
53
+ st.sidebar.write("πŸ‘©β€πŸ’» **About**: Built with ❀️ by **Anam Jafar**")
54
+ st.sidebar.write("[πŸ”— Connect on LinkedIn](https://www.linkedin.com/in/anam-jafar)")
 
 
55
 
56
+ # ---- File Upload ----
57
+ uploaded_files = st.file_uploader(
58
+ "πŸ“‚ Upload digit images (single or multiple):",
59
+ type=["png", "jpg", "jpeg"],
60
+ accept_multiple_files=True
61
+ )
62
 
63
+ if uploaded_files:
64
+ st.subheader("πŸ“· Uploaded Images & Predictions")
65
+ cols = st.columns(len(uploaded_files)) # grid layout
66
 
67
+ for idx, file in enumerate(uploaded_files):
68
+ img = Image.open(file).convert('L').resize((28, 28))
 
 
69
  img_array = np.array(img) / 255.0
70
+ img_array = img_array.reshape(1, 28, 28, 1)
71
 
 
72
  pred = model.predict(img_array)
73
  pred_label = np.argmax(pred)
74
+ confidence = np.max(pred)
75
+
76
+ with cols[idx]:
77
+ st.image(file, caption=f"Pred: {pred_label} ({confidence*100:.1f}%)", width=120)
78
+
79
+ # ---- Drawing Pad ----
80
+ st.subheader("πŸ–ŒοΈ Draw your digit here:")
81
+ canvas_result = st_canvas(
82
+ stroke_width=12,
83
+ stroke_color="#000000",
84
+ background_color="#FFFFFF",
85
+ width=280,
86
+ height=280,
87
+ drawing_mode="freedraw",
88
+ key="canvas",
89
+ )
90
+
91
+ if canvas_result.image_data is not None:
92
+ img = cv2.resize(canvas_result.image_data.astype("uint8"), (28, 28))
93
+ img = cv2.cvtColor(img, cv2.COLOR_RGBA2GRAY)
94
+ img = img / 255.0
95
+ img = img.reshape(1, 28, 28, 1)
96
+
97
+ pred = model.predict(img)
98
+ pred_label = np.argmax(pred)
99
+ confidence = np.max(pred)
100
 
101
+ st.markdown(
102
+ f"""
103
+ <div style="padding:15px; border-radius:10px; background-color:#FFF3CD; text-align:center;">
104
+ <h2 style="color:#D32F2F;"> 🎯 Predicted Digit: {pred_label} </h2>
105
+ <p>Confidence: {confidence*100:.2f}%</p>
106
+ </div>
107
+ """,
108
+ unsafe_allow_html=True
109
+ )
110
 
111
+ # Probability bar chart
112
+ st.bar_chart(pred[0])
113
+
114
+ # ---- Footer ----
115
  st.markdown("---")
116
+ st.markdown(
117
+ "<p style='text-align: center;'>Built with ❀️ using Streamlit & TensorFlow | By <b>Anam Jafar</b></p>",
118
+ unsafe_allow_html=True
119
+ )