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

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

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

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

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

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

          ③识别考号

          ④计算得分

          ⑤统计全班的每题得分率

          ⑥选择题柱状图

 

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

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

        ② 对图像四角变换

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

        ⑤ 输出选项到列表

 

具体代码:        

  1. #① 打开摄像头,捕获一帧。这里用了定时器,否则会卡
  2. self.timer = QTimer() # 初始化定时器
  3. self.timer.timeout.connect(self.time)#定时器信号
  4. self.cap = cv2.VideoCapture(0) #打开视频
  5. self.cap.set(cv2.CAP_PROP_FRAME_WIDTH, 1366)#图像宽
  6. self.cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 768) #图像高
  7. self.timer.start(1)
    self.ret,self.frame = self.cap.read() #读取内存中的帧
  1. # ②对图像四角变换
  2. if (self.cap.isOpened()):
  3. M = cv2.getRotationMatrix2D((self.frame.shape[1] / 2, self.frame.shape[0] / 2), -90, 0.8) # 获得旋转矩阵
  4. self.frame = cv2.warpAffine(self.frame, M, (self.frame.shape[1], self.frame.shape[0])) # 旋转90度
  5. gray = cv2.cvtColor(self.frame, cv2.COLOR_BGR2GRAY) # 转换为灰度图像
  6. blurred = cv2.GaussianBlur(gray, (3, 3), 0) # 高斯滤波1
  7. edged = cv2.Canny(blurred, 10, 100) # 边缘检测
  8. #cv2.imshow(\'edged\', edged)
  9. cnts = cv2.findContours(edged, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) # 查找轮廓
  10. cnts = cnts[1] if imutils.is_cv2() else cnts[0] # # 用以区分OpenCV2.4和OpenCV3
  11. docCnt = None
  12. if len(cnts) > 0: # 确保至少有一个轮廓被找到
  13. cnts = sorted(cnts, key=cv2.contourArea, reverse=True) # 将轮廓按大小降序排序
  14. for c in cnts: # 对排序后的轮廓循环处理
  15. peri = cv2.arcLength(c, True) # 周长# 获取近似的轮廓
  16. approx = cv2.approxPolyDP(c, 0.02 * peri, True) # 如果近似轮廓有四个顶点,那么就认为找到了答题卡
  17. if len(approx) == 4:
  18. docCnt = approx
  19. break
  20. self.framexianshi = self.frame.copy() # 复制原图
  21. self.paper = four_point_transform(self.frame, docCnt.reshape(4, 2)) # 对原始图像进行四点透视变换
  22. self.framexianshi = cv2.drawContours(self.framexianshi, cnts, 0, (0, 255, 0), 2) #画绿边轮廓
  1. #③ 形态学变换(灰度 反向二值化 开运算 膨胀)
  2. paper = cv2.resize(self.paper, (1196, 1946)) # 重新缩放指定尺寸统一尺寸 便于分割
  3. #cv2.imshow(\'suofanghou\', paper)
  4. hanggao = paper.shape[0]
  5. hanggao_1 = hanggao // 64
  6. liekuan = paper.shape[1]
  7. liekuan_1 = liekuan // 23
  8. huidu = cv2.cvtColor(paper, cv2.COLOR_BGR2GRAY) # 灰度图
  9. t, erzhihua = cv2.threshold(huidu, 95, 255, cv2.THRESH_BINARY_INV) # 反向二值化
  10. # cv2.imshow(\'erzhihua\', erzhihua)
  11. k = np.ones((8, 8), np.uint8) # 开运算
  12. kaiyunsuan = cv2.morphologyEx(erzhihua, cv2.MORPH_OPEN, k) # 开运算
  13. # cv2.imshow(\'kaiyunsuan\', kaiyunsuan)
  14. peng = np.ones((3, 3), np.uint8)
  15. kaiyunsuan = cv2.dilate(kaiyunsuan, peng) # 膨胀

 

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

  1.  

 

  1. # ④ 涂卡面积的占比 这里应该有更好的办法,我只用了这个办法来识别,把感兴趣区域截取更小一些或许更好,这样也完全够了!姓名与考号与此法类似我就不再重复了!
    # 插入列表时候多选我使用了字典处理的
  2. for ii in range(0, 5): # 识别1-5 的选择题
  3. for jj in range(17, 21):
  4. lie = ii * liekuan_1
  5. hang = jj * hanggao_1
  6. baisemianji = cv2.countNonZero(kaiyunsuan[hang: hang + hanggao_1, lie: lie + liekuan_1]) # 涂卡的面积
  7. quanbumianji = hanggao_1 * liekuan_1 # 全部的面积
  8. ratio = baisemianji * 100 / quanbumianji # 涂卡比率; 比例;
  9. # print(ratio)
  10. if (ratio > self.mianjibaifenbi):
  11. if jj == 17:
  12. # print(f\'第 {ii+1} 题选:A \')
  13. self.charuxuan[ii + 1].append(\'A\')
  14. elif jj == 18:
  15. self.charuxuan[ii + 1].append(\'B\')
  16. elif jj == 19:
  17. self.charuxuan[ii + 1].append(\'C\')
  18. elif jj == 20:
  19. self.charuxuan[ii + 1].append(\'D\')
  20. self.gengxinruxuan[ii + 1].append(\'\'.join(self.charuxuan[ii + 1]))
  21. for ii in range(6, 11): # 识别6-10 的选择题
  22. for jj in range(17, 21):
  23. lie = ii * liekuan_1
  24. hang = jj * hanggao_1
  25. baisemianji = cv2.countNonZero(kaiyunsuan[hang: hang + hanggao_1, lie: lie + liekuan_1])
  26. quanbumianji = kaiyunsuan[hanggao_1: hanggao_1 + hanggao_1, liekuan_1: liekuan_1 + liekuan_1].shape[0] * \
  27. erzhihua[hang: hang + hanggao_1, lie: lie + liekuan_1].shape[1]
  28. ratio = baisemianji * 100 / quanbumianji # 比率; 比例;
  29. if (ratio > self.mianjibaifenbi):
  30. if jj == 17:
  31. self.charuxuan[ii].append(\'A\')
  32. elif jj == 18:
  33. self.charuxuan[ii].append(\'B\')
  34. elif jj == 19:
  35. self.charuxuan[ii].append(\'C\')
  36. elif jj == 20:
  37. self.charuxuan[ii].append(\'D\')
  38. self.gengxinruxuan[ii].append(\'\'.join(self.charuxuan[ii]))
  39. for ii in range(12, 17): # 识别11-15 的选择题
  40. for jj in range(17, 21):
  41. lie = ii * liekuan_1
  42. hang = jj * hanggao_1
  43. baisemianji = cv2.countNonZero(kaiyunsuan[hang: hang + hanggao_1, lie: lie + liekuan_1])
  44. quanbumianji = kaiyunsuan[hanggao_1: hanggao_1 + hanggao_1, liekuan_1: liekuan_1 + liekuan_1].shape[0] * \
  45. erzhihua[hang: hang + hanggao_1, lie: lie + liekuan_1].shape[1]
  46. ratio = baisemianji * 100 / quanbumianji # 比率; 比例;
  47. # print(ratio)
  48. if (ratio > self.mianjibaifenbi):
  49. if jj == 17:
  50. self.charuxuan[ii - 1].append(\'A\')
  51. elif jj == 18:
  52. self.charuxuan[ii - 1].append(\'B\')
  53. elif jj == 19:
  54. self.charuxuan[ii - 1].append(\'C\')
  55. elif jj == 20:
  56. self.charuxuan[ii - 1].append(\'D\')
  57. self.gengxinruxuan[ii - 1].append(\'\'.join(self.charuxuan[ii - 1]))
  58. for ii in range(18, 23): # 识别16-20 的选择题
  59. for jj in range(17, 21):
  60. lie = ii * liekuan_1
  61. hang = jj * hanggao_1
  62. baisemianji = cv2.countNonZero(kaiyunsuan[hang: hang + hanggao_1, lie: lie + liekuan_1])
  63. quanbumianji = kaiyunsuan[hanggao_1: hanggao_1 + hanggao_1, liekuan_1: liekuan_1 + liekuan_1].shape[0] * \
  64. erzhihua[hang: hang + hanggao_1, lie: lie + liekuan_1].shape[1]
  65. ratio = baisemianji * 100 / quanbumianji # 比率; 比例;
  66. if (ratio > self.mianjibaifenbi):
  67. if jj == 17:
  68. self.charuxuan[ii - 2].append(\'A\')
  69. elif jj == 18:
  70. self.charuxuan[ii - 2].append(\'B\')
  71. elif jj == 19:
  72. self.charuxuan[ii - 2].append(\'C\')
  73. elif jj == 20:
  74. self.charuxuan[ii - 2].append(\'D\')
  75. self.gengxinruxuan[ii - 2].append(\'\'.join(self.charuxuan[ii - 2]))
  76. self.xuan = list(self.gengxinruxuan.values()) # 字典变成二维列表
  77. self.xuan = list(chain.from_iterable(self.xuan)) # 二维列表变成一维
  78. print(self.xuan)
  79. self.tishu = int(self.lineEdit_tishu.text())
  80. self.xuan = self.xuan[: self.tishu] # 切片除题目数量
  81. self.xuan[self.tishu:] = \' \'
  82. self.xuan = self.xuan[0:20]

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

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

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

  1. #① 判断正确与否是请教QQ群里面的大神,我觉得每次请教可以用红包的方式来请教,虽然都差钱,但是每次你花10元-20元的红包来请教,一来你耽误了别人的宝贵时间,二来别人看你的问题给你解答要动脑筋的,我觉得付费是理所当然的
  2. for i in range(len(self.answer)):
  3. dd = set(self.answer[i].upper())
  4. xx = set(self.xuan[i].upper())
  5. if xx == dd and self.answer[i] != \'\':
  6. self.right = self.right + 1
  7. if i == 0:
  8. self.lineEdit_001.setStyleSheet("color:rgb(0, 170, 0)")
  9. self.label_001.setText(\'1题√ \')
  10. self.label_001.setStyleSheet("color: rgb(0, 170, 0)")
  11. elif i == 1:
  12. self.lineEdit_002.setStyleSheet("color:rgb(0, 170, 0)")
  13. self.label_002.setText(\'2题√ \')
  14. self.label_002.setStyleSheet("color:rgb(0, 170, 0)")
  15. elif i == 2:
  16. self.lineEdit_003.setStyleSheet("color:rgb(0, 170, 0)")
  17. self.label_003.setText(\'3题√ \')
  18. self.label_003.setStyleSheet("color:rgb(0, 170, 0)")
  19. elif i == 3:
  20. self.lineEdit_004.setStyleSheet("color:rgb(0, 170, 0)")
  21. self.label_004.setText(\'4题√ \')
  22. self.label_004.setStyleSheet("color:rgb(0, 170, 0)")
  23. elif i == 4:
  24. self.lineEdit_005.setStyleSheet("color:rgb(0, 170, 0)")
  25. self.label_005.setText(\'5题√ \')
  26. self.label_005.setStyleSheet("color:rgb(0, 170, 0)")
  27. elif i == 5:
  28. self.lineEdit_006.setStyleSheet("color:rgb(0, 170, 0)")
  29. self.label_006.setText(\'6题√ \')
  30. self.label_006.setStyleSheet("color:rgb(0, 170, 0)")
  31. elif i == 6:
  32. self.lineEdit_007.setStyleSheet("color:rgb(0, 170, 0)")
  33. self.label_007.setText(\'7题√ \')
  34. self.label_007.setStyleSheet("color:rgb(0, 170, 0)")
  35. elif i == 7:
  36. self.lineEdit_008.setStyleSheet("color:rgb(0, 170, 0)")
  37. self.label_008.setText(\'8题√ \')
  38. self.label_008.setStyleSheet("color:rgb(0, 170, 0)")
  39. elif i == 8:
  40. self.lineEdit_009.setStyleSheet("color:rgb(0, 170, 0)")
  41. self.label_009.setText(\'9题√ \')
  42. self.label_009.setStyleSheet("color:rgb(0, 170, 0)")
  43. elif i == 9:
  44. self.lineEdit_010.setStyleSheet("color:rgb(0, 170, 0)")
  45. self.label_010.setText(\'10题√ \')
  46. self.label_010.setStyleSheet("color:rgb(0, 170, 0)")
  47. elif i == 10:
  48. self.lineEdit_011.setStyleSheet("color:rgb(0, 170, 0)")
  49. self.label_011.setText(\'11题√ \')
  50. self.label_011.setStyleSheet("color:rgb(0, 170, 0)")
  51. elif i == 11:
  52. self.lineEdit_012.setStyleSheet("color:rgb(0, 170, 0)")
  53. self.label_012.setText(\'12题√ \')
  54. self.label_012.setStyleSheet("color:rgb(0, 170, 0)")
  55. elif i == 12:
  56. self.lineEdit_013.setStyleSheet("color:rgb(0, 170, 0)")
  57. self.label_013.setText(\'13题√ \')
  58. self.label_013.setStyleSheet("color:rgb(0, 170, 0)")
  59. elif i == 13:
  60. self.lineEdit_014.setStyleSheet("color:rgb(0, 170, 0)")
  61. self.label_014.setText(\'14题√ \')
  62. self.label_014.setStyleSheet("color:rgb(0, 170, 0)")
  63. elif i == 14:
  64. self.lineEdit_015.setStyleSheet("color:rgb(0, 170, 0)")
  65. self.label_015.setText(\'15题√ \')
  66. self.label_015.setStyleSheet("color:rgb(0, 170, 0)")
  67. elif i == 15:
  68. self.lineEdit_016.setStyleSheet("color:rgb(0, 170, 0)")
  69. self.label_016.setText(\'16题√ \')
  70. self.label_016.setStyleSheet("color:rgb(0, 170, 0)")
  71. elif i == 16:
  72. self.lineEdit_017.setStyleSheet("color:rgb(0, 170, 0)")
  73. self.label_017.setText(\'17题√ \')
  74. self.label_017.setStyleSheet("color:rgb(0, 170, 0)")
  75. elif i == 17:
  76. self.lineEdit_018.setStyleSheet("color:rgb(0, 170, 0)")
  77. self.label_018.setText(\'18题√ \')
  78. self.label_018.setStyleSheet("color:rgb(0, 170, 0)")
  79. elif i == 18:
  80. self.lineEdit_019.setStyleSheet("color:rgb(0, 170, 0)")
  81. self.label_019.setText(\'19题√ \')
  82. self.label_019.setStyleSheet("color:rgb(0, 170, 0)")
  83. elif i == 19:
  84. self.lineEdit_020.setStyleSheet("color:rgb(0, 170, 0)")
  85. self.label_020.setText(\'20题√ \')
  86. self.label_020.setStyleSheet("color:rgb(0, 170, 0)")
  87. elif (xx.issubset(dd) == True) and (dd.difference(xx) != set()) and (self.answer[i] != \'\') and (self.xuan[i] != \'\'):
  88. self.bandu = self.bandu + 1
  89. if i == 0:
  90. self.lineEdit_001.setStyleSheet("color:rgb(255, 0, 255)")
  91. self.label_001.setText(\'1题乄 \')
  92. self.label_001.setStyleSheet("color: rgb(255, 0, 255)")
  93. elif i == 1:
  94. self.lineEdit_002.setStyleSheet("color:rgb(255, 0, 255)")
  95. self.label_002.setText(\'2题乄 \')
  96. self.label_002.setStyleSheet("color:rgb(255, 0, 255)")
  97. elif i == 2:
  98. self.lineEdit_003.setStyleSheet("color:rgb(255, 0, 255)")
  99. self.label_003.setText(\'3题乄 \')
  100. self.label_003.setStyleSheet("color:rgb(255, 0, 255)")
  101. elif i == 3:
  102. self.lineEdit_004.setStyleSheet("color:rgb(255, 0, 255)")
  103. self.label_004.setText(\'4题乄 \')
  104. self.label_004.setStyleSheet("color:rgb(255, 0, 255)")
  105. elif i == 4:
  106. self.lineEdit_005.setStyleSheet("color:rgb(255, 0, 255)")
  107. self.label_005.setText(\'5题乄 \')
  108. self.label_005.setStyleSheet("color:rgb(255, 0, 255)")
  109. elif i == 5:
  110. self.lineEdit_006.setStyleSheet("color:rgb(255, 0, 255)")
  111. self.label_006.setText(\'6题乄 \')
  112. self.label_006.setStyleSheet("color:rgb(255, 0, 255)")
  113. elif i == 6:
  114. self.lineEdit_007.setStyleSheet("color:rgb(255, 0, 255)")
  115. self.label_007.setText(\'7题乄 \')
  116. self.label_007.setStyleSheet("color:rgb(255, 0, 255)")
  117. elif i == 7:
  118. self.lineEdit_008.setStyleSheet("color:rgb(255, 0, 255)")
  119. self.label_008.setText(\'8题乄 \')
  120. self.label_008.setStyleSheet("color:rgb(255, 0, 255)")
  121. elif i == 8:
  122. self.lineEdit_009.setStyleSheet("color:rgb(255, 0, 255)")
  123. self.label_009.setText(\'9题乄 \')
  124. self.label_009.setStyleSheet("color:rgb(255, 0, 255)")
  125. elif i == 9:
  126. self.lineEdit_010.setStyleSheet("color:rgb(255, 0, 255)")
  127. self.label_010.setText(\'10题乄 \')
  128. self.label_010.setStyleSheet("color:rgb(255, 0, 255)")
  129. elif i == 10:
  130. self.lineEdit_011.setStyleSheet("color:rgb(255, 0, 255)")
  131. self.label_011.setText(\'11题乄 \')
  132. self.label_011.setStyleSheet("color:rgb(255, 0, 255)")
  133. elif i == 11:
  134. self.lineEdit_012.setStyleSheet("color:rgb(255, 0, 255)")
  135. self.label_012.setText(\'12题乄 \')
  136. self.label_012.setStyleSheet("color:rgb(255, 0, 255)")
  137. elif i == 12:
  138. self.lineEdit_013.setStyleSheet("color:rgb(255, 0, 255)")
  139. self.label_013.setText(\'13题乄 \')
  140. self.label_013.setStyleSheet("color:rgb(255, 0, 255)")
  141. elif i == 13:
  142. self.lineEdit_014.setStyleSheet("color:rgb(255, 0, 255)")
  143. self.label_014.setText(\'14题乄 \')
  144. self.label_014.setStyleSheet("color:rgb(255, 0, 255)")
  145. elif i == 14:
  146. self.lineEdit_015.setStyleSheet("color:rgb(255, 0, 255)")
  147. self.label_015.setText(\'15题乄 \')
  148. self.label_015.setStyleSheet("color:rgb(255, 0, 255)")
  149. elif i == 15:
  150. self.lineEdit_016.setStyleSheet("color:rgb(255, 0, 255)")
  151. self.label_016.setText(\'16题乄 \')
  152. self.label_016.setStyleSheet("color:rgb(255, 0, 255)")
  153. elif i == 16:
  154. self.lineEdit_017.setStyleSheet("color:rgb(255, 0, 255)")
  155. self.label_017.setText(\'17题乄 \')
  156. self.label_017.setStyleSheet("color:rgb(255, 0, 255)")
  157. elif i == 17:
  158. self.lineEdit_018.setStyleSheet("color:rgb(255, 0, 255)")
  159. self.label_018.setText(\'18题乄 \')
  160. self.label_018.setStyleSheet("color:rgb(255, 0, 255)")
  161. elif i == 18:
  162. self.lineEdit_019.setStyleSheet("color:rgb(255, 0, 255)")
  163. self.label_019.setText(\'19题乄 \')
  164. self.label_019.setStyleSheet("color:rgb(255, 0, 255)")
  165. elif i == 19:
  166. self.lineEdit_020.setStyleSheet("color:rgb(255, 0, 255)")
  167. self.label_020.setText(\'20题乄 \')
  168. self.label_020.setStyleSheet("color:rgb(255, 0, 255)")
  169. elif self.answer[i] != \'\' :
  170. self.wrong = self.wrong + 1
  171. if i == 0:
  172. self.lineEdit_001.setStyleSheet("color:rgb(255, 0, 0)")
  173. self.label_001.setText(\'1题× \')
  174. self.label_001.setStyleSheet("color: rgb(255, 0, 0)")
  175. elif i == 1:
  176. self.lineEdit_002.setStyleSheet("color:rgb(255, 0, 0)")
  177. self.label_002.setText(\'2题× \')
  178. self.label_002.setStyleSheet("color:rgb(255, 0, 0)")
  179. elif i == 2:
  180. self.lineEdit_003.setStyleSheet("color:rgb(255, 0, 0)")
  181. self.label_003.setText(\'3题× \')
  182. self.label_003.setStyleSheet("color:rgb(255, 0, 0)")
  183. elif i == 3:
  184. self.lineEdit_004.setStyleSheet("color:rgb(255, 0, 0)")
  185. self.label_004.setText(\'4题× \')
  186. self.label_004.setStyleSheet("color:rgb(255, 0, 0)")
  187. elif i == 4:
  188. self.lineEdit_005.setStyleSheet("color:rgb(255, 0, 0)")
  189. self.label_005.setText(\'5题× \')
  190. self.label_005.setStyleSheet("color:rgb(255, 0, 0)")
  191. elif i == 5:
  192. self.lineEdit_006.setStyleSheet("color:rgb(255, 0, 0)")
  193. self.label_006.setText(\'6题× \')
  194. self.label_006.setStyleSheet("color:rgb(255, 0, 0)")
  195. elif i == 6:
  196. self.lineEdit_007.setStyleSheet("color:rgb(255, 0, 0)")
  197. self.label_007.setText(\'7题× \')
  198. self.label_007.setStyleSheet("color:rgb(255, 0, 0)")
  199. elif i == 7:
  200. self.lineEdit_008.setStyleSheet("color:rgb(255, 0, 0)")
  201. self.label_008.setText(\'8题× \')
  202. self.label_008.setStyleSheet("color:rgb(255, 0, 0)")
  203. elif i == 8:
  204. self.lineEdit_009.setStyleSheet("color:rgb(255, 0, 0)")
  205. self.label_009.setText(\'9题× \')
  206. self.label_009.setStyleSheet("color:rgb(255, 0, 0)")
  207. elif i == 9:
  208. self.lineEdit_010.setStyleSheet("color:rgb(255, 0, 0)")
  209. self.label_010.setText(\'10题× \')
  210. self.label_010.setStyleSheet("color:rgb(255, 0, 0)")
  211. elif i == 10:
  212. self.lineEdit_011.setStyleSheet("color:rgb(255, 0, 0)")
  213. self.label_011.setText(\'11题× \')
  214. self.label_011.setStyleSheet("color:rgb(255, 0, 0)")
  215. elif i == 11:
  216. self.lineEdit_012.setStyleSheet("color:rgb(255, 0, 0)")
  217. self.label_012.setText(\'12题× \')
  218. self.label_012.setStyleSheet("color:rgb(255, 0, 0)")
  219. elif i == 12:
  220. self.lineEdit_013.setStyleSheet("color:rgb(255, 0, 0)")
  221. self.label_013.setText(\'13题× \')
  222. self.label_013.setStyleSheet("color:rgb(255, 0, 0)")
  223. elif i == 13:
  224. self.lineEdit_014.setStyleSheet("color:rgb(255, 0, 0)")
  225. self.label_014.setText(\'14题× \')
  226. self.label_014.setStyleSheet("color:rgb(255, 0, 0)")
  227. elif i == 14:
  228. self.lineEdit_015.setStyleSheet("color:rgb(255, 0, 0)")
  229. self.label_015.setText(\'15题× \')
  230. self.label_015.setStyleSheet("color:rgb(255, 0, 0)")
  231. elif i == 15:
  232. self.lineEdit_016.setStyleSheet("color:rgb(255, 0, 0)")
  233. self.label_016.setText(\'16题× \')
  234. self.label_016.setStyleSheet("color:rgb(255, 0, 0)")
  235. elif i == 16:
  236. self.lineEdit_017.setStyleSheet("color:rgb(255, 0, 0)")
  237. self.label_017.setText(\'17题× \')
  238. self.label_017.setStyleSheet("color:rgb(255, 0, 0)")
  239. elif i == 17:
  240. self.lineEdit_018.setStyleSheet("color:rgb(255, 0, 0)")
  241. self.label_018.setText(\'18题× \')
  242. self.label_018.setStyleSheet("color:rgb(255, 0, 0)")
  243. elif i == 18:
  244. self.lineEdit_019.setStyleSheet("color:rgb(255, 0, 0)")
  245. self.label_019.setText(\'19题× \')
  246. self.label_019.setStyleSheet("color:rgb(255, 0, 0)")
  247. elif i == 19:
  248. self.lineEdit_020.setStyleSheet("color:rgb(255, 0, 0)")
  249. self.label_020.setText(\'20题× \')
  250. self.label_020.setStyleSheet("color:rgb(255, 0, 0)")
  251. self.lineEdit_daduitishu.setText(str(self.right)) # 显示正确错误半对的数量
  252. self.lineEdit_banduitishu.setText(str(self.bandu)) # 显示正确错误半对的数量
  253. self.lineEdit_dacuotishu.setText(str(self.wrong)) # 显示正确错误半对的数量

 

 

  1. #② 把答案保存在电子表格,用Opencvyxl 库
  2. self.chengji = [\'\'] * 24
  3. self.chengji[0] = self.imgname #序号入列表
  4. self.chengji[1] = self.diyigezichuan + self.diergezichuan + self.disangezichuan #姓名入列表
  5. self.chengji[2] = self.kaohaochuan #考号入列表
  6. self.chengji[3] = (self.right * self.meitifenshu) + (self.bandu * self.bufendefen) #成绩入列表
  7. self.chengji[4:] = self.xuan #选项入列表
  8. self.chengjiexcel = openpyxl.load_workbook(\'chengji.xlsx\') # 打开excel
  9. self.sh1 = self.chengjiexcel[\'chengjish\'] # 打开表单一
  10. self.sh2 = self.chengjiexcel[\'tongjish\'] # 打开表单二
  11.  
  12. for col in range(len(self.chengji)): # 信息入电子表格
  13. self.sh1.cell(row =self.imgname + 1 , column = col+1 ).value = self.chengji[col]
  14. self.chengjiexcel.save(\'chengji.xlsx\') #保存
  1. #③ 把选择的正确率做成柱状图用 matplotlib 库
  2. for zhu in range(len(self.answer)): #循环显示柱状图
  3. if self.answer[zhu] != \'\':
  4. plt.figure(\'\'+ str(zhu+1)+\'\')
  5. x = [\'A\', \'B\', \'C\', \'D\']
  6. 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\'))]
  7. plt.bar(x, y, label=\'\'+str((zhu+1))+\'题选\' + self.answer[zhu], color=\'g\')
  8. plt.legend()
  9. plt.savefig(\'imgzhu\\\'+ str((zhu+1))+\'\'+\'.jpg\')
  10. plt.show()
  1. #④用到的库如下
  2. # -*- coding: utf-8 -*-
  3. import sys,os
  4. if hasattr(sys, \'frozen\'):
  5. os.environ[\'PATH\'] = sys._MEIPASS + ";" + os.environ[\'PATH\']
  6. import cv2
  7. import numpy as np
  8. import imutils
  9. import openpyxl
  10. from itertools import chain
  11. from PyQt5 import QtWidgets
  12. from untitled import Ui_Form
  13. from PyQt5.QtCore import *
  14. from PyQt5.QtGui import *
  15. from PyQt5.QtWidgets import *
  16. import matplotlib.pyplot as plt
  17. from PyQt5.QtGui import QPixmap
  18. from PyQt5.QtWidgets import QApplication
  19. 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即可

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

版权声明:本文为zty321---原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/zty321---/p/12879895.html