tensorflow手写自动识别数字(0-9)

用python的tensorflow包写了个手写自动识别的py脚本

前提条件

python 复制代码
pip install tensorflow pillow numpy matplotlib
python 复制代码
import tensorflow as tf
from tensorflow.keras import datasets, layers, models
import numpy as np
import tkinter as tk
from PIL import Image, ImageOps, ImageDraw
from tkinter import ttk

# 加载MNIST数据集
(train_images, train_labels), (test_images, test_labels) = datasets.mnist.load_data()
train_images, test_images = train_images / 255.0, test_images / 255.0

# 构建卷积神经网络模型
model = models.Sequential([
    layers.Conv2D(32, (3, 3), activation='relu', input_shape=(28, 28, 1)),
    layers.MaxPooling2D((2, 2)),
    layers.Conv2D(64, (3, 3), activation='relu'),
    layers.MaxPooling2D((2, 2)),
    layers.Conv2D(64, (3, 3), activation='relu'),
    layers.Flatten(),
    layers.Dense(64, activation='relu'),
    layers.Dense(10, activation='softmax')
])

# 编译并训练模型
model.compile(optimizer='adam',
              loss='sparse_categorical_crossentropy',
              metrics=['accuracy'])
model.fit(train_images[..., np.newaxis], train_labels, epochs=5, validation_data=(test_images[..., np.newaxis], test_labels))

# Tkinter UI 界面,手写输入并预测数字
class DigitRecognizerApp:
    def __init__(self, root):
        self.root = root
        self.root.title("Handwritten Digit Recognition")

        # 创建画布用于手写,绑定窗口大小变化时调整画布大小
        self.canvas = tk.Canvas(self.root, bg='white')
        self.canvas.grid(row=0, column=0, pady=2, padx=2, sticky="nsew")
        self.canvas.bind("<B1-Motion>", self.paint)
        self.canvas.bind("<Configure>", self.resize_canvas)

        # 初始图像对象
        self.image = Image.new("L", (200, 200), 255)
        self.draw = ImageDraw.Draw(self.image)

        # 按钮:清除画布
        self.clear_button = tk.Button(self.root, text="Clear", command=self.clear_canvas)
        self.clear_button.grid(row=1, column=0, pady=2, sticky="ew")

        # 按钮:预测数字
        self.predict_button = tk.Button(self.root, text="Predict", command=self.predict_digit)
        self.predict_button.grid(row=2, column=0, pady=2, sticky="ew")

        # 结果显示区
        self.result_label = tk.Label(self.root, text="Prediction: None", font=('Helvetica', 16))
        self.result_label.grid(row=3, column=0, pady=2, sticky="ew")

        # 概率显示区 - 显示最高概率数字和所有概率
        self.prob_frame = tk.Frame(self.root)
        self.prob_frame.grid(row=4, column=0, pady=2, sticky="nsew")
        self.highest_prob_label = tk.Label(self.prob_frame, text="Highest Probability: None", font=('Helvetica', 12))
        self.highest_prob_label.pack(pady=2)
        self.prob_text = tk.Text(self.prob_frame, height=10, font=('Helvetica', 12))
        self.prob_text.pack(fill=tk.BOTH, expand=True)

        # 调整窗口布局
        self.root.grid_rowconfigure(0, weight=1)
        self.root.grid_columnconfigure(0, weight=1)
        self.root.grid_rowconfigure(4, weight=1)  # 使概率显示区域自适应

    def paint(self, event):
        # 在画布上绘制手写输入
        x, y = event.x, event.y
        r = 8  # 手写笔的半径
        self.canvas.create_oval(x-r, y-r, x+r, y+r, fill='black')
        self.draw.ellipse([x-r, y-r, x+r, y+r], fill='black')

    def resize_canvas(self, event):
        # 调整图像大小,保持用户手写的内容
        new_width, new_height = event.width, event.height
        self.image = self.image.resize((new_width, new_height), Image.ANTIALIAS)
        self.draw = ImageDraw.Draw(self.image)

    def clear_canvas(self):
        # 清除画布
        self.canvas.delete("all")
        self.image = Image.new("L", (self.canvas.winfo_width(), self.canvas.winfo_height()), 255)
        self.draw = ImageDraw.Draw(self.image)
        self.result_label.config(text="Prediction: None")
        self.highest_prob_label.config(text="Highest Probability: None")
        self.prob_text.delete(1.0, tk.END)

    def predict_digit(self):
        # 将用户手写的图像处理为模型输入格式
        img = self.image.resize((28, 28))  # 将图像调整为28x28
        img = ImageOps.invert(img)  # 反转颜色,黑底白字
        img = np.array(img).reshape(1, 28, 28, 1) / 255.0  # 标准化

        # 使用模型进行预测
        predictions = model.predict(img)
        predicted_digit = np.argmax(predictions[0])  # 最高概率的数字
        probabilities = predictions[0]  # 每个数字的概率
        highest_prob = probabilities[predicted_digit]  # 获取最高概率

        # 更新UI显示结果
        self.result_label.config(text=f"Prediction: {predicted_digit}")
        self.highest_prob_label.config(text=f"Highest Probability: {predicted_digit} ({highest_prob:.4f})")

        # 显示所有数字的概率
        self.prob_text.delete(1.0, tk.END)
        for i in range(10):
            self.prob_text.insert(tk.END, f"Digit {i}: {probabilities[i]:.4f}\n")

# 启动应用程序
if __name__ == "__main__":
    root = tk.Tk()
    app = DigitRecognizerApp(root)
    root.mainloop()

还有点缺陷就是不能ui界面不能根据画面的放大缩小自动适应

相关推荐
晚霞apple4 分钟前
三维重建技术的未来创新方向
论文阅读·人工智能·深度学习·神经网络·机器学习
NocoBase11 分钟前
GitHub 上最值得关注的 14 个开源 AI 低代码工具
人工智能·低代码·github
无风听海22 分钟前
神经网络之语义空间
人工智能·深度学习·神经网络
cxr82839 分钟前
AI提示工程第一性原理:精通原子提示,激发语言模型的基本单位
人工智能·语言模型·自然语言处理
X.AI6661 小时前
YouTube评论情感分析项目84%正确率:基于BERT的实战复现与原理解析
人工智能·深度学习·bert
Python×CATIA工业智造1 小时前
Pycatia二次开发基础代码解析:组件识别、选择反转与链接创建技术解析
python·pycharm
艾莉丝努力练剑1 小时前
【C++:继承】面向对象编程精要:C++继承机制深度解析与最佳实践
开发语言·c++·人工智能·继承·c++进阶
小宁爱Python1 小时前
从零搭建 RAG 智能问答系统 6:Text2SQL 与工作流实现数据库查询
数据库·人工智能·python·django
Hard_Liquor1 小时前
Datawhale秋训营-“大运河杯”数据开发应用创新大赛
人工智能·深度学习·算法
m0_748241231 小时前
Java注解与反射实现日志与校验
java·开发语言·python