Problem in trying to run a digit classifier in a webapp that captures image in a drawing pad

14 views Asked by At

I'm trying to create a webpage using streamlit.There is a drawing pad to draw a number , from which then the image data is sent into the CNN I pretrained to print out the prediction. As I have no background in frontend or anything that has to do with webdev , i used gemini and chatgpt to make a drawing pad using p5.js and ml5.js. First i had the problem of image_data not being captured. Then after many changes it's resolved. But now the issue is after loading the model and doing the preprocessing for image_data , the prediction should be printed as per the flow . But nothing appears. I'll provide the code for streamlit below :

import streamlit as st
from streamlit.components.v1 import html
import tensorflow as tf
import numpy as np

# HTML code with JavaScript for the drawing pad 
html_code = """
<!DOCTYPE html>
<html>
<head>
  <title>Drawing Pad</title>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.0/p5.js"></script>
  <script src="https://unpkg.com/ml5@latest/dist/ml5.min.js"></script>
</head>
<body>
  <script>
    let canvas;
    let isDrawing = false;
    let lastX = 0;
    let lastY = 0;

    function setup() {
      canvas = createCanvas(680, 120);
      canvas.parent('canvas-container');
    }

    function draw() {
      if (isDrawing) {
        stroke(0);
        strokeWeight(2);
        line(pmouseX, pmouseY, mouseX, mouseY);
      }
    }

    function mousePressed() {
      isDrawing = true;
      lastX = mouseX;
      lastY = mouseY;
    }
    function mouseReleased() {
      isDrawing = false;
      let imgData = canvas.canvas.toDataURL('image/png');
      console.log("Image data captured:", imgData);
      window.dispatchEvent(new Event('predictImage'));
    }
  </script>

  <div id="canvas-container"></div>
</body>
</html>
"""


st.components.v1.html(html_code)

js_code = """
window.addEventListener('predictImage', () => {
  st.session_state.imageData = canvas.canvas.toDataURL('image/png');
});
"""
st.components.v1.html(js_code)





loaded_model = tf.keras.models.load_model("D:/Models/digit_clf.keras")
def bilinear_interpolation(image, new_width, new_height):
   
    rows, cols, channels = image.shape
    resized_image = np.zeros((new_height, new_width, channels))

    for i in range(new_height):
        for j in range(new_width):
            # Bilinear interpolation weights
            x = j / (new_width - 1) * (cols - 1)
            y = i / (new_height - 1) * (rows - 1)

            x0 = int(np.floor(x))
            x1 = x0 + 1
            y0 = int(np.floor(y))
            y1 = y0 + 1

            # Clamping to avoid out-of-bounds access
            x0 = max(0, x0)
            x1 = min(cols - 1, x1)
            y0 = max(0, y0)
            y1 = min(rows - 1, y1)

            # Interpolation weights
            wa = (x1 - x) * (y1 - y)
            wb = (x - x0) * (y1 - y)
            wc = (x1 - x) * (y - y0)
            wd = (x - x0) * (y - y0)

            # Weighted sum of neighboring pixels
            resized_image[i, j] = np.sum([wa * image[y0, x0],
                                           wb * image[y1, x0],
                                           wc * image[y0, x1],
                                           wd * image[y1, x1]], axis=0)

    return resized_image


def predict_from_image(data , model = loaded_model):
        data = bilinear_interpolation(data ,28,28)
        data = data.astype('float32') / 255.0
        data = data.values.reshape(-1,28,28,1)
        prediction = model.predict(data)
        return prediction.argmax(axis =1)


def handle_predict_event():
    if 'imageData' in st.session_state:
        image_data = st.session_state.pop('imageData')  # Pop to avoid data persistence
        prediction = predict_from_image(image_data)
        return prediction

if st.button("Submit"):
    prediction = handle_predict_event()
    st.write(f"The predicted digit is {prediction}")

I'll provide the warnings and errors: 2024-03-22 22:21:13.723671: I tensorflow/core/util/port.cc:113] oneDNN custom operations are on. You may see slightly different numerical results due to floating-point round-off errors from different computation orders. To turn them off, set the environment variable TF_ENABLE_ONEDNN_OPTS=0. 2024-03-22 22:21:14.740142: I tensorflow/core/util/port.cc:113] oneDNN custom operations are on. You may see slightly different numerical results due to floating-point round-off errors from different computation orders. To turn them off, set the environment variable TF_ENABLE_ONEDNN_OPTS=0. 2024-03-22 22:21:16.821803: I tensorflow/core/platform/cpu_feature_guard.cc:210] This TensorFlow binary is optimized to use available CPU instructions in performance-critical operations. To enable the following instructions: AVX2 AVX512F AVX512_VNNI FMA, in other operations, rebuild TensorFlow with the appropriate compiler flags. F:\vs code python\openvino_env\Lib\site-packages\keras\src\saving\saving_lib.py:396: UserWarning: Skipping variable loading for optimizer 'rmsprop', because it has 10 variables whereas the saved optimizer has 9 variables. trackable.load_own_variables(weights_store.get(inner_path)) WARNING:tensorflow:From F:\vs code python\openvino_env\Lib\site-packages\keras\src\backend\common\global_state.py:73: The name tf.reset_default_graph is deprecated. Please use tf.compat.v1.reset_default_graph instead.

The webpage :

This is the model:

I just wanted to try and using the ML model in a different application and I really had no idea whether it is possible or not. Just tried and stuck halfway. I'd like some help in this.

0

There are 0 answers