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

相关推荐
cczixun7 分钟前
OpenAI连发GPT-5.5系列:免费版幻觉大降,安全版能力飙升,千亿融资估值直冲8520亿美元
人工智能·gpt·安全
飞Link14 分钟前
商汤 SenseNova 6.7 Flash-Lite 深度评测:原生多模态 Agent 的“降本增效”终极方案?
人工智能
飞Link18 分钟前
OpenAI 与微软“非排他性”协议解读:AI 云计算市场将迎来百家争鸣?
人工智能·microsoft·云计算
徐健峰1 小时前
GPT-image-2 热门玩法实战(三):AI 手办/Action Figure — 把自己变成盒装玩具
人工智能
扑兔AI1 小时前
B2B销售线索挖掘效率提升的技术实践:基于工商公开数据的客源筛选与竞品分析架构
大数据·人工智能·架构
亚鲁鲁1 小时前
00-目录
人工智能
罗西的思考1 小时前
【GUI-Agent】阿里通义MAI-UI 代码阅读(2)--- 实现
人工智能·算法·机器学习
阿豪只会阿巴1 小时前
【没事学点啥】TurboBlog轻量级个人博客项目——项目介绍
javascript·python·django·html
墨染天姬2 小时前
【AI】cursor提示词小技巧
前端·数据库·人工智能
Raink老师2 小时前
【AI面试临阵磨枪-40】文本切块(Chunking)策略:固定长度、语义切块、递归切块、重叠设计
人工智能·ai 面试