[Python] When run with streamlit, the modal performs properly. However, when an image is...

Discussão em 'Python' iniciado por Stack, Março 9, 2025.

  1. Stack

    Stack Membro Participativo

    I used quick draw data set to train modal. It works correctly with streamlit. But it doesn't work correctly when I input an image.

    testing purpose code

    import os
    import streamlit as st
    import numpy as np
    import tensorflow as tf
    from streamlit_drawable_canvas import st_canvas
    from PIL import Image
    import matplotlib.pyplot as plt
    from Constant.QuickDraw.quick_draw_constant import quick_draw_class_names

    # Model path
    model_path = 'quickDraw.keras'

    # Load the model if it exists
    if os.path.exists(model_path):
    try:
    model = tf.keras.models.load_model(model_path)
    st.write("✅ Model loaded successfully.")
    except Exception as e:
    st.error(f"❌ Error loading model: {e}")
    model = None
    else:
    st.error(f"❌ Model file not found: {model_path}")
    model = None

    # Canvas dimensions
    WIDTH, HEIGHT = 28, 28


    def preprocess_image(image):
    """Preprocess image for model prediction."""
    image = image.convert("L") # Convert to grayscale
    image = image.resize((WIDTH, HEIGHT)) # Resize to 28x28
    image = np.array(image) / 255.0 # Normalize
    image = image.reshape((1, HEIGHT, WIDTH, 1)) # Reshape for model input
    return image


    def predict_drawing(image, top_k=5):
    """Predict the drawing using the model."""
    pred = model.predict(image)[0]
    top_indices = (-pred).argsort()[:top_k]
    return [(quick_draw_class_names, pred) for i in top_indices]


    # Streamlit UI
    st.title(" Quick Draw Game - Draw or Upload an Image")

    # Session states for storing data
    if 'canvas_data' not in st.session_state:
    st.session_state.canvas_data = None
    if 'prediction_result' not in st.session_state:
    st.session_state.prediction_result = None

    # Create layout columns
    col1, col2 = st.columns([2, 1])

    # Canvas for drawing
    with col1:
    st.subheader("️ Draw here:")
    canvas_result = st_canvas(
    fill_color="black",
    stroke_color="white",
    stroke_width=10,
    height=HEIGHT * 10,
    width=WIDTH * 10,
    key="canvas",
    drawing_mode="freedraw",
    update_streamlit=True
    )

    # Image Uploading
    uploaded_file = st.file_uploader(" Or upload a JPG/PNG image", type=["jpg", "jpeg", "png"])

    # Prediction Button (For Both Canvas & Upload)
    if st.button(" Predict Drawing"):
    image = None # Initialize image variable

    if uploaded_file is not None:
    st.write(" Processing uploaded image...")
    uploaded_image = Image.open(uploaded_file) # Open the uploaded image
    image = preprocess_image(uploaded_image) # Preprocess the image

    # Display the converted image (grayscale, 28x28)
    st.image(uploaded_image, caption="Converted Image (Grayscale & Resized)", use_column_width=True)

    elif model is not None and canvas_result.image_data is not None:
    st.write("️ Processing drawn image...")
    image = np.array(canvas_result.image_data) # Convert canvas to NumPy array
    image = np.mean(image, axis=2) / 255.0 # Convert to grayscale & normalize
    image = Image.fromarray((image * 255).astype(np.uint8)) # Convert to PIL image
    image = preprocess_image(image) # Preprocess image for model

    # Show the preprocessed image
    st.image(image.reshape((28, 28)), caption="Converted Image (Canvas)", width=150, clamp=True)

    # Optional: Debugging - Print image as a NumPy array in the console
    print("Preprocessed Image Array:")
    print(image.reshape((28, 28)))

    # Optional: Show image using matplotlib (for debugging)
    fig, ax = plt.subplots()
    ax.imshow(image.reshape((28, 28)), cmap="gray")
    ax.axis("off")
    st.pyplot(fig)

    else:
    st.write("⚠️ Please draw something or upload an image.")

    # Perform Prediction
    if image is not None:
    predicted_value = predict_drawing(image)
    st.session_state.prediction_result = predicted_value

    # Display Prediction Result
    if st.session_state.prediction_result is not None:
    st.subheader(" Prediction Result:")
    labels = [class_name for class_name, _ in st.session_state.prediction_result]
    probabilities = [probability for _, probability in st.session_state.prediction_result]

    for class_name, probability in st.session_state.prediction_result:
    st.write(f"**{class_name}:** {probability:.2f}")

    # Display Pie Chart
    fig, ax = plt.subplots()
    ax.pie(probabilities, labels=labels, autopct='%1.1f%%', startangle=90)
    ax.axis('equal')
    st.pyplot(fig)



    Project Code

    import os
    import numpy as np
    import tensorflow as tf
    from PIL import Image
    from io import BytesIO
    from Constant.QuickDraw.quick_draw_constant import quick_draw_class_names

    # Model Path
    MODEL_PATH = "BackendTesting/QuickDraw/quickDraw.keras"

    # Load Model
    if os.path.exists(MODEL_PATH):
    try:
    model = tf.keras.models.load_model(MODEL_PATH)
    print("Model loaded successfully.")
    except Exception as e:
    print(f"Error loading model: {e}")
    model = None
    else:
    print(f"Model file not found: {MODEL_PATH}")
    model = None


    # Class Names

    def process_image(image: Image.Image):
    """Convert the image to grayscale, resize to 28x28, and normalize."""
    image = image.convert("L") # Convert to grayscale
    image = image.resize((28, 28)) # Resize to model input size
    image = np.array(image) / 255.0 # Normalize
    image = image.reshape((1, 28, 28, 1)) # Reshape for model
    return image


    def predict_drawing(image):
    """Predict the drawing using the model."""
    pred = model.predict(image)[0]
    top_index = np.argmax(pred)
    return quick_draw_class_names[top_index], pred[top_index]


    def validate_prediction(file: BytesIO, selected_object: str):
    """Processes an image and checks if the prediction matches the selected object."""
    if model is None:
    return {"error": "Model not loaded."}

    # Read and process the image
    image = Image.open(file)
    image = process_image(image)

    # Make prediction
    predicted_class, confidence = predict_drawing(image)

    # Check correctness
    is_correct = predicted_class.lower() == selected_object.lower()

    return {
    "predicted_class": predicted_class,
    "confidence": round(float(confidence), 4),
    "selected_object": selected_object,
    "is_correct": is_correct
    }



    When I give a jpg as input, the prediction should work properly. I need to change this code so that when I give a jpg, it is correctly detected and the prediction is correct. I think there is a problem with the way the input image is converted to the image. I need to fix the image conversion method of this.

    I am using these images as input. image 1 image 2

    Continue reading...

Compartilhe esta Página