import streamlit as st # makes the web app import numpy as np #handles math & image arrays import cv2 #image processing(resize, grayscale) from PIL import Image # image handling, works with uploaded images from tensorflow.keras.models import load_model #loads the trained mnist model from streamlit_drawable_canvas import st_canvas #Imports the drawable canvas component for Streamlit which lets you draw digits inside app #This sets up the web app title, icon, and layout. st.set_page_config( page_title="Digit Recognition App", page_icon="π’", layout="wide" ) # The CSS part changes the background color gradient st.markdown( """ """, unsafe_allow_html=True ) # This loads the trained model (mnist_cnn.h5) that recognizes digits. @st.cache_resource #makes sure the model loads only once, not every time you interact. def load_cnn_model(): return load_model("mnist_cnn.h5") #loads the saved model file mnist_cnn.h5. model = load_cnn_model() #stores the loaded model in the variable model so you can call it later. # ---- Preprocessing Helpers ---- def preprocess_pil_file(file_or_pil_image): #Defines a function which accepts either a file or a Image. if not isinstance(file_or_pil_image, Image.Image): img = Image.open(file_or_pil_image) #If the input is not already a PIL Image object, use Image.open() to load it. Otherwise, use it directly. else: img = file_or_pil_image #PIL = Python Imaging Library .Itβs a library that helps you open, edit, and save images in Python. img = img.convert('L').resize((28, 28)) # Convert to grayscale & resize arr = np.array(img).astype('float32') / 255.0 # Normalize (0β1 scale) if arr.mean() > 0.5: # invert if background is white arr = 1.0 - arr arr = arr.reshape(1, 28, 28, 1).astype('float32') #Reshape to fit model input. return arr, Image.fromarray((arr[0, :, :, 0] * 255).astype('uint8')) def preprocess_canvas_image(image_data): if image_data is None: return None, None img_uint8 = image_data.astype('uint8') if img_uint8.shape[2] == 4: # RGBA alpha = img_uint8[..., 3] / 255.0 rgb = img_uint8[..., :3].astype('float32') white = np.ones_like(rgb) * 255.0 comp = (rgb * alpha[..., None] + white * (1 - alpha[..., None])).astype('uint8') gray = cv2.cvtColor(comp, cv2.COLOR_RGB2GRAY) else: gray = cv2.cvtColor(img_uint8, cv2.COLOR_RGB2GRAY) # convert canvas to grayscale small = cv2.resize(gray, (28, 28), interpolation=cv2.INTER_AREA).astype('float32') / 255.0 if small.mean() > 0.5: small = 1.0 - small arr = small.reshape(1, 28, 28, 1).astype('float32') display_img = Image.fromarray((small * 255).astype('uint8')) return arr, display_img # ---- Header ---- st.markdown("
Confidence: {conf*100:.2f}%
Built with β€οΈ using Streamlit & TensorFlow | By Anam Jafar
", unsafe_allow_html=True )