opencv 答题卡,opencv实现答题卡定位

  opencv 答题卡,opencv实现答题卡定位

  这篇文章主要为大家详细介绍了中文版实现答题卡识别,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  本文实例为大家分享了中文版实现答题卡识别的具体代码,供大家参考,具体内容如下

  识别答题卡

  导入cv2

  将数组作为铭牌导入

  def showImg(img_name,img):

  cv2.imshow(img名称,img)

  cv2.waitKey()

  cv2.destroyAllWindows()

  def get _ max _ rect(sorted _ CNTs):

  对于sorted _ cnts:中的(cannot)不能

  # 轮廓近似

  possible_cnts=[]

  =0.1 * cv2。弧长(CNT,真实值)

  approx=cv2.approxPolyDP(cnt,epsilon,True)

  如果len(近似值)==4:

  可能_cnts.append(cnt)

  possible _ CNTs=sorted(possible _ CNTs,key=lambda x : cv2。arclength(x,True))

  返回可能_计数

  def get _ max _ bounding _ rect(possible _ CNTs):

  # for cnt in possible_cnts:

  # x,y,w,h=cv2.boundingRect(cnt)

  sorted _ CNTs=sorted(possible _ CNTs,key=lambda CNT : cv2。边界矩形(CNT)[2]* cv2。边界矩形(CNT)[3],反向=真)

  打印(已排序_计数[0])

  def show_countour(img,cnt):

  img_copy=img.copy()

  cv2.drawContours(img_copy,cnt,-1,(0,255,0),3)

  显示( img_copy ,img_copy)

  # 读取答题卡图片,并显示

  答案_工作表_ img=cv2。我在读( t1。jpg’)

  打印(answer_sheet_img.shape)

  showImg(answer_sheet_img ,answer_sheet_img)

  # 高斯滤波,去除噪音

  模糊=cv2 .GaussianBlur(answer_sheet_img,(5,5),0)

  显示("模糊",模糊)

  # 图像转灰度值

  sheet_gray=cv2.cvtColor(blur,cv2 .COLOR_BGR2GRAY)

  显示(工作表_灰色,工作表_灰色)

  # 二值化

  retval,sheet _ threshold=cv2。threshold(sheet _ gray,177,255,cv2 .THRESH_BINARY)

  # print(type(sheet_threshold),sheet_threshold)

  显示(工作表_阈值,工作表_阈值)

  # 边界检测

  边缘=cv2 .Canny(sheet_threshold,100,200)

  显示("边缘",边缘)

  #打印(类型(边缘))

  # 寻找轮廓

  copy_edges=edges.copy()

  img_copy=answer_sheet_img.copy()

  img,cnts,hierarchy=cv2。寻找轮廓(复制边缘,cv2 .获得文件树,cv2 .CHAIN_APPROX_SIMPLE)

  cv2.drawContours(img_copy,cnts,-1,(0,0,255),1)

  显示( img_copy ,img_copy)

  # 对所有轮廓加一个外接矩形,找最大的外接矩形

  最大面积指数=无

  面积=0

  对于索引,枚举中的计数(计数):

  x,y,w,h=cv2.boundingRect(cnt)

  如果宽*高是:

  最大面积指数=指数

  show_countour(answer_sheet_img,cnts[max_area_index])

  # 仿射,拿到答题卡主要部位

  x,y,w,h=cv2。边界矩形(CNTs[max _ area _ index])#最大的边界

  cv2.rectangle(answer_sheet_img,(x,y),(x w,y h),(0,0,255),2)

  showImg("answer_sheet_img", answer_sheet_img)

  pts1 = np.float32([[x,y], [x+w, y], [x+w, y+h]])

  pts2 = np.float32([[0,0], [w, 0], [w, h]])

  M = cv2.getAffineTransform(pts1, pts2)

  sheet_threshold_copy = sheet_threshold.copy()

  dst = cv2.warpAffine(sheet_threshold_copy, M, (w, h))

  showImg("dst", dst)

  print(answer_sheet_img.shape)

  part_sheet_img = answer_sheet_img[y:y+h, x:x+w]

  showImg("part_sheet_img", part_sheet_img)

  # 对答案区域灰度,二值,找轮廓

  part_answer_gray = cv2.cvtColor(part_sheet_img, cv2.COLOR_BGR2GRAY) # 灰度

  ret, threshold_answer = cv2.threshold(part_answer_gray, 175, 255, cv2.THRESH_BINARY)

  showImg("threshold_answer", threshold_answer)

  img, answer_cnts, x = cv2.findContours(threshold_answer, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)

  part_sheet_img_copy = part_sheet_img.copy()

  cv2.drawContours(part_sheet_img_copy, answer_cnts, -1, (0, 0, 255), 1)

  showImg("dst_copy", part_sheet_img_copy)

  # 对所有轮廓找外接矩形,想过滤掉不合适的矩形

  print("画矩形")

  answer_filter_cnts = []

  answer_circles = []

  img_ = part_sheet_img.copy()

  for cnt in answer_cnts:

  x, y, w, h = cv2.boundingRect(cnt)

  if 30<w<40 and 30<h<40:

  print(x, y, w, h)

  circle_x = int(x + w/2)

  circle_y = int(y+h/2)

  r = int((w+h)/4)

  answer_circles.append((circle_x, circle_y, r))

  answer_filter_cnts.append(cnt)

  answer_filter_cnts = np.array(answer_filter_cnts)

  cv2.drawContours(img_, answer_filter_cnts, -1, (0, 0, 255), 1)

  # cv2.rectangle(img, (x, y), (x+w, y+h), (0,255,0), 2)

  showImg("img_", img_)

  print("geshu", len(answer_circles))

  # 从answer_circles中取25个

  mask_dict = {1:[],2:[], 3:[], 4:[],5:[]} # 一共不一定是25个圆,将圆按照题目行分类,

  sorted_y_answer_circles = sorted(answer_circles, key=lambda circle: circle[1])

  print("sorted_y_answer_circles", sorted_y_answer_circles)

  set_num = 1

  for index, circle in enumerate(sorted_y_answer_circles):

  if index == 0:

  mask_dict[1].append(circle)

  else:

  if circle[1] - sorted_y_answer_circles[index-1][1] > 30:

  set_num += 1

  mask_dict[set_num].append(circle)

  else:

  mask_dict[set_num].append(circle)

  print("mask_dict", mask_dict)

  for k, mask_circle_list in mask_dict.items(): # 对每一个题目,保留五个答案,多余的舍去

  if len(mask_circle_list) == 5:

  sorted_x_mask_circle_list = sorted(mask_circle_list, key=lambda x:x[0])

  mask_dict[k]=sorted_x_mask_circle_list

  else:

  sorted_x_mask_circle_list = sorted(mask_circle_list, key=lambda x: x[0])

  sorted_x_mask_circle_list_5 = []

  for i, c in enumerate(sorted_x_mask_circle_list):

  if i == 0:

  sorted_x_mask_circle_list_5.append(c)

  else:

  if abs(c[0] - sorted_x_mask_circle_list[i-1][0]) < 10:

  pass

  else:

  sorted_x_mask_circle_list_5.append(c)

  mask_dict[k] = sorted_x_mask_circle_list_5

  print("mask_dict", mask_dict)

  # mask_dict 分好组的按照顺序的圈圈

  # 做掩码

  mask_img = np.zeros_like(part_sheet_img, dtype=uint8) # 全黑图

  showImg("threshold_answer", threshold_answer)

  threshold_answer = np.array(threshold_answer)

  # mask_dict = sorted(mask_dict, key=lambda x: mask_dict.keys())

  all_scores = [] # 所有答案处的评分

  for exercise_num, circle_mask_list in mask_dict.items():

  # 对于每一题

  score_list = [] # 每一题的每个选项的评分,涂黑的为选择的,值越接近0, 评分较低

  for circle_mask in circle_mask_list:

  mask_img_copy = cv2.cvtColor(mask_img, cv2.COLOR_BGR2GRAY)

  # 做一个当前圆的掩码:

  cv2.circle(mask_img_copy, (circle_mask[0], circle_mask[1]), circle_mask[2], (255, 255, 255), -1)

  print(threshold_answer.shape, mask_img_copy.shape)

  mask_img_ = cv2.bitwise_and(threshold_answer, threshold_answer, mask=mask_img_copy)

  score = mask_img_.sum()

  score_list.append(score)

  # showImg("mask_img_", mask_img_)

  all_scores.append(score_list)

  all_score_np = np.array(all_scores)

  s = np.argmin(all_score_np, axis=1) # 找评分最低处即为选择项

  answer_dict = {

  0: "A",

  1: "B",

  2: "C",

  3: "D",

  4: "E"

  }

  for index, v in enumerate(s):

  print("第%s题的答案是%s" %(index+1, answer_dict[v]))

  效果图:

  

 

  以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持盛行IT软件开发工作室。

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

