ocilab's picture
Update app.py
1af0a28 verified
Raw
History Blame Contribute Delete
2.47 kB
import spaces
import gradio as gr
import numpy as np
import tensorflow as tf
from PIL import Image
# Load the trained ANN model
model = tf.keras.models.load_model("mnist_ann.keras")
def preprocess(image):
"""Convert sketchpad/uploaded image to MNIST format:
white digit on black, cropped to bounding box, centered in 28x28."""
if image is None:
return None
# Gradio Sketchpad returns a dict with 'composite' key
if isinstance(image, dict):
image = image.get("composite")
if image is None:
return None
img = Image.fromarray(np.array(image).astype("uint8")).convert("L")
arr = np.array(img).astype("float32")
# MNIST = white digit on black background.
# Sketchpad = black drawing on white, so invert if background is white.
if arr.mean() > 127:
arr = 255.0 - arr
# --- Step 1: Crop to the bounding box of the drawing ---
mask_rows = np.any(arr > 30, axis=1)
mask_cols = np.any(arr > 30, axis=0)
if not mask_rows.any() or not mask_cols.any():
return None # empty canvas
r0, r1 = np.where(mask_rows)[0][[0, -1]]
c0, c1 = np.where(mask_cols)[0][[0, -1]]
arr = arr[r0:r1 + 1, c0:c1 + 1]
# --- Step 2: Resize to fit in 20x20 (keeping aspect ratio) ---
h, w = arr.shape
scale = 20.0 / max(h, w)
new_h = max(1, int(round(h * scale)))
new_w = max(1, int(round(w * scale)))
img_small = Image.fromarray(arr.astype("uint8")).resize(
(new_w, new_h), Image.LANCZOS
)
# --- Step 3: Paste in the center of a 28x28 black canvas ---
canvas = np.zeros((28, 28), dtype="float32")
top = (28 - new_h) // 2
left = (28 - new_w) // 2
canvas[top:top + new_h, left:left + new_w] = np.array(img_small)
# Normalize to [0, 1]
canvas = canvas / 255.0
return canvas.reshape(1, 28, 28)
@spaces.GPU(duration=10)
def predict_digit(image):
arr = preprocess(image)
if arr is None:
return {"Draw a digit first!": 1.0}
probs = model.predict(arr, verbose=0)[0]
return {str(i): float(probs[i]) for i in range(10)}
demo = gr.Interface(
fn=predict_digit,
inputs=gr.Sketchpad(label="Draw a digit (0-9)"),
outputs=gr.Label(num_top_classes=3, label="Prediction"),
title="MNIST Digit Classifier (ANN)",
description="Assignment 3 - Model Deployment | Draw a handwritten digit and the ANN model will predict it.",
)
if __name__ == "__main__":
demo.launch(ssr_mode=False)