Python+Opencv实现摄像头答题卡识别

本文是一位高中物理教师通过学习Python、PyQT5和OpenCV,结合高拍仪,开发出一款能自动识别答题卡选择题的系统。系统能识别姓名、考号、选择题答案,计算得分,并生成柱状图。识别过程包括图像预处理、四角变换、分割和涂卡面积占比计算。此外,文章还介绍了答案处理和程序打包的过程。
摘要由CSDN通过智能技术生成

原文:Python+Opencv实现摄像头答题卡识别 - 狼行三人组-1 - 博客园
前言:大家好,我是一名高中物理教师,比较喜欢学习编程,由于平时批改作业比较忙,所以突然冒出个想法,做个摄像头答题卡识别就会减轻我平时批改作业的很多负担,特别是选择题,重复性的劳动,意义不大,如果用机器代替工作那该多好呀,网上一搜,有很多教程,但是都不太满意,所以我趁着躲避新冠在家隔离的这段时间,边学边做,终于做成了,还没开学,等开学了就去试试,通过博客园,把我的心得分享给大家!

首先,我学习了三本书,python3.7  Pyqt5  opencv ,对我的帮助很大,感谢这几本书的作者。

第二,软件环境: anaconda(python3.7)+pycharm +pqty5 + opencv4.2.0+Excel2016 + 一堆库

第三,硬件环境: 高拍仪(1000W像素,分辨率1920*1080)

第四,实现的功能:   ①识别选择题

          ②识别名字(用汉字区位码)

          ③识别考号

          ④计算得分

          ⑤统计全班的每题得分率

          ⑥选择题柱状图

第五,答题卡设置要求:横平竖直,格子的宽高相同(我设置的是64行,23列),便于分割!

第六,识别部分:① 打开摄像头,捕获一帧。

        ② 对图像四角变换

        ④ 把图像分割,计算每个格子中涂卡面积占比

        ⑤ 输出选项到列表

具体代码:        

#① 打开摄像头,捕获一帧。这里用了定时器,否则会卡
self.timer = QTimer()  # 初始化定时器
self.timer.timeout.connect(self.time)#定时器信号
self.cap = cv2.VideoCapture(0) #打开视频
self.cap.set(cv2.CAP_PROP_FRAME_WIDTH, 1366)#图像宽
self.cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 768) #图像高
self.timer.start(1)
self.ret,self.frame = self.cap.read() #读取内存中的帧
# ②对图像四角变换
        if (self.cap.isOpened()):
            M = cv2.getRotationMatrix2D((self.frame.shape[1] / 2, self.frame.shape[0] / 2), -90, 0.8)  # 获得旋转矩阵
            self.frame = cv2.warpAffine(self.frame, M, (self.frame.shape[1], self.frame.shape[0]))  # 旋转90度
            gray = cv2.cvtColor(self.frame, cv2.COLOR_BGR2GRAY)  # 转换为灰度图像
            blurred = cv2.GaussianBlur(gray, (3, 3), 0)  # 高斯滤波1
            edged = cv2.Canny(blurred, 10, 100)  # 边缘检测
            #cv2.imshow('edged', edged)
            cnts = cv2.findContours(edged, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)  # 查找轮廓
            cnts = cnts[1] if imutils.is_cv2() else cnts[0]  # # 用以区分OpenCV2.4和OpenCV3
            docCnt = None
            if len(cnts) > 0:  # 确保至少有一个轮廓被找到
                cnts = sorted(cnts, key=cv2.contourArea, reverse=True)  # 将轮廓按大小降序排序
                for c in cnts:  # 对排序后的轮廓循环处理
                    peri = cv2.arcLength(c, True)  # 周长# 获取近似的轮廓
                    approx = cv2.approxPolyDP(c, 0.02 * peri, True)  # 如果近似轮廓有四个顶点,那么就认为找到了答题卡
                    if len(approx) == 4:
                        docCnt = approx
                        break
            self.framexianshi = self.frame.copy()  # 复制原图
            self.paper = four_point_transform(self.frame, docCnt.reshape(4, 2))  # 对原始图像进行四点透视变换
            self.framexianshi = cv2.drawContours(self.framexianshi, cnts, 0, (0, 255, 0), 2)  #画绿边轮廓