相关文章阅读

  • opencv图像识别数字,opencv 识别
  • opencv图像识别数字,opencv 识别,如何基于opencv实现简单的数字识别
  • opencv图像的旋转角度计算,opencv图像仿射变换
  • opencv图像的旋转角度计算,opencv图像仿射变换,OpenCV图像几何变换之透视变换
  • opencv图像的旋转角度计算,opencv 旋转任意角度
  • opencv图像的旋转角度计算,opencv 旋转任意角度,opencv图片的任意角度旋转实现示例
  • opencv图像处理函数,opencv图像轮廓合并
  • opencv图像处理函数,opencv图像轮廓合并,OpenCV图像处理之七种常用图像几何变换
  • opencv双线性插值函数,opencv 图像插值
  • LBPH人脸识别,基于opencv的人脸识别技术
  • LBPH人脸识别,基于opencv的人脸识别技术,Opencv LBPH人脸识别算法详解
  • ,,OpenCV黑帽运算(BLACKHAT)的使用
  • opencv双线性插值函数,opencv 图像插值,C++ OpenCV实现图像双三次插值算法详解
  • ,,C语言 OpenCV实现柱面投影
  • ,,C++ Opencv imfill孔洞填充函数的实现思路与代码
  • 留言与评论(共有 条评论)
       
    验证码: