What I'm trying to do is process the attendance sheet below to tell me who is there and who is not 
I am currently using matchTemplate, using a special black dot that finds all the filled dots (the image is first converted to grayscale). Image below

Then I process the matchPattern array and get about the center of each in the y direction, and I see where there are spaces corresponding to the missing students.
The problem I am facing is that this sorting works for perfect input, but my goal is to take a snapshot of a physical sheet of paper and process this? Note: the attendance sheet is made by me, so it can be changed / changed, but necessary.
I have attached a sample image, which will be shown below.
Using my current method is just a disaster (see below). Now I'm not sure where to go from here, I tried to change the threshold, but the past .65 he can not find any images. 
import cv2 import numpy as np from matplotlib import pyplot as plt values = [] img_rgb = cv2.imread('/home/user/Downloads/input.png') img_gray = cv2.cvtColor(img_rgb, cv2.COLOR_BGR2GRAY) template = cv2.imread('/home/user/Downloads/input_2.png',0) w, h = template.shape[::-1] res = cv2.matchTemplate(img_gray,template,cv2.TM_CCOEFF_NORMED) threshold = 0.6 loc = np.where( res >= threshold) for pt in zip(*loc[::-1]): cv2.rectangle(img_rgb, pt, (pt[0] + w, pt[1] + h), (0,0,255), 2) values.append(pt[1]+h/2) cv2.imwrite('output.png',img_rgb) values.sort() pivot = values[0] count = 1 total = values[0] cleaned = [] for x in range(1,len(values)): if(values[x] < pivot+20): pivot = values[x] count = count + 1 total = total + values[x] else: print values[x] cleaned.append(int(total/count)) pivot = values[x] count = 1 total = values[x] if x == len(values)-1: cleaned.append(int(total/count)) print values print cleaned
Here is another test image: 