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)