opencv答题卡识别

opencv答题卡识别,第1张

opencv答题卡识别

基于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", "注册"))

项目下载地址:下载地址

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5658734.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-16
下一篇 2022-12-16

发表评论

登录后才能评论

评论列表(0条)

保存