使用PyQt展示手写体数字识别的结果

RuntimeError: mat1 and mat2 shapes cannot be multiplied (5760x6 and 128x4):

手写体数字识别的官方数据集图像都是28×28的图像,所以将训练好的模型拿来读取自己的图片的时候要将图片转成28×28的大小。

PyQt如何打印一个返回值

加入一个str()

需要靠test2文件来获取图片路径,需要靠handwritng_detection来对图片进行深度学习,来输出的分类,但是如果两个操作分别在两个python文件里执行,会互相导入对方的包导致出现“import circulation”的问题,所以我在handwriting_detection文件里将模型训练好后保存通过save操作保存模型,将随机选取手写体图片进行识别的代码块放入test2文件中,再通过load加载出刚刚保存好的模型,再test2中先后实现“获取指定图片路径”、“检测图片”的操作。

以下是具体代码。

 main:

# 这是一个示例 Python 脚本。

# 按 Shift+F10 执行或将其替换为您的代码。
# 按 双击 Shift 在所有地方搜索类、文件、工具窗口、操作和设置。

import sys
# from PyQt5.QtWidgets import QApplication, QMainWindow, QFileDialog
from PyQt5.QtWidgets import QApplication

from enterTest1 import FirstWindowActions
# 从enterTest1里导入FirstWindowActions功能(函数)

if __name__ == '__main__':
    # 界面的入口,在这里需要定义QApplication对象,之后界面跳转时不用重新定义,只需要调用show()函数jike
    app = QApplication(sys.argv)
    # 显示创建的界面
    MainWindow = FirstWindowActions()  # 创建窗体对象
    MainWindow.show()  # 显示窗体

    sys.exit(app.exec_())  # 程序关闭时退出进程

test1(第一个界面的后前端代码):

import sys

from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtGui import QPalette, QPixmap, QBrush
from PyQt5.QtWidgets import QApplication, QMainWindow


class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(943, 641)
        # 给MainWindow设置背景图片
        # palette = QPalette()
        # palette.setBrush(QPalette.Background, QBrush(QPixmap('D:\\python\\RRJ\\pycharmproject\\Practice\\chep2\\bdd'
        #                                                      '\\background3.jpg')))
        # MainWindow.setPalette(palette)

        # # 给MainWindow设置背景图片
        # palette = QPalette()
        # palette.setBrush(QPalette.Background, QBrush(QPixmap("D:\Softwares\Anaconda3\Project\pythonProject1\sumiao\face.jpg")))
        # MainWindow.setPalette(palette)

        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.label_2 = QtWidgets.QLabel(self.centralwidget)
        self.label_2.setGeometry(QtCore.QRect(140, 220, 101, 31))
        self.label_2.setStyleSheet("font:32px;")
        self.label_2.setObjectName("label_2")
        self.label_3 = QtWidgets.QLabel(self.centralwidget)
        self.label_3.setGeometry(QtCore.QRect(140, 320, 101, 31))
        self.label_3.setStyleSheet("font:32px;")
        self.label_3.setObjectName("label_3")
        self.lineEdit = QtWidgets.QLineEdit(self.centralwidget)
        self.lineEdit.setGeometry(QtCore.QRect(250, 220, 181, 31))
        self.lineEdit.setObjectName("lineEdit")
        self.lineEdit_2 = QtWidgets.QLineEdit(self.centralwidget)
        self.lineEdit_2.setGeometry(QtCore.QRect(250, 320, 181, 31))
        self.lineEdit_2.setObjectName("lineEdit_2")
        self.pushButton = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton.setGeometry(QtCore.QRect(180, 410, 181, 51))
        self.pushButton.setStyleSheet("color:rgb(101,153,26);\n"
                                      "background-color:rgb(198,224,205);\n"
                                      "hover{color:red};\n"
                                      "border-radius:6px;\n"
                                      "font:28px;")
        self.pushButton.setObjectName("pushButton")
        self.label = QtWidgets.QLabel(self.centralwidget)
        self.label.setGeometry(QtCore.QRect(170, 50, 651, 101))
        self.label.setStyleSheet("border-width:0px;\n"
                                 "border-style:solid;\n"
                                 "border-color:rgb(50, 50, 50);\n"
                                 "font:54px;\n"
                                 "\n"
                                 "color:rgb(255, 170, 0)")
        self.label.setObjectName("label")
        self.label_6 = QtWidgets.QLabel(self.centralwidget)
        self.label_6.setGeometry(QtCore.QRect(490, 170, 361, 361))
        # self.label_6.setStyleSheet("border-width:1px;\n"
        #                            "border-style:solid;")
        self.label_6.setText("")
        self.label_6.setObjectName("label_6")
        # 给label添加背景图片
        # png = QPixmap('D:\\download\\hg.jpg')
        png = QPixmap('D:\Softwares\Anaconda3\Project\pythonProject1\handwriting_detection\img.png')
        self.label_6.setPixmap(png)
        # 图片自适应窗体大小
        self.label_6.setScaledContents(True)

        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtWidgets.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 943, 26))
        self.menubar.setObjectName("menubar")
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
        self.label_2.setText(_translate("MainWindow", "用户名"))
        self.label_3.setText(_translate("MainWindow", "密  码"))
        self.pushButton.setText(_translate("MainWindow", "登 录"))
        self.label.setText(_translate("MainWindow", "欢迎使用手写体数字识别器"))

