Python+Opencv實現攝像頭答題卡識別


前言:大家好,我是一名高中物理教師,比較喜歡學習編程,由於平時批改作業比較忙,所以突然冒出個想法,做個攝像頭答題卡識別就會減輕我平時批改作業的很多負擔,特別是選擇題,重復性的勞動,意義不大,如果用機器代替工作那該多好呀,網上一搜,有很多教程,但是都不太滿意,所以我趁着躲避新冠在家隔離的這段時間,邊學邊做,終於做成了,還沒開學,等開學了就去試試,通過博客園,把我的心得分享給大家!

首先,我學習了三本書,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即可

總結:說得好像論七八糟,大神請略過,第一次發博客手生,請見諒!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM