import sys import streamlit as st from PIL import Image, ImageOps import tensorflow import numpy as np import base64 from io import BytesIO import joblib import os from streamlit_drawable_canvas import st_canvas BASE_DIR = os.path.dirname(os.path.abspath(__file__)) # 页面布局 st.set_page_config(page_title="图像分类平台", page_icon="🔬", layout="wide") # 页面布局 st.title('图像分类平台') st.header('手写数字识别') # 创建画布 canvas = st_canvas( fill_color="#FFFFFF", # 画布背景色 stroke_color="#000000", # 笔触颜色 height=300, # 画布高度 width=300, # 画布宽度 drawing_mode="freedraw", # 绘制模式 key='canvas' ) # 添加提交按钮 user_drew = st.button("提交并预测数字") # 加载模型 model_path = os.path.join(BASE_DIR, "model/number_model.h5") if os.path.isfile(model_path): try: num_model = tensorflow.keras.models.load_model(model_path, compile=True) except Exception as e: st.error(f"加载模型时发生错误: {e}") num_model = None else: st.error(f"模型文件不存在: {model_path}") num_flag = 1 # 执行预测 if user_drew: if canvas is not None and canvas.image_data is not None: try: # 将 NumPy 数组转换为 PIL 图像 image = canvas.image_data # 检查 canvas.image_data 是否是有效的图像数据 print("Canvas image data shape:", canvas.image_data.shape) print("Canvas image data dtype:", canvas.image_data.dtype) if canvas.image_data.shape[-1] == 4: my_image = canvas.image_data[..., 3:] else: my_image = canvas.image_data # 显示用户绘制的图像 st.image(my_image, caption='您绘制的数字') print("my_image shape:", my_image.shape) # 创建一个新的 PIL 图像,模式设置为 'L'(灰度) pil_image = Image.new('L', (my_image.shape[1], my_image.shape[0])) # 将 my_image 的数据复制到 PIL 图像中 pil_image.putdata(my_image.reshape(-1)) image = pil_image.resize((28, 28), Image.Resampling.LANCZOS) # 调整大小 st.image(image, caption='调整大小后') # 归一化图像数据 image_array = np.array(image) / 255.0 image_array = np.expand_dims(image_array, axis=-1) # 添加通道维度 image_array = np.expand_dims(image_array, axis=0) # 添加批次维度 # 显示用户绘制的图像 st.image(image_array[0, :, :, 0], caption='处理后的图像') # 打印图像数组的形状和数据类型 print("Image array shape:", image_array.shape) print("Image array dtype:", image_array.dtype) # 打印最小和最大像素值 print("Min pixel value:", image_array.min()) print("Max pixel value:", image_array.max()) # 使用模型进行预测 num_class_labels = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] predictions = num_model.predict(image_array)[0] st.write(f"predictions:{predictions}") predicted_class_index = np.argmax(predictions) st.write(f"predicted_class_index:{np.argmax(predictions)}") predicted_class = num_class_labels[predicted_class_index] st.write(f"predicted_class:{num_class_labels[predicted_class_index]}") # 获取预测的概率值 predicted_probabilities = predictions * 100 st.write(f"对于您绘制的数字的预测结果是:") st.write(f"类别:'{predicted_class}' 概率:{predicted_probabilities[predicted_class_index]:.2f}") except Exception as e: # 显示错误信息 st.error("图像处理出错") st.exception(e) num_flag = 0 else: st.warning("没有检测到图像数据。请在画布上绘制数字。") num_flag = 0