enterTest1(第一个界面的后端代码):

import sys

import enterTest2
import test1
from PyQt5.QtWidgets import QApplication, QMainWindow, QWidget, QFileDialog, QMessageBox
from PyQt5 import QtWidgets


# 这里定义的第一个界面的后端代码需要继承两个类
class FirstWindowActions(test1.Ui_MainWindow, QMainWindow):

    def __init__(self):
        super(test1.Ui_MainWindow, self).__init__()
        # 创建界面
        self.setupUi(self)
        self.pushButton.clicked.connect(self.click_login_button)

    def click_login_button(self):
        """点击登录按钮,跳转到相应界面"""

        # 实例化第二个界面的后端类,并对第二个界面进行显示
        self.scend_window = enterTest2.SecondWindowActions()
        # 显示第二个界面
        self.scend_window.show()
        # 关闭第一个界面
        self.close()

# if __name__ == '__main__':
#     # 界面的入口,在这里需要定义QApplication对象,之后界面跳转时不用重新定义,只需要调用show()函数jikt
#     app = QApplication(sys.argv)
#     # 显示创建的界面
#     MainWindow = FirstWindowActions()  # 创建窗体对象
#     MainWindow.show()  # 显示窗体
#
#     sys.exit(app.exec_())  # 程序关闭时退出进程
'''
enterTest1文件中有关联函数,是因为关联的函数就是打开第二个界面,可以直接写在同一个Python文件中,很简单;
enterTest2文件中没有关联函数,是因为关联的函数很多,就将关联的函数和关联函数的声明另存与另一个文件。
'''

test2(第二个界面的前端代码):

主要是在startAction函数里进行了改动。

# -*- coding: utf-8 -*-

# Form implementation generated from reading ui file 'test2.ui'
#
# Created by: PyQt5 UI code generator 5.15.4
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again.  Do not edit this file unless you know what you are doing.
'''
这个文件用于显示PyQt,无需输入正确的账号和密码就可以登录进去
选择图片的时候只能选择28*28像素的图片,也就是TestDigitImgs的第一张图片
'''

import cv2
import numpy as np
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtGui import QPixmap, QBrush
from PyQt5.QtWidgets import QFileDialog, QApplication
from PyQt5.QtGui import QIcon

from PyQt5.QtGui import QPalette
# from handwriting_detection import *

from torch.autograd import Variable
import torch.nn.functional as F

import torch
from torch import nn
from torch import optim
from torch.nn.parameter import Parameter
import torchvision
import torchvision.transforms as transforms
import torch.nn.functional as F
import numpy as np
# from model import *
import cv2

