基于opencv的答题卡识别,支持批量识别与注册登录功能。博客最后附有下载地址。
观看视频:
opencv答题卡识别
注册登录界面:
主界面:
答题卡图片:
识别结果:
代码部分:
主程序main.py
import sys, cv2 from PyQt5.QtGui import * from PyQt5.QtWidgets import * from PyQt5.QtCore import * from untitled import Ui_Dialog from untitled2 import Ui_Dialog2 from dududu import * from untitled3 import Ui_Dialog3 class Zhu_ce(QMainWindow,Ui_Dialog3): def __init__(self): super(Zhu_ce,self).__init__() self.setupUi(self) self.pushButton.clicked.connect(self.zhuc) def zhuc(self): self.zhanghao = self.lineEdit.text() self.mima = self.lineEdit_2.text() with open('zhang_hao.txt', 'a') as f: f.write(self.zhanghao + ' ' + self.mima + 'n') zhu_ce.close() import os class Dlu(QMainWindow,Ui_Dialog2): def __init__(self): super(Dlu,self).__init__() self.setupUi(self) self.setWindowTitle("基于opencv的答题卡识别系统") self.key=False self.pushButton.clicked.connect(self.ddlu) self.pushButton_2.clicked.connect(self.zhuce) self.setIcon() def setIcon(self): palette1 = QPalette() # palette1.setColor(self.backgroundRole(), QColor(192,253,123)) # 设置背景颜色 palette1.setBrush(self.backgroundRole(), QBrush(QPixmap('dl.png'))) # 设置背景图片 self.setPalette(palette1) def ddlu(self): self.zhanghao = self.lineEdit.text() self.mima = self.lineEdit_2.text() with open('zhang_hao.txt','r') as f: lines=f.readlines() for lin in lines: zhang=lin.split()[0] mima=lin.split()[1] if zhang==self.zhanghao and mima==self.mima: self.key=True if self.key==True: self.close() win.show() else: QMessageBox.information(self, 'What?', '密码或账号错误') def zhuce(self): zhu_ce.show() # zhu_ce.zhanghao = self.lineEdit.text() # zhu_ce.mima = self.lineEdit_2.text() # with open('zhang_hao.txt','a') as f: # f.write(self.zhanghao+' '+self.mima+'n') class My(QMainWindow,Ui_Dialog): def __init__(self): super(My,self).__init__() self.setupUi(self) self.pushButton.clicked.connect(self.pic) self.pushButton_2.clicked.connect(self.dis) self.pushButton_3.clicked.connect(self.end) self.pushButton_4.clicked.connect(self.piliang) self.setIcon() def setIcon(self): palette1 = QPalette() # palette1.setColor(self.backgroundRole(), QColor(192,253,123)) # 设置背景颜色 palette1.setBrush(self.backgroundRole(), QBrush(QPixmap('background.png'))) # 设置背景图片 self.setPalette(palette1) def pic(self): imgName, imgType = QFileDialog.getOpenFileName(self, "打开图片", "", " *.jpg;;*.png;;*.jpeg;;*.bmp;;All Files (*)") try: img = cv2.imread(imgName) self.img=img.copy() _,img=pic(img) img=self.change_pic(img) # warped_2 = maaain(img) img=self.cv_qt(img) self.label.setPixmap(QPixmap.fromImage(img)) except:pass def dis(self): img2,score,xue_hao=maaain(self.img) self.lineEdit_2.setText(xue_hao) self.lineEdit_3.setText(str(score)) img2=self.change_pic(img2) img2=self.cv_qt(img2) self.label.setPixmap(QPixmap.fromImage(img2)) def end(self): sys.exit(app.exec_()) def piliang(self): dir_path = QFileDialog.getExistingDirectory(self, "choose directory", r"C:/") #dir_path = unicode(dir_path.toUtf8(), 'utf-8', 'ignore') self.lu=dir_path.split('/')[-1] pic_names=os.listdir(dir_path) scoss=[] xue_haos=[] for name in pic_names: img=cv.imread(dir_path+'/'+name) img2, score, xue_hao = maaain(img) scoss.append(score) xue_haos.append(xue_hao) self.ccs(name=self.lu,haos=xue_haos,scores=scoss) QMessageBox.information(self, 'OK', '已经全部处理,保存在{}.csv文件中'.format(self.lu)) def ccs(self,name, haos, scores): workbook = xlwt.Workbook() # 新建一个工作簿 sheet = workbook.add_sheet(sheetname=name) # 在工作簿中新建一个表格 sheet.write(0, 0, '学号') sheet.write(0, 1, '成绩') for i,(h,s) in enumerate(zip(haos,scores)): sheet.write(i+1, 0, h) sheet.write(i+1, 1, str(s)) workbook.save('./{}.csv'.format(self.lu)) # 保存工作簿 print("xls格式表格写入数据成功!") def cv_qt(self, src): h, w, d = src.shape bytesperline = d * w # self.src=cv.cvtColor(self.src,cv.COLOR_BGR2RGB) qt_image = QImage(src.data, w, h, bytesperline, QImage.Format_RGB888).rgbSwapped() return qt_image def change_pic(self,src): h,w=src.shape[0],src.shape[1] da=max(h,w) rate=da/780 src=cv.resize(src,(int(w/rate),int(h/rate))) return src if __name__ == '__main__': app = QApplication(sys.argv) # 初始化GUI窗口 并传入摄像头句柄 zhu_ce = Zhu_ce() win = My() dlu=Dlu() dlu.show() sys.exit(app.exec_())
untitled.py代码
# -*- coding: utf-8 -*- # Form implementation generated from reading ui file 'untitled.ui' # # Created by: PyQt5 UI code generator 5.15.2 # # 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. from PyQt5 import QtCore, QtGui, QtWidgets class Ui_Dialog(object): def setupUi(self, Dialog): Dialog.setObjectName("Dialog") Dialog.resize(900, 898) self.label = QtWidgets.QLabel(Dialog) self.label.setGeometry(QtCore.QRect(90, 30, 651, 781)) self.label.setStyleSheet("") self.label.setText("") self.label.setObjectName("label") self.pushButton = QtWidgets.QPushButton(Dialog) self.pushButton.setGeometry(QtCore.QRect(50, 860, 75, 23)) self.pushButton.setObjectName("pushButton") self.pushButton_2 = QtWidgets.QPushButton(Dialog) self.pushButton_2.setGeometry(QtCore.QRect(140, 860, 75, 23)) self.pushButton_2.setObjectName("pushButton_2") self.pushButton_3 = QtWidgets.QPushButton(Dialog) self.pushButton_3.setGeometry(QtCore.QRect(410, 860, 75, 23)) self.pushButton_3.setObjectName("pushButton_3") self.label_3 = QtWidgets.QLabel(Dialog) self.label_3.setGeometry(QtCore.QRect(783, 401, 51, 31)) font = QtGui.QFont() font.setPointSize(15) self.label_3.setFont(font) self.label_3.setStyleSheet("color: rgb(255, 0, 0);") self.label_3.setObjectName("label_3") self.lineEdit_2 = QtWidgets.QLineEdit(Dialog) self.lineEdit_2.setGeometry(QtCore.QRect(770, 450, 113, 21)) self.lineEdit_2.setObjectName("lineEdit_2") self.label_4 = QtWidgets.QLabel(Dialog) self.label_4.setGeometry(QtCore.QRect(773, 521, 61, 41)) font = QtGui.QFont() font.setPointSize(15) self.label_4.setFont(font) self.label_4.setStyleSheet("color: rgb(255, 0, 0);") self.label_4.setObjectName("label_4") self.lineEdit_3 = QtWidgets.QLineEdit(Dialog) self.lineEdit_3.setGeometry(QtCore.QRect(770, 590, 113, 21)) self.lineEdit_3.setObjectName("lineEdit_3") self.pushButton_4 = QtWidgets.QPushButton(Dialog) self.pushButton_4.setGeometry(QtCore.QRect(270, 860, 75, 23)) self.pushButton_4.setObjectName("pushButton_4") self.retranslateUi(Dialog) QtCore.QmetaObject.connectSlotsByName(Dialog) def retranslateUi(self, Dialog): _translate = QtCore.QCoreApplication.translate Dialog.setWindowTitle(_translate("Dialog", "Dialog")) self.pushButton.setText(_translate("Dialog", "图片")) self.pushButton_2.setText(_translate("Dialog", "检测")) self.pushButton_3.setText(_translate("Dialog", "退出")) self.label_3.setText(_translate("Dialog", "学号:")) self.label_4.setText(_translate("Dialog", "分数:")) self.pushButton_4.setText(_translate("Dialog", "批量处理"))
dududu.py代码:
import cv2 as cv import numpy as np import xlwt from start import pic #from model import * with open('answer.txt') as f: answers=f.readlines() def kao_hao(warpe,xx,yy,yy2): global warped_2 nn=mmic(warpe) #cv.imshow('q12',nn) # kao_hao(warpe) cv.rectangle(warped_2, (xx, yy - 30), (xx + 207, yy2), (255, 0, 0), 2) shuz=[] for i in range(9): lk = [] lie_1=nn[yy:yy2,xx:xx+23] contours, hierarchy = cv.findContours(lie_1, cv.RETR_TREE, cv.CHAIN_APPROX_SIMPLE) for con in contours: x, y, w, h = cv.boundingRect(con) area = cv.contourArea(con) if area>30: lk.append(con) if len(lk)!=1: a1='N' cv.rectangle(warped_2, (xx,yy),(xx+22,yy2),(255,0,0),1) cv.putText(warped_2, a1, (xx,yy - 40), cv.FONT_HERSHEY_SIMPLEX, 0.75, (255, 0, 0), 2) shuz.append(a1) else: x, y, w, h = cv.boundingRect(lk[0]) if 229-6150,0,255).astype('uint8') #开运算 kernel = np.ones((3,3),np.uint8) nn = cv.erode(thred,kernel,iterations = 1) nn = cv.dilate(nn,kernel,iterations = 1) return nn def discern(warpe,xx,yy,yy2): global warped_2 nn=mmic(warpe) # kao_hao(warpe) shuz=[] for i in range(5): lk = [] lie_1=nn[yy:yy2,xx:xx+22] contours, hierarchy = cv.findContours(lie_1, cv.RETR_TREE, cv.CHAIN_APPROX_SIMPLE) for con in contours: x, y, w, h = cv.boundingRect(con) area = cv.contourArea(con) if area>50: lk.append(con) if len(lk)!=1: a1='N' cv.rectangle(warped_2, (xx,yy),(xx+22,yy2),(255,0,0),1) cv.putText(warped_2, str(a1), (xx,yy - 5), cv.FONT_HERSHEY_SIMPLEX, 0.75, (255, 0, 0), 2) shuz.append(a1) else: x, y, w, h = cv.boundingRect(lk[0]) if y+h/2>=0 and y+h/2<13: a1='A' cv.rectangle(warped_2, (xx, yy), (xx + 22, yy2), (255, 0, 0), 1) cv.putText(warped_2, a1, (xx,yy - 5), cv.FONT_HERSHEY_SIMPLEX, 0.75, (255, 0, 0), 2) shuz.append(a1) elif y+h/2>=13 and y+h/2<26: a1='B' cv.rectangle(warped_2, (xx, yy), (xx + 22, yy2), (255, 0, 0), 1) cv.putText(warped_2, a1, (xx,yy - 5), cv.FONT_HERSHEY_SIMPLEX, 0.75, (255, 0, 0), 2) shuz.append(a1) elif y+h/2>=26 and y+h/2<39: a1='C' cv.rectangle(warped_2, (xx, yy), (xx + 22, yy2), (255, 0, 0), 1) cv.putText(warped_2, a1, (xx,yy - 5), cv.FONT_HERSHEY_SIMPLEX, 0.75, (255, 0, 0), 2) shuz.append(a1) elif y+h/2>=39 and y+h/2<52: a1='D' cv.rectangle(warped_2, (xx, yy), (xx + 22, yy2), (255, 0, 0), 1) cv.putText(warped_2, a1, (xx,yy - 5), cv.FONT_HERSHEY_SIMPLEX, 0.75, (255, 0, 0), 2) shuz.append(a1) xx += 22 return shuz def ccs(name,hao,score): workbook = xlwt.Workbook() # 新建一个工作簿 sheet = workbook.add_sheet(sheetname=name) # 在工作簿中新建一个表格 sheet.write(0,0,'学号') sheet.write(0, 1, '成绩') sheet.write(1, 0, ''.join(hao)) sheet.write(1, 1, str(score)) # # for i,j in enumerate(jieguo): # sheet.write(i+1, 1, j) # 像表格中写入数据(对应的行和列) workbook.save('./score.csv') # 保存工作簿 print("xls格式表格写入数据成功!") def change_pic(src,guiyihu=True): src = cv.threshold(src, 200, 255, cv.THRESH_BINARY_INV)[1] h,w,d=src.shape[0],src.shape[1],src.shape[2] da=max(h,w) if da>60: rate=da/60 else: rate=da/60 src=cv.resize(src,(int(w/rate),int(h/rate))) h2, w2, d2 = src.shape[0], src.shape[1], src.shape[2] top=int((60-h2)/2) bot=60-h2-top left=int((60-w2)/2) right=60-left-w2 ro = cv.copyMakeBorder(src, top, bot, left, right, cv.BORDER_CONSTANT, value=0) ro=cv.cvtColor(ro,cv.COLOR_BGR2GRAY) ro=cv.threshold(ro,0,255,cv.THRESH_BINARY)[1] #print(ro) # print(ro.shape) kernel = np.ones((3, 3), np.uint8) ro = cv.erode(ro, kernel, iterations=1) ro = cv.erode(ro, kernel, iterations=1) ro = cv.erode(ro, kernel, iterations=1) cv.imshow('a221', ro) ro=np.reshape(ro,(60,60,1)) if guiyihu: ro=(ro/255).astype('float32') return ro # def xing_ming(src): # gray=cv.cvtColor(src,cv.COLOR_BGR2GRAY) # thred=np.where(gray>200,0,255).astype('uint8') # kernel = np.ones((3, 3), np.uint8) # nn = cv.dilate(thred, kernel, iterations=1) # nn = cv.dilate(nn, kernel, iterations=1) # contours, hierarchy = cv.findContours(nn, cv.RETR_TREE, cv.CHAIN_APPROX_SIMPLE) # contours_2=[] # contours_3=[] # x_idx=[] # for con in contours: # x, y, w, h = cv.boundingRect(con) # area = cv.contourArea(con) # if area>50: # x_idx.append(x) # contours_2.append(con) # x_idx=np.array(x_idx) # idx=np.argsort(x_idx) # for aw in idx: # contours_3.append(contours_2[aw]) # name='' # for ccn in contours_3: # x, y, w, h = cv.boundingRect(ccn) # pic1=src[y:y+h,x:x+w] # pic1=change_pic(pic1) # pic1=np.reshape(pic1,(1,60,60,1)) # pre=model.predict(pic1)[0] # idx=np.argmax(pre) # name=liness[idx] # name=name+name # return name def maaain(img): global warped_2 warped,_=pic(img) warped_2=warped.copy() jie_guo=[] shuz1_5=discern(warped,157,400,452) jie_guo.extend(shuz1_5) shuz6_10=discern(warped,293,400,453) jie_guo.extend(shuz6_10) shuz11_15=discern(warped,430,400,452) jie_guo.extend(shuz11_15) shuz16_20=discern(warped,564,400,452) jie_guo.extend(shuz16_20) shuz21_25=discern(warped,159,483,536) jie_guo.extend(shuz21_25) shuz26_30=discern(warped,294,483,536) jie_guo.extend(shuz26_30) shuz31_35=discern(warped,428,483,536) jie_guo.extend(shuz31_35) shuz36_40=discern(warped,564,483,536) jie_guo.extend(shuz36_40) shuz41_45=discern(warped,159,566,617) jie_guo.extend(shuz41_45) shuz46_50=discern(warped,294,566,617) jie_guo.extend(shuz46_50) shuz51_55=discern(warped,429,566,617) jie_guo.extend(shuz51_55) shuz56_60=discern(warped,565,566,617) jie_guo.extend(shuz56_60) shuz61_65=discern(warped,159,647,700) jie_guo.extend(shuz61_65) shuz66_70=discern(warped,295,647,700) jie_guo.extend(shuz66_70) shuz71_75=discern(warped,430,647,700) jie_guo.extend(shuz71_75) shuz76_80=discern(warped,565,647,700) jie_guo.extend(shuz76_80) shuz81_85=discern(warped,159,730,782) jie_guo.extend(shuz81_85) shuz86_90=discern(warped,296,730,782) jie_guo.extend(shuz86_90) shuz91_95=discern(warped,432,730,782) jie_guo.extend(shuz91_95) shuz96_100=discern(warped,566,730,782) jie_guo.extend(shuz96_100) shuz101_105=discern(warped,159,813,865) jie_guo.extend(shuz101_105) shuz106_110=discern(warped,296,813,865) jie_guo.extend(shuz106_110) shuz111_115=discern(warped,432,813,865) jie_guo.extend(shuz111_115) shuz116_120=discern(warped,566,813,865) jie_guo.extend(shuz116_120) shuz121_125=discern(warped,159,896,948) jie_guo.extend(shuz121_125) shuz126_130=discern(warped,296,896,948) jie_guo.extend(shuz126_130) shuz131_135=discern(warped,432,896,948) jie_guo.extend(shuz131_135) shuz136_140=discern(warped,566,896,948) jie_guo.extend(shuz136_140) cv.rectangle(warped_2,(240,152),(411,183),(255,0,0),1) # gray=cv.cvtColor() # cv.imshow('a45',xming) # cv.waitKey(0) #考号 hao=kao_hao(warped,471,225,358) score=0 for ans,outcom in zip(answers,jie_guo): #print(ans.strip(),outcom.strip()) if ans.strip()==outcom.strip(): score+=1 cv.putText(warped_2,'SCORE: '+str(score),(75,66),cv.FONT_HERSHEY_SIMPLEX, 2, (0, 0, 255), 2) ccs(name='aq',hao=hao,score=score) xue_hao=''.join(hao) return warped_2,score,xue_hao if __name__=='__main__': img = cv.imread('picture/4.jpg') warped_2=maaain(img) cv.imshow('a1142',warped_2) cv.waitKey(0) cv.destroyWindow()
untitled3.py代码:
# -*- coding: utf-8 -*- # Form implementation generated from reading ui file 'untitled3.ui' # # Created by: PyQt5 UI code generator 5.15.2 # # 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. from PyQt5 import QtCore, QtGui, QtWidgets class Ui_Dialog3(object): def setupUi(self, Dialog): Dialog.setObjectName("Dialog") Dialog.resize(330, 277) self.label = QtWidgets.QLabel(Dialog) self.label.setGeometry(QtCore.QRect(80, 100, 61, 21)) self.label.setObjectName("label") self.label_2 = QtWidgets.QLabel(Dialog) self.label_2.setGeometry(QtCore.QRect(80, 150, 71, 21)) self.label_2.setObjectName("label_2") self.lineEdit = QtWidgets.QLineEdit(Dialog) self.lineEdit.setGeometry(QtCore.QRect(150, 100, 113, 20)) self.lineEdit.setObjectName("lineEdit") self.lineEdit_2 = QtWidgets.QLineEdit(Dialog) self.lineEdit_2.setGeometry(QtCore.QRect(150, 150, 113, 20)) self.lineEdit_2.setObjectName("lineEdit_2") self.pushButton = QtWidgets.QPushButton(Dialog) self.pushButton.setGeometry(QtCore.QRect(130, 210, 75, 23)) self.pushButton.setObjectName("pushButton") self.retranslateUi(Dialog) QtCore.QmetaObject.connectSlotsByName(Dialog) def retranslateUi(self, Dialog): _translate = QtCore.QCoreApplication.translate Dialog.setWindowTitle(_translate("Dialog", "Dialog")) self.label.setText(_translate("Dialog", "输入账号:")) self.label_2.setText(_translate("Dialog", "输入密码:")) self.pushButton.setText(_translate("Dialog", "注册"))
项目下载地址:下载地址
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)