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界面不能根据画面的放大缩小自动适应

相关推荐
这里有鱼汤1 小时前
miniQMT下载历史行情数据太慢怎么办?一招提速10倍!
前端·python
aneasystone本尊1 小时前
学习 Chat2Graph 的知识库服务
人工智能
IT_陈寒1 小时前
Redis 性能翻倍的 7 个冷门技巧,第 5 个大多数人都不知道!
前端·人工智能·后端
databook10 小时前
Manim实现脉冲闪烁特效
后端·python·动效
程序设计实验室10 小时前
2025年了,在 Django 之外,Python Web 框架还能怎么选?
python
飞哥数智坊12 小时前
GPT-5-Codex 发布,Codex 正在取代 Claude
人工智能·ai编程
倔强青铜三12 小时前
苦练Python第46天:文件写入与上下文管理器
人工智能·python·面试
虫无涯13 小时前
Dify Agent + AntV 实战:从 0 到 1 打造数据可视化解决方案
人工智能
Dm_dotnet15 小时前
公益站Agent Router注册送200刀额度竟然是真的
人工智能
算家计算15 小时前
7B参数拿下30个世界第一!Hunyuan-MT-7B本地部署教程:腾讯混元开源业界首个翻译集成模型
人工智能·开源