class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        # 给MainWindow设置图标
        # MainWindow.setWindowIcon(QIcon('D:\\download\\xj.ico'))  # 路径错误找不到问题所在
        # MainWindow.setWindowIcon(QIcon('D:\\Softwares\\Anaconda3\\Project\\pythonProject1\\sumiao\\shou.png'))


        # 给MainWindow设置背景图片
        # palette = QPalette()
        # palette.setBrush(QPalette.Background, QBrush(QPixmap('D:\\python\\RRJ\\pycharmproject\\Practice\\chep2\\bdd'
        #                                                      '\\background3.jpg')))
        # MainWindow.setPalette(palette)

        # 给MainWindow设置背景图片
        # palette = QPalette()
        # palette.setBrush(QPalette.Background, QBrush(QPixmap('"D:\\Softwares\\Anaconda3\\Project\\pythonProject1\\sumiao\\back.jpg"')))
        # MainWindow.setPalette(palette)

        MainWindow.resize(994, 783)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.label = QtWidgets.QLabel(self.centralwidget)
        self.label.setGeometry(QtCore.QRect(10, 0, 961, 721))
        self.label.setStyleSheet("font:28px;\n"
                                 "border-style:solid;\n"
                                 "border-width:1px;\n"
                                 "border-color:rgb(0, 0, 0);\n"
                                 "\n"
                                 "")
        self.label.setText("")
        self.label.setObjectName("label")
        self.pushButton_2 = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton_2.setGeometry(QtCore.QRect(50, 150, 121, 41))
        self.pushButton_2.setStyleSheet("font:22px;")
        self.pushButton_2.setObjectName("pushButton_2")
        self.label_2 = QtWidgets.QLabel(self.centralwidget)
        self.label_2.setGeometry(QtCore.QRect(340, 30, 321, 81))
        self.label_2.setStyleSheet("font: 75 26pt \"Segoe Print\";\n"
                                   "color:rgb(255, 85, 0);\n"
                                   "text-align:center;\n"
                                   "letter-spacing:4pt;")
        self.label_2.setObjectName("label_2")
        self.line = QtWidgets.QFrame(self.centralwidget)
        self.line.setGeometry(QtCore.QRect(10, 120, 961, 20))
        self.line.setFrameShape(QtWidgets.QFrame.HLine)
        self.line.setFrameShadow(QtWidgets.QFrame.Sunken)
        self.line.setObjectName("line")
        self.line_2 = QtWidgets.QFrame(self.centralwidget)
        self.line_2.setGeometry(QtCore.QRect(10, 200, 961, 16))
        self.line_2.setFrameShape(QtWidgets.QFrame.HLine)
        self.line_2.setFrameShadow(QtWidgets.QFrame.Sunken)
        self.line_2.setObjectName("line_2")
        self.lineEdit_3 = QtWidgets.QLineEdit(self.centralwidget)
        self.lineEdit_3.setGeometry(QtCore.QRect(170, 150, 321, 41))
        self.lineEdit_3.setObjectName("lineEdit_3")
        self.pushButton_3 = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton_3.setGeometry(QtCore.QRect(530, 150, 151, 41))
        self.pushButton_3.setStyleSheet("font: 22px;")
        self.pushButton_3.setObjectName("pushButton_3")
        self.pushButton_4 = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton_4.setGeometry(QtCore.QRect(730, 150, 151, 41))
        self.pushButton_4.setStyleSheet("font:22px;")
        self.pushButton_4.setObjectName("pushButton_4")
        self.label_3 = QtWidgets.QLabel(self.centralwidget)
        self.label_3.setGeometry(QtCore.QRect(50, 270, 411, 421))
        self.label_3.setStyleSheet("font:28px;\n"
                                   "border-style:solid;\n"
                                   "border-width:1px;\n"
                                   "border-color:rgb(45, 45, 45);\n"
                                   "\n"
                                   "")
        self.label_3.setText("")
        self.label_3.setObjectName("label_3")
        self.label_4 = QtWidgets.QLabel(self.centralwidget)
        self.label_4.setGeometry(QtCore.QRect(540, 270, 401, 421))
        self.label_4.setStyleSheet("font:28px;\n"
                                   "border-style:solid;\n"
                                   "border-width:1px;\n"
                                   "border-color:rgb(45, 45, 45);\n"
                                   "\n"
                                   "")
        self.label_4.setText("")
        self.label_4.setObjectName("label_4")
        self.label_5 = QtWidgets.QLabel(self.centralwidget)
        self.label_5.setGeometry(QtCore.QRect(220, 230, 91, 31))
        self.label_5.setStyleSheet("font: 14pt \"Arial\";")
        self.label_5.setObjectName("label_5")
        self.label_6 = QtWidgets.QLabel(self.centralwidget)
        self.label_6.setGeometry(QtCore.QRect(710, 230, 72, 31))
        self.label_6.setStyleSheet("font: 14pt \"Arial\";")
        self.label_6.setObjectName("label_6")
        self.label.raise_()
        self.pushButton_2.raise_()
        self.line.raise_()
        self.line_2.raise_()
        self.label_2.raise_()
        self.lineEdit_3.raise_()
        self.pushButton_3.raise_()
        self.pushButton_4.raise_()
        self.label_3.raise_()
        self.label_4.raise_()
        self.label_5.raise_()
        self.label_6.raise_()
        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtWidgets.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 994, 26))
        self.menubar.setObjectName("menubar")
        self.menutest2 = QtWidgets.QMenu(self.menubar)
        self.menutest2.setObjectName("menutest2")
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)
        self.actiondemo1 = QtWidgets.QAction(MainWindow)
        self.actiondemo1.setObjectName("actiondemo1")
        self.actiondemo2 = QtWidgets.QAction(MainWindow)
        self.actiondemo2.setObjectName("actiondemo2")
        self.menutest2.addAction(self.actiondemo1)
        self.menutest2.addAction(self.actiondemo2)
        self.menubar.addAction(self.menutest2.menuAction())

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

        # 按钮关联函数
        self.pushButton_2.clicked.connect(self.openImage)
        self.pushButton_3.clicked.connect(self.startAction)
        self.pushButton_4.clicked.connect(self.saveImage)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "手写体识别"))
        self.pushButton_2.setText(_translate("MainWindow", "选择图片"))
        self.label_2.setText(_translate("MainWindow", "手写体数字识别"))
        self.pushButton_3.setText(_translate("MainWindow", "开始"))
        self.pushButton_4.setText(_translate("MainWindow", "保存"))
        self.label_5.setText(_translate("MainWindow", "所选图像"))
        self.label_6.setText(_translate("MainWindow", "识别结果"))
        self.menutest2.setTitle(_translate("MainWindow", "test2"))
        self.actiondemo1.setText(_translate("MainWindow", "demo1"))
        self.actiondemo2.setText(_translate("MainWindow", "demo2"))

    # 选择本地图片上传
    def openImage(self):
        global imgNamepath  # 这里为了方便别的地方引用图片路径,将其设置为全局变量
        # 弹出一个文件选择框,第一个返回值imgName记录选中的文件路径+文件名,第二个返回值imgType记录文件的类型
        # QFileDialog就是系统对话框的那个类第一个参数是上下文,第二个参数是弹框的名字,第三个参数是默认打开的路径,第四个参数是需要的格式
        # imgNamepath, imgType = QFileDialog.getOpenFileName(self.centralwidget, "选择图片",
        #                                                    "D:\\python\\RRJ\\pycharmproject\\Practice\\chep2\\Image",
        #                                                    "*.jpg;;*.png;;All Files(*)")

        imgNamepath, imgType = QFileDialog.getOpenFileName(self.centralwidget, "选择图片",
                                                           "D:\Softwares\Anaconda3\Project\pythonProject1\handwriting_detection\TestDigitImgs",
                                                           "*.jpg;;*.png;;All Files(*)")

        # 通过文件路径获取图片文件,并设置图片长宽为label控件的长、宽
        img = QtGui.QPixmap(imgNamepath).scaled(self.label_3.width(), self.label_3.height())
        # 在label控件上显示选择的图片
        self.label_3.setPixmap(img)
        # 显示所选图片的路径
        self.lineEdit_3.setText(imgNamepath)

        '''以下为改动细节'''

    # 保存图片到本地(第二种方式:首先提取相对应Qlabel中的图片,然后打开一个保存文件的弹出框,最后保存图片到选中的路径)
    def saveImage(self):
        # 提取Qlabel中的图片
        img = self.label_4.pixmap().toImage()
        fpath, ftype = QFileDialog.getSaveFileName(self.centralwidget, "保存图片", "d:\\", "*.jpg;;*.png;;All Files(*)")
        img.save(fpath)

    # '''以下是改动细节'''
    # def show(self):
    #     # img = cv2.imread('./TestDigitImgs/1600417425118.jpg', 0)
    #     # img = cv2.imread(imgNamePath, 0)
    #     img = cv2.imread(imgNamepath, 0)
    #     img = np.array(img).astype(np.float32)
    #     img = np.expand_dims(img, 0)
    #     img = np.expand_dims(img, 0)
    #     img = torch.from_numpy(img)
    #     img = img.to(device)
    #     output = net(Variable(img))
    #     prob = F.softmax(output, dim=1)
    #     prob = Variable(prob)
    #     prob = prob.cpu().numpy()
    #     print(prob)
    #     pred = np.argmax(prob)
    #     print(pred.item())
    #     return pred.item()
    # '''以上是改动细节'''

    # 生成对应预测的数字
    def startAction(self):
        # img = cv2.imread(imgNamepath)

        # path = "D:\\python\\RRJ\\pycharmProject2\\zhanCunDiZhi\\"
        # path = "D:\\Softwares\\Anaconda3\\Project\\pythonProject1\\handwriting_detection"
        # path = "D:\Softwares\Anaconda3\Project\pythonProject1\handwriting_detection\result_"
        # 因为不知道怎么将<class 'numpy.ndarray'>转换为<class 'PyQt5.QtGui.QPixmap'>类型,因此采用暂存再读出的方式
        # cv2.imwrite(path + 'ZC2.jpg', img)
        # pyqt5从路径读取图片
        # imgShow = QPixmap(path + 'ZC2.jpg')

        #设置 QLabel 的 setScaledContents 属性为 True,使得 QLabel 中的图片可以根据 QLabel 的大小进行缩放。
        # self.label_4.setScaledContents(True)

        #将 QPixmap 对象设置到 QLabel 中,使得素描图片可以在 QLabel 控件中显示出来。
        # self.label_4.setPixmap(imgShow)

        '''
        这里的show()相当于直接跳转到当前文件夹目录的handwriting_detection。
        至于为什么在这个区域疯狂打印,是因为我在debug这里的时候,在这个位置突然报错退出了,所以开始一个变量一个变量的打印
        '''
        device = torch.device('cpu')# 当时打印到6的时候突然出错了,不打印7,和handwriting_detection对比发现是没有这段代码

        net = torch.load("./Models/CNNNet.pth", map_location=torch.device('cpu'))
        img = cv2.imread(imgNamepath, 0)
        img = np.array(img).astype(np.float32)
        img = np.expand_dims(img, 0)
        img = torch.from_numpy(img)
        img = img.to(device)
        output = net(Variable(img))
        prob = F.softmax(output, dim=1)
        prob = Variable(prob)
        prob = prob.cpu().numpy()
        print(prob)
        pred = np.argmax(prob)
        print(pred.item())

        self.label_4.setText(str(pred.item()))

