手写数字识别应用:画数字,一键预测

需积分: 5 0 下载量 147 浏览量 更新于2024-11-04 收藏 54KB ZIP 举报
资源摘要信息:"digit-draw-recognize" 知识点: 1. 应用程序功能描述:该应用程序的主要功能是识别手写数字。用户可以在应用程序的画布区域中自由绘制数字,并通过点击“预测”按钮来获取系统对所画数字的识别结果。如果需要重新开始绘制,可以点击“清除”按钮以清空画布。 2. 模型说明:虽然描述中未详细提供模型的具体信息,但根据应用程序的功能,我们可以推断它使用了一个机器学习模型,特别是手写数字识别模型。这类模型通常基于神经网络架构,如卷积神经网络(CNN),它们在图像识别任务中表现出色。 3. 技术栈与实现:应用程序标签为"HTML",这意味着应用程序至少部分或主要使用了HTML技术来实现前端界面。通常,前端还会涉及到CSS用于样式设计,JavaScript用于交互逻辑处理。HTML通常用于构建网页的结构,例如创建画布元素供用户绘制数字。 4. 前端交互组件:应用程序中提到的“画布”可能是指HTML5中的`<canvas>`元素,这是一个可以通过JavaScript动态绘制图形的画布区域。用户可以在画布上使用鼠标或触摸笔进行绘图,这些绘图动作可以通过JavaScript来捕捉并转化为相应的数字图像数据。 5. 预测与反馈:用户点击“预测”按钮后,系统可能会通过JavaScript调用后端服务(如果有的话),或者是通过前端运行的机器学习模型来处理画布上的数据。预测结果将返回给前端并在界面上展示给用户。这需要应用程序后端或前端具有足够的数据处理和机器学习算法实现。 6. 模型的训练与应用:手写数字识别模型的开发需要一个大量手写数字样本的数据集,如著名的MNIST数据集,用于训练模型。通过数据集上的监督学习,模型学会区分不同的数字特征。训练完成后,模型可以对新的、未见过的数字进行预测。 7. 用户体验:良好的用户体验对于此类应用程序至关重要。它应确保画布响应迅速,识别准确,预测结果易于理解。此外,用户界面应直观易用,减少用户的学习成本,提供清晰的指示让用户知道如何操作。 8. 机器学习模型的部署与优化:如果模型是在服务器端运行,它需要被有效地部署到一个可以快速响应前端请求的服务中。此外,为了确保良好的用户体验,模型的预测速度应当尽可能快。如果模型是前端实现,需要确保不会过度占用客户端资源,影响其他应用程序的运行。 通过以上知识点的总结,我们可以了解到digit-draw-recognize应用程序是一个集成了机器学习技术的前端应用程序,其核心功能是通过图像识别技术对用户手写的数字进行准确预测,并提供简洁直观的用户界面供用户使用。

from tkinter import * import cv2 import numpy as np from PIL import ImageGrab from tensorflow.keras.models import load_model from temp import * model = load_model('mnist.h5') image_folder = "img/" root = Tk() root.resizable(0, 0) root.title("HDR") lastx, lasty = None, None image_number = 0 cv = Canvas(root, width=1200, height=480, bg='white') cv.grid(row=0, column=0, pady=2, sticky=W, columnspan=2) def clear_widget(): global cv cv.delete('all') def draw_lines(event): global lastx, lasty x, y = event.x, event.y cv.create_line((lastx, lasty, x, y), width=8, fill='black', capstyle=ROUND, smooth=True, splinesteps=12) lastx, lasty = x, y def activate_event(event): global lastx, lasty cv.bind('<B1-Motion>', draw_lines) lastx, lasty = event.x, event.y cv.bind('<Button-1>', activate_event) def Recognize_Digit(): global image_number filename = f'img_{image_number}.png' root.update() widget = cv x = root.winfo_rootx() + widget.winfo_rootx() y = root.winfo_rooty() + widget.winfo_rooty() x1 = x + widget.winfo_width() y1 = y + widget.winfo_height() print(x, y, x1, y1) # get image and save ImageGrab.grab().crop((x, y, x1, y1)).save(image_folder + filename) image = cv2.imread(image_folder + filename, cv2.IMREAD_COLOR) gray = cv2.cvtColor(image.copy(), cv2.COLOR_BGR2GRAY) ret, th = cv2.threshold( gray, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU) # contours = cv2.findContours( # th, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)[0] Position = findContours(th) for m in range(len(Position)): # make a rectangle box around each curve cv2.rectangle(th, (Position[m][0], Position[m][1]), ( Position[m][2], Position[m][3]), (255, 0, 0), 1) # Cropping out the digit from the image corresponding to the current contours in the for loop digit = th[Position[m][1]:Position[m] [3], Position[m][0]:Position[m][2]] # Resizing that digit to (18, 18) resized_digit = cv2.resize(digit, (18, 18)) # Padding the digit with 5 pixels of black color (zeros) in each side to finally produce the image of (28, 28) padded_digit = np.pad(resized_digit, ((5, 5), (5, 5)), "constant", constant_values=0) digit = padded_digit.reshape(1, 28, 28, 1) digit = digit / 255.0 pred = model.predict([digit])[0] final_pred = np.argmax(pred) data = str(final_pred) + ' ' + str(int(max(pred) * 100)) + '%' print(data) font = cv2.FONT_HERSHEY_SIMPLEX fontScale = 0.5 color = (255, 0, 0) thickness = 1 cv2.putText(th, data, (Position[m][0], Position[m][1] - 5), font, fontScale, color, thickness) cv2.imshow('image', th) cv2.waitKey(0) cv2.destroyAllWindows() btn_save = Button(text='Recognize Digit', command=Recognize_Digit) btn_save.grid(row=2, column=0, pady=1, padx=1) button_clear = Button(text='Clear Widget', command=clear_widget) button_clear.grid(row=2, column=1, pady=1, padx=1) root.mainloop()

2023-04-21 上传