#③ 形态学变换(灰度 反向二值化 开运算 膨胀) 
paper = cv2.resize(self.paper, (1196, 1946))  # 重新缩放指定尺寸统一尺寸 便于分割
            #cv2.imshow('suofanghou', paper)
            hanggao = paper.shape[0]
            hanggao_1 = hanggao // 64
            liekuan = paper.shape[1]
            liekuan_1 = liekuan // 23
            huidu = cv2.cvtColor(paper, cv2.COLOR_BGR2GRAY)  # 灰度图
            t, erzhihua = cv2.threshold(huidu, 95, 255, cv2.THRESH_BINARY_INV)  # 反向二值化
            # cv2.imshow('erzhihua', erzhihua)
            k = np.ones((8, 8), np.uint8)  # 开运算
            kaiyunsuan = cv2.morphologyEx(erzhihua, cv2.MORPH_OPEN, k)  # 开运算
            # cv2.imshow('kaiyunsuan', kaiyunsuan)
            peng = np.ones((3, 3), np.uint8)
            kaiyunsuan = cv2.dilate(kaiyunsuan, peng)  # 膨胀

#分割后的图像
            for heng in range(0, hanggao + hanggao_1, hanggao_1):  # 显示分割的横线竖线
                paper = cv2.line(paper, (0, heng), (liekuan, heng), (0, 0, 255), 1)  # 显示分割的横线竖线
            for j in range(0, liekuan, liekuan_1):  # 显示分割的横线竖线
                paper = cv2.line(paper, (j, 0), (j, liekuan), (0, 0, 255), 1)  # 显示分割的横线竖线
                cv2.imshow('paperbianxian1', paper)

 
# ④ 涂卡面积的占比 这里应该有更好的办法,我只用了这个办法来识别,把感兴趣区域截取更小一些或许更好,这样也完全够了!姓名与考号与此法类似我就不再重复了!
# 插入列表时候多选我使用了字典处理的

            for ii in range(0, 5):  # 识别1-5 的选择题
                for jj in range(17, 21):
                    lie = ii * liekuan_1
                    hang = jj * hanggao_1
                    baisemianji = cv2.countNonZero(kaiyunsuan[hang: hang + hanggao_1, lie: lie + liekuan_1])  # 涂卡的面积
                    quanbumianji = hanggao_1 * liekuan_1  # 全部的面积
                    ratio = baisemianji * 100 / quanbumianji  # 涂卡比率; 比例;
                    # print(ratio)
                    if (ratio > self.mianjibaifenbi):
                        if jj == 17:
                            # print(f'第 {ii+1} 题选:A ')
                            self.charuxuan[ii + 1].append('A')
                        elif jj == 18:
                            self.charuxuan[ii + 1].append('B')
                        elif jj == 19:
                            self.charuxuan[ii + 1].append('C')
                        elif jj == 20:
                            self.charuxuan[ii + 1].append('D')
                self.gengxinruxuan[ii + 1].append(''.join(self.charuxuan[ii + 1]))

            for ii in range(6, 11):  # 识别6-10 的选择题
                for jj in range(17, 21):
                    lie = ii * liekuan_1
                    hang = jj * hanggao_1
                    baisemianji = cv2.countNonZero(kaiyunsuan[hang: hang + hanggao_1, lie: lie + liekuan_1])
                    quanbumianji = kaiyunsuan[hanggao_1: hanggao_1 + hanggao_1, liekuan_1: liekuan_1 + liekuan_1].shape[0] * \
                                   erzhihua[hang: hang + hanggao_1, lie: lie + liekuan_1].shape[1]
                    ratio = baisemianji * 100 / quanbumianji  # 比率; 比例;
                    if (ratio > self.mianjibaifenbi):
                        if jj == 17:
                            self.charuxuan[ii].append('A')
                        elif jj == 18:
                            self.charuxuan[ii].append('B')
                        elif jj == 19:
                            self.charuxuan[ii].append('C')
                        elif jj == 20:
                            self.charuxuan[ii].append('D')
                self.gengxinruxuan[ii].append(''.join(self.charuxuan[ii]))

            for ii in range(12, 17):  # 识别11-15 的选择题
                for jj in range(17, 21):
                    lie = ii * liekuan_1
                    hang = jj * hanggao_1
                    baisemianji = cv2.countNonZero(kaiyunsuan[hang: hang + hanggao_1, lie: lie + liekuan_1])
                    quanbumianji = kaiyunsuan[hanggao_1: hanggao_1 + hanggao_1, liekuan_1: liekuan_1 + liekuan_1].shape[0] * \
                                   erzhihua[hang: hang + hanggao_1, lie: lie + liekuan_1].shape[1]
                    ratio = baisemianji * 100 / quanbumianji  # 比率; 比例;
                    # print(ratio)
                    if (ratio > self.mianjibaifenbi):
                        if jj == 17:
                            self.charuxuan[ii - 1].append('A')
                        elif jj == 18:
                            self.charuxuan[ii - 1].append('B')
                        elif jj == 19:
                            self.charuxuan[ii - 1].append('C')
                        elif jj == 20:
                            self.charuxuan[ii - 1].append('D')
                self.gengxinruxuan[ii - 1].append(''.join(self.charuxuan[ii - 1]))

            for ii in range(18, 23):  # 识别16-20 的选择题
                for jj in range(17, 21):
                    lie = ii * liekuan_1
                    hang = jj * hanggao_1
                    baisemianji = cv2.countNonZero(kaiyunsuan[hang: hang + hanggao_1, lie: lie + liekuan_1])
                    quanbumianji = kaiyunsuan[hanggao_1: hanggao_1 + hanggao_1, liekuan_1: liekuan_1 + liekuan_1].shape[0] * \
                                   erzhihua[hang: hang + hanggao_1, lie: lie + liekuan_1].shape[1]
                    ratio = baisemianji * 100 / quanbumianji  # 比率; 比例;
                    if (ratio > self.mianjibaifenbi):
                        if jj == 17:
                            self.charuxuan[ii - 2].append('A')
                        elif jj == 18:
                            self.charuxuan[ii - 2].append('B')
                        elif jj == 19:
                            self.charuxuan[ii - 2].append('C')
                        elif jj == 20:
                            self.charuxuan[ii - 2].append('D')
                self.gengxinruxuan[ii - 2].append(''.join(self.charuxuan[ii - 2]))
            self.xuan = list(self.gengxinruxuan.values())  # 字典变成二维列表
            self.xuan = list(chain.from_iterable(self.xuan))  # 二维列表变成一维
            print(self.xuan)
            self.tishu = int(self.lineEdit_tishu.text())
            self.xuan = self.xuan[: self.tishu]  # 切片除题目数量
            self.xuan[self.tishu:] = '                    '
            self.xuan = self.xuan[0:20]

