import tensorflow as tf from tensorflow.keras import layers, models, Sequential import numpy as np import matplotlib.pyplot as plt import os from PyQt6.QtWidgets import QApplication, QMainWindow, QWidget, QVBoxLayout, QPushButton, QLabel from PyQt6.QtGui import QPainter, QPen, QImage from PyQt6.QtCore import Qt, QPoint import sys data_dir = "/home/mia/Schule/KISY/schrifterkennung/" # Ignore full path, had some weird problem otherwise model_file = "model.keras" # Model save file. No Idea if this is the correct extention but nobody cares, right? print("We have done training already so we load this to not waste very precious cpu :)") model = tf.keras.models.load_model(model_file) #for images, labels in val_ds.take(10): # preds = model.predict(images) # print(f"Prediction: {class_names[np.argmax(preds[0])]}") # print(f"Label: {class_names[labels[0].numpy().astype(int)]}") # plt.imshow(images[0].numpy().squeeze(), cmap='gray') # plt.title(f"Pred: {class_names[np.argmax(preds[0])]}") # plt.show() #### DISCLAIMER: This was written by AI; I hate GUI stuff #### class DrawingCanvas(QWidget): def __init__(self): super().__init__() self.setFixedSize(320, 320) # 10x the model input size for easier drawing self.image = QImage(self.size(), QImage.Format.Format_Grayscale8) self.image.fill(Qt.GlobalColor.white) self.drawing = False self.last_point = QPoint() def paintEvent(self, event): painter = QPainter(self) painter.drawImage(0, 0, self.image) def mousePressEvent(self, event): if event.button() == Qt.MouseButton.LeftButton: self.drawing = True self.last_point = event.position().toPoint() def mouseMoveEvent(self, event): if (event.buttons() & Qt.MouseButton.LeftButton) and self.drawing: painter = QPainter(self.image) # We use a thick white pen because the model was trained on grayscale images painter.setPen(QPen(Qt.GlobalColor.black, 18, Qt.PenStyle.SolidLine, Qt.PenCapStyle.RoundCap)) painter.drawLine(self.last_point, event.position().toPoint()) self.last_point = event.position().toPoint() self.update() def clear(self): self.image.fill(Qt.GlobalColor.white) self.update() class MainWindow(QMainWindow): def __init__(self): super().__init__() self.setWindowTitle("Handwriting Recognition") main_layout = QVBoxLayout() self.canvas = DrawingCanvas() self.result_label = QLabel("Draw something and click Predict. (Need to fill entire space or model has stroke") self.result_label.setAlignment(Qt.AlignmentFlag.AlignCenter) predict_btn = QPushButton("Predict") predict_btn.clicked.connect(self.predict_image) clear_btn = QPushButton("Clear Canvas") clear_btn.clicked.connect(self.canvas.clear) main_layout.addWidget(self.canvas) main_layout.addWidget(self.result_label) main_layout.addWidget(predict_btn) main_layout.addWidget(clear_btn) container = QWidget() container.setLayout(main_layout) self.setCentralWidget(container) def predict_image(self): # 1. Resize the drawing to 32x32 to match the model input scaled_img = self.canvas.image.scaled(32, 32, Qt.AspectRatioMode.IgnoreAspectRatio, Qt.TransformationMode.SmoothTransformation) # 2. Convert QImage to Numpy Array ptr = scaled_img.bits() ptr.setsize(32 * 32) arr = np.frombuffer(ptr, np.uint8).reshape(32, 32, 1) # 3. Add batch dimension and predict # Note: We don't manually rescale by 1/255 here because your model has a Rescaling layer built-in! img_batch = np.expand_dims(arr, axis=0) prediction = model.predict(img_batch, verbose=0) print(type(prediction), prediction) class_names = list('ABCDEFGHIJKLMNOPQRSTUVWXYZ') print([x for x in zip(class_names, prediction[0])]) result = class_names[np.argmax(prediction)] confidence = np.max(prediction) * 100 self.result_label.setText(f"Prediction: {result} ({confidence:.1f}%)") if __name__ == "__main__": app = QApplication(sys.argv) app.setStyle("Breeze") # Use system theme so it looks nice on linux window = MainWindow() window.show() sys.exit(app.exec())