enterTest2(第二个界面的前端代码):

import test2
from PyQt5.QtWidgets import QApplication, QMainWindow


class SecondWindowActions(test2.Ui_MainWindow, QMainWindow):

    def __init__(self):
        super(test2.Ui_MainWindow, self).__init__()
        #调用 setupUi 方法来初始化和设置这个窗口类的用户界面。这里的 self 指的是主窗口类的实例
        self.setupUi(self)

参考链接:

【精选】PyTorch——手写数字识别_pytorch 手写数字_诺亚方包的博客-CSDN博客

完整的代码连接:

 llf000000/handwriting_detection_PyQt: handwriting_detection and PyQt (github.com)

PyQt是一种基于Python编程语言的开源图形用户界面框架,主要用于开发跨平台的GUI程序。手写体数字识别是一项常见的图像识别任务,其主要目标是根据输入的数字图像来判断其所代表的数字。KNN是一种常用的分类算法,其根据数据点之间的距离进行分类,可以用于实现手写体数字识别任务。 在PyQt中实现手写体数字识别KNN,需要先收集一组手写数字的图像数据,这些数据可采用MNIST数据集或者自己手动绘制。然后需要对这些数据进行特征提取,例如可以提取每个数字图像中的像素点灰度值作为特征。接着需要使用KNN算法来训练模型,并将其应用于新的数字图像。 在实现过程中,PyQt提供了许多方便的图形用户界面元素,例如标签、按钮、文本框等,可以用于实现交互式的数字识别界面。在界面设计中,需要将输入的数字图像进行预处理,并将其转换为特征向量输入到KNN算法当中。最后,应将KNN算法的输出结果返回到界面上并显示出来,供用户查看。 总之,PyQt手写体数字识别KNN是一项非常有意义的任务,可以促进图像识别技术的发展,并且提高人们的生活质量。由于开源性和跨平台优势,PyQt已经成为了一种热门的GUI框架,同时KNN算法也是一种简单有效的分类算法,这两者结合起来可以为图像识别任务提供一个高效的解决方案。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值