第七,答案处理:① 把答案输出到列表1

        ② 把学生选项输出到列表2

        ③ 对比两个列表的元素 判断正误

#① 判断正确与否是请教QQ群里面的大神,我觉得每次请教可以用红包的方式来请教,虽然都差钱,但是每次你花10元-20元的红包来请教,一来你耽误了别人的宝贵时间,二来别人看你的问题给你解答要动脑筋的,我觉得付费是理所当然的
            for i in range(len(self.answer)):
                dd = set(self.answer[i].upper())
                xx = set(self.xuan[i].upper())
                if xx == dd and self.answer[i] != '':
                    self.right = self.right + 1
                    if i == 0:
                        self.lineEdit_001.setStyleSheet("color:rgb(0, 170, 0)")
                        self.label_001.setText('第1题√ ')
                        self.label_001.setStyleSheet("color: rgb(0, 170, 0)")
                    elif i == 1:
                        self.lineEdit_002.setStyleSheet("color:rgb(0, 170, 0)")
                        self.label_002.setText('第2题√ ')
                        self.label_002.setStyleSheet("color:rgb(0, 170, 0)")
                    elif i == 2:
                        self.lineEdit_003.setStyleSheet("color:rgb(0, 170, 0)")
                        self.label_003.setText('第3题√ ')
                        self.label_003.setStyleSheet("color:rgb(0, 170, 0)")
                    elif i == 3:
                        self.lineEdit_004.setStyleSheet("color:rgb(0, 170, 0)")
                        self.label_004.setText('第4题√ ')
                        self.label_004.setStyleSheet("color:rgb(0, 170, 0)")
                    elif i == 4:
                        self.lineEdit_005.setStyleSheet("color:rgb(0, 170, 0)")
                        self.label_005.setText('第5题√ ')
                        self.label_005.setStyleSheet("color:rgb(0, 170, 0)")
                    elif i == 5:
                        self.lineEdit_006.setStyleSheet("color:rgb(0, 170, 0)")
                        self.label_006.setText('第6题√ ')
                        self.label_006.setStyleSheet("color:rgb(0, 170, 0)")
                    elif i == 6:
                        self.lineEdit_007.setStyleSheet("color:rgb(0, 170, 0)")
                        self.label_007.setText('第7题√ ')
                        self.label_007.setStyleSheet("color:rgb(0, 170, 0)")
                    elif i == 7:
                        self.lineEdit_008.setStyleSheet("color:rgb(0, 170, 0)")
                        self.label_008.setText('第8题√ ')
                        self.label_008.setStyleSheet("color:rgb(0, 170, 0)")
                    elif i == 8:
                        self.lineEdit_009.setStyleSheet("color:rgb(0, 170, 0)")
                        self.label_009.setText('第9题√ ')
                        self.label_009.setStyleSheet("color:rgb(0, 170, 0)")
                    elif i == 9:
                        self.lineEdit_010.setStyleSheet("color:rgb(0, 170, 0)")
                        self.label_010.setText('10题√ ')
                        self.label_010.setStyleSheet("color:rgb(0, 170, 0)")
                    elif i == 10:
                        self.lineEdit_011.setStyleSheet("color:rgb(0, 170, 0)")
                        self.label_011.setText('11题√ ')
                        self.label_011.setStyleSheet("color:rgb(0, 170, 0)")
                    elif i == 11:
                        self.lineEdit_012.setStyleSheet("color:rgb(0, 170, 0)")
                        self.label_012.setText('12题√ ')
                        self.label_012.setStyleSheet("color:rgb(0, 170, 0)")
                    elif i == 12:
                        self.lineEdit_013.setStyleSheet("color:rgb(0, 170, 0)")
                        self.label_013.setText('13题√ ')
                        self.label_013.setStyleSheet("color:rgb(0, 170, 0)")
                    elif i == 13:
                        self.lineEdit_014.setStyleSheet("color:rgb(0, 170, 0)")
                        self.label_014.setText('14题√ ')
                        self.label_014.setStyleSheet("color:rgb(0, 170, 0)")
                    elif i == 14:
                        self.lineEdit_015.setStyleSheet("color:rgb(0, 170, 0)")
                        self.label_015.setText('15题√ ')
                        self.label_015.setStyleSheet("color:rgb(0, 170, 0)")
                    elif i == 15:
                        self.lineEdit_016.setStyleSheet("color:rgb(0, 170, 0)")
                        self.label_016.setText('16题√ ')
                        self.label_016.setStyleSheet("color:rgb(0, 170, 0)")
                    elif i == 16:
                        self.lineEdit_017.setStyleSheet("color:rgb(0, 170, 0)")
                        self.label_017.setText('17题√ ')
                        self.label_017.setStyleSheet("color:rgb(0, 170, 0)")
                    elif i == 17:
                        self.lineEdit_018.setStyleSheet("color:rgb(0, 170, 0)")
                        self.label_018.setText('18题√ ')
                        self.label_018.setStyleSheet("color:rgb(0, 170, 0)")
                    elif i == 18:
                        self.lineEdit_019.setStyleSheet("color:rgb(0, 170, 0)")
                        self.label_019.setText('19题√ ')
                        self.label_019.setStyleSheet("color:rgb(0, 170, 0)")
                    elif i == 19:
                        self.lineEdit_020.setStyleSheet("color:rgb(0, 170, 0)")
                        self.label_020.setText('20题√ ')
                        self.label_020.setStyleSheet("color:rgb(0, 170, 0)")

                elif (xx.issubset(dd) == True) and (dd.difference(xx) != set()) and (self.answer[i] != '') and (self.xuan[i] != ''):
                    self.bandu = self.bandu + 1
                    if i == 0:
                        self.lineEdit_001.setStyleSheet("color:rgb(255, 0, 255)")
                        self.label_001.setText('第1题乄 ')
                        self.label_001.setStyleSheet("color: rgb(255, 0, 255)")
                    elif i == 1:
                        self.lineEdit_002.setStyleSheet("color:rgb(255, 0, 255)")
                        self.label_002.setText('第2题乄 ')
                        self.label_002.setStyleSheet("color:rgb(255, 0, 255)")
                    elif i == 2:
                        self.lineEdit_003.setStyleSheet("color:rgb(255, 0, 255)")
                        self.label_003.setText('第3题乄 ')
                        self.label_003.setStyleSheet("color:rgb(255, 0, 255)")
                    elif i == 3:
                        self.lineEdit_004.setStyleSheet("color:rgb(255, 0, 255)")
                        self.label_004.setText('第4题乄 ')
                        self.label_004.setStyleSheet("color:rgb(255, 0, 255)")
                    elif i == 4:
                        self.lineEdit_005.setStyleSheet("color:rgb(255, 0, 255)")
                        self.label_005.setText('第5题乄 ')
                        self.label_005.setStyleSheet("color:rgb(255, 0, 255)")
                    elif i == 5:
                        self.lineEdit_006.setStyleSheet("color:rgb(255, 0, 255)")
                        self.label_006.setText('第6题乄 ')
                        self.label_006.setStyleSheet("color:rgb(255, 0, 255)")
                    elif i == 6:
                        self.lineEdit_007.setStyleSheet("color:rgb(255, 0, 255)")
                        self.label_007.setText('第7题乄 ')
                        self.label_007.setStyleSheet("color:rgb(255, 0, 255)")
                    elif i == 7:
                        self.lineEdit_008.setStyleSheet("color:rgb(255, 0, 255)")
                        self.label_008.setText('第8题乄 ')
                        self.label_008.setStyleSheet("color:rgb(255, 0, 255)")
                    elif i == 8:
                        self.lineEdit_009.setStyleSheet("color:rgb(255, 0, 255)")
                        self.label_009.setText('第9题乄 ')
                        self.label_009.setStyleSheet("color:rgb(255, 0, 255)")
                    elif i == 9:
                        self.lineEdit_010.setStyleSheet("color:rgb(255, 0, 255)")
                        self.label_010.setText('10题乄 ')
                        self.label_010.setStyleSheet("color:rgb(255, 0, 255)")
                    elif i == 10:
                        self.lineEdit_011.setStyleSheet("color:rgb(255, 0, 255)")
                        self.label_011.setText('11题乄 ')
                        self.label_011.setStyleSheet("color:rgb(255, 0, 255)")
                    elif i == 11:
                        self.lineEdit_012.setStyleSheet("color:rgb(255, 0, 255)")
                        self.label_012.setText('12题乄 ')
                        self.label_012.setStyleSheet("color:rgb(255, 0, 255)")
                    elif i == 12:
                        self.lineEdit_013.setStyleSheet("color:rgb(255, 0, 255)")
                        self.label_013.setText('13题乄 ')
                        self.label_013.setStyleSheet("color:rgb(255, 0, 255)")
                    elif i == 13:
                        self.lineEdit_014.setStyleSheet("color:rgb(255, 0, 255)")
                        self.label_014.setText('14题乄 ')
                        self.label_014.setStyleSheet("color:rgb(255, 0, 255)")
                    elif i == 14:
                        self.lineEdit_015.setStyleSheet("color:rgb(255, 0, 255)")
                        self.label_015.setText('15题乄 ')
                        self.label_015.setStyleSheet("color:rgb(255, 0, 255)")
                    elif i == 15:
                        self.lineEdit_016.setStyleSheet("color:rgb(255, 0, 255)")
                        self.label_016.setText('16题乄 ')
                        self.label_016.setStyleSheet("color:rgb(255, 0, 255)")
                    elif i == 16:
                        self.lineEdit_017.setStyleSheet("color:rgb(255, 0, 255)")
                        self.label_017.setText('17题乄 ')
                        self.label_017.setStyleSheet("color:rgb(255, 0, 255)")
                    elif i == 17:
                        self.lineEdit_018.setStyleSheet("color:rgb(255, 0, 255)")
                        self.label_018.setText('18题乄 ')
                        self.label_018.setStyleSheet("color:rgb(255, 0, 255)")
                    elif i == 18:
                        self.lineEdit_019.setStyleSheet("color:rgb(255, 0, 255)")
                        self.label_019.setText('19题乄 ')
                        self.label_019.setStyleSheet("color:rgb(255, 0, 255)")
                    elif i == 19:
                        self.lineEdit_020.setStyleSheet("color:rgb(255, 0, 255)")
                        self.label_020.setText('20题乄 ')
                        self.label_020.setStyleSheet("color:rgb(255, 0, 255)")

                elif self.answer[i] != '' :
                    self.wrong = self.wrong + 1
                    if i == 0:
                        self.lineEdit_001.setStyleSheet("color:rgb(255, 0, 0)")
                        self.label_001.setText('第1题× ')
                        self.label_001.setStyleSheet("color: rgb(255, 0, 0)")
                    elif i == 1:
                        self.lineEdit_002.setStyleSheet("color:rgb(255, 0, 0)")
                        self.label_002.setText('第2题× ')
                        self.label_002.setStyleSheet("color:rgb(255, 0, 0)")
                    elif i == 2:
                        self.lineEdit_003.setStyleSheet("color:rgb(255, 0, 0)")
                        self.label_003.setText('第3题× ')
                        self.label_003.setStyleSheet("color:rgb(255, 0, 0)")
                    elif i == 3:
                        self.lineEdit_004.setStyleSheet("color:rgb(255, 0, 0)")
                        self.label_004.setText('第4题× ')
                        self.label_004.setStyleSheet("color:rgb(255, 0, 0)")
                    elif i == 4:
                        self.lineEdit_005.setStyleSheet("color:rgb(255, 0, 0)")
                        self.label_005.setText('第5题× ')
                        self.label_005.setStyleSheet("color:rgb(255, 0, 0)")
                    elif i == 5:
                        self.lineEdit_006.setStyleSheet("color:rgb(255, 0, 0)")
                        self.label_006.setText('第6题× ')
                        self.label_006.setStyleSheet("color:rgb(255, 0, 0)")
                    elif i == 6:
                        self.lineEdit_007.setStyleSheet("color:rgb(255, 0, 0)")
                        self.label_007.setText('第7题× ')
                        self.label_007.setStyleSheet("color:rgb(255, 0, 0)")
                    elif i == 7:
                        self.lineEdit_008.setStyleSheet("color:rgb(255, 0, 0)")
                        self.label_008.setText('第8题× ')
                        self.label_008.setStyleSheet("color:rgb(255, 0, 0)")
                    elif i == 8:
                        self.lineEdit_009.setStyleSheet("color:rgb(255, 0, 0)")
                        self.label_009.setText('第9题× ')
                        self.label_009.setStyleSheet("color:rgb(255, 0, 0)")
                    elif i == 9:
                        self.lineEdit_010.setStyleSheet("color:rgb(255, 0, 0)")
                        self.label_010.setText('10题× ')
                        self.label_010.setStyleSheet("color:rgb(255, 0, 0)")
                    elif i == 10:
                        self.lineEdit_011.setStyleSheet("color:rgb(255, 0, 0)")
                        self.label_011.setText('11题× ')
                        self.label_011.setStyleSheet("color:rgb(255, 0, 0)")
                    elif i == 11:
                        self.lineEdit_012.setStyleSheet("color:rgb(255, 0, 0)")
                        self.label_012.setText('12题× ')
                        self.label_012.setStyleSheet("color:rgb(255, 0, 0)")
                    elif i == 12:
                        self.lineEdit_013.setStyleSheet("color:rgb(255, 0, 0)")
                        self.label_013.setText('13题× ')
                        self.label_013.setStyleSheet("color:rgb(255, 0, 0)")
                    elif i == 13:
                        self.lineEdit_014.setStyleSheet("color:rgb(255, 0, 0)")
                        self.label_014.setText('14题× ')
                        self.label_014.setStyleSheet("color:rgb(255, 0, 0)")
                    elif i == 14:
                        self.lineEdit_015.setStyleSheet("color:rgb(255, 0, 0)")
                        self.label_015.setText('15题× ')
                        self.label_015.setStyleSheet("color:rgb(255, 0, 0)")
                    elif i == 15:
                        self.lineEdit_016.setStyleSheet("color:rgb(255, 0, 0)")
                        self.label_016.setText('16题× ')
                        self.label_016.setStyleSheet("color:rgb(255, 0, 0)")
                    elif i == 16:
                        self.lineEdit_017.setStyleSheet("color:rgb(255, 0, 0)")
                        self.label_017.setText('17题× ')
                        self.label_017.setStyleSheet("color:rgb(255, 0, 0)")
                    elif i == 17:
                        self.lineEdit_018.setStyleSheet("color:rgb(255, 0, 0)")
                        self.label_018.setText('18题× ')
                        self.label_018.setStyleSheet("color:rgb(255, 0, 0)")
                    elif i == 18:
                        self.lineEdit_019.setStyleSheet("color:rgb(255, 0, 0)")
                        self.label_019.setText('19题× ')
                        self.label_019.setStyleSheet("color:rgb(255, 0, 0)")
                    elif i == 19:
                        self.lineEdit_020.setStyleSheet("color:rgb(255, 0, 0)")
                        self.label_020.setText('20题× ')
                        self.label_020.setStyleSheet("color:rgb(255, 0, 0)")

            self.lineEdit_daduitishu.setText(str(self.right))  # 显示正确错误半对的数量
            self.lineEdit_banduitishu.setText(str(self.bandu))  # 显示正确错误半对的数量
            self.lineEdit_dacuotishu.setText(str(self.wrong))  # 显示正确错误半对的数量

