title: OMR bubble sheet scanner using python opencv
body: <p>I'm working on OMR bubble sheet scanner, detecting the correct bubbled answers using python openCV. While executing with the below code I am not getting the answers correctly. Could anyone please go through the code and let me know where I did a mistake?</p>
  
  <p>I tried with the below URL image</p>
  
  <p><a href="https://www.pyimagesearch.com/wp-content/uploads/2016/10/omr_test_01.png" rel="nofollow noreferrer">https://www.pyimagesearch.com/wp-content/uploads/2016/10/omr_test_01.png</a></p>
  
  <pre><code>import cv2 as cv
  import numpy as np
  
  image = cv.imread("H:/omr_test_01.png",0)
  image1 = cv.imread("H:/omr_test_01.png")
  correct_answers = ['B','E','A','C','B']
  
  crop_img = image[157:975, 42:330]
  #print(crop_img)
  answers = []
  
  itr = 0
  
  for itr in range(2):
      if itr ==0:
          img1 = crop_img[0:818, 0:120]
      else:
          img1 = crop_img[0:818, 167:288]
  
  
  img1 = cv.GaussianBlur(img1,(5,5),0)
  
  img1 = cv.Canny(img1,100,200)
  
  img1 = cv.adaptiveThreshold(img1,255,cv.ADAPTIVE_THRESH_MEAN_C,cv.THRESH_BINARY,11,2)
  img1 = cv.adaptiveThreshold(img1,255,cv.ADAPTIVE_THRESH_MEAN_C,cv.THRESH_BINARY,11,2)
  img1 = cv.adaptiveThreshold(img1,255,cv.ADAPTIVE_THRESH_MEAN_C,cv.THRESH_BINARY,11,2)
  img1 = cv.adaptiveThreshold(img1,255,cv.ADAPTIVE_THRESH_MEAN_C,cv.THRESH_BINARY,11,2)
  img1 = cv.adaptiveThreshold(img1,255,cv.ADAPTIVE_THRESH_MEAN_C,cv.THRESH_BINARY,11,2)
  
  
  img1 = cv.GaussianBlur(img1,(5,5),0)
  
  img = img1
  img = cv.equalizeHist(img)
  
  cimg = cv.cvtColor(img,cv.COLOR_GRAY2BGR)
  print(cimg)
  img1 = cv.Canny(img1,100,200)
  img1 = cv.Canny(img1,100,200)
  img1 = cv.Canny(img1,0,255,cv.THRESH_BINARY_INV | cv.THRESH_OTSU)[1]
  img1 = cv.GaussianBlur(img1,(5,5),1)
  img1 = cv.GaussianBlur(img1,(5,5),1)
  
  circles = cv.HoughCircles(img,cv.HOUGH_GRADIENT,1,10,param1=50,param2=50,minRadius=0,maxRadius=0)
  circles = np.uint16(np.around(circles))
  k=0
  for i in circles[0,:]:
      cv.circle(cimg,(i[0],i[1]),2,(0,255,0),3)
      k = k+1
  
      cv.waitKey(0)
      cv.destroyAllWindows()
  
  
     for i in range(k):
          answers.append(circles[0][i][0]+circles[0][i][1]+circles[0][i][2])
  
  
  sheet = len(answers)
  
  final_answers = []
  for i in range(0,5):
      j = i
      ind = 0
      index = ind
      index = 0
      max = answers[j]
      for j in range(i+1):
          if max&lt;=answers[j]:
              max = answers[j]
              ind = ind+1
              index = ind
      if index == 0:
          final_answers.append('A')
      if index == 1:
          final_answers.append('B')
      if index == 2:
          final_answers.append('C')
      if index == 3:
          final_answers.append('D')
      if index == 4:
          final_answers.append('E')
  
  
  mark = 0
  itrr = len(final_answers)
  for i in range(itrr):
      if final_answers[i]==correct_answers[i]:
          mark = mark+1
  print(final_answers)
  print(mark)
  
  
  font = cv.FONT_HERSHEY_SIMPLEX
  
  cv.putText(image1,'Marks:2/5', (20,450), font, 2,(0,0,255),3,cv.LINE_AA)
  cv.imshow('marks',image1)
  cv.waitKey(0)
  cv.destroyAllWindows()
  </code></pre>
  
  <p>Actual output:</p>
  
  <p>['B', 'E', 'A', 'C', 'B']</p>
  
  <p>5</p>
  
  <p>Getting output:</p>
  
  <p>['B', 'B', 'C', 'C', 'D']</p>
  
  <p>4</p>