#② 把答案保存在电子表格,用Opencvyxl 库
            self.chengji = [''] * 24
            self.chengji[0] = self.imgname                                                      #序号入列表
            self.chengji[1] = self.diyigezichuan + self.diergezichuan + self.disangezichuan     #姓名入列表
            self.chengji[2] = self.kaohaochuan                                                  #考号入列表
            self.chengji[3] = (self.right * self.meitifenshu) + (self.bandu * self.bufendefen)  #成绩入列表
            self.chengji[4:] = self.xuan                                                        #选项入列表

            self.chengjiexcel = openpyxl.load_workbook('chengji.xlsx')  # 打开excel
            self.sh1 = self.chengjiexcel['chengjish']                        # 打开表单一
            self.sh2 = self.chengjiexcel['tongjish']                         # 打开表单二

            for col in range(len(self.chengji)):                   # 信息入电子表格
                self.sh1.cell(row =self.imgname + 1  , column = col+1 ).value = self.chengji[col]
            self.chengjiexcel.save('chengji.xlsx')                      #保存
#③ 把选择的正确率做成柱状图用 matplotlib 库
            for zhu in range(len(self.answer)):  #循环显示柱状图
                if self.answer[zhu] != '':
                    plt.figure('第'+ str(zhu+1)+'题')
                    x = ['A', 'B', 'C', 'D']
                    y = [(eval('di' + str(zhu+1) + 'ti').count('A')),(eval('di' + str(zhu+1) + 'ti').count('B')),(eval('di' + str(zhu+1) + 'ti').count('C')),(eval('di' + str(zhu+1) + 'ti').count('D'))]
                    plt.bar(x, y, label='第'+str((zhu+1))+'题选' + self.answer[zhu], color='g')
                    plt.legend()
                    plt.savefig('imgzhu\\'+ str((zhu+1))+'题'+'.jpg')
                    plt.show()
#④用到的库如下
# -*- coding: utf-8 -*-
import sys,os
if hasattr(sys, 'frozen'):
    os.environ['PATH'] = sys._MEIPASS + ";" + os.environ['PATH']
import cv2
import numpy as np
import imutils
import openpyxl
from itertools import chain
from PyQt5 import QtWidgets
from untitled import Ui_Form
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
import matplotlib.pyplot as plt
from PyQt5.QtGui import QPixmap
from PyQt5.QtWidgets import  QApplication
from imutils.perspective import four_point_transform

第八,程序打包:

安装:pip uninstall pyinstaller

打开:CMD

切换路径:自己工程的路径并输入 pyinstaller -F -w Run.py

如果出现错误:

1.在执行命令 pyinstaller -F D:\py\programe\banksystem.py打包生成.exe文件时报错:python maximum recursion depth exceeded

2.处理办法分三步走:
①.命令行输入:pyi-makespec -F D:\py\programe\清单核对\bomcheck.py,会生成一个bomcheck.spec文件
②.找到bomcheck.spec这个文件给它的第二行插入下面两行代码
import sys
sys.setrecursionlimit(50000)
③.重新编译生成命令行输入:pyinstaller -F Run.spec即可

总结:说得好像论七八糟,大神请略过,第一次发博客手生,请见谅!

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值