Awesome OMR Scanner and Grader using just OpenCV and Python
- Combines the following techniques: 2. Sorting the contours 3. Perspective transform to get top-down view
- Steps involved:
- Detect the OMR sheet
- Apply perspective transform to get the top-down view of the sheet
- Extract out all the bubbles in the sheet
- Sort them in rows
- Determine the answer bubble for each row
- Match with the correct answer
- Do this for all questions (all rows)
- Assumptions:
- The app assumes that the OMR document we are scanning is the main focus of the image.
- All 4 edges of the OMR document are visible in the image.
- The largest rectangle available in the image will be the OMR document.
- Stored the correct answer keys in a dict in python.
- Used Canny edge detection for detecting the edges in the document and Gussian blur for reducing high frequency noise.
- OpenCV has the way to get the top-down view of the image. Used that methodology to get the top-down view.
- Used Otsu’s thresholding method for thresholding.
- Determined the bubbles using the aspect ratio of approx one (1) for it's bounding rectangle.
- Used bitwise operations and masking to find the filled in bubble using the amount of shaded pixels in the bubble.
- python (3.7.3)
- opencv (4.1.0)
- numpy (1.61.4)
- imutils (0.5.2)
python test_grader.py --image images/test_02.png
The results are pretty amazing. The grading system is working perfectly fine.
input
Output
input
Output
- There is no logic to handle non-filled bubbles. (This can be solved by using a threshold value for marking a bubble as filled)
- Multiple bubbles marking is not handled. (This can also be solved using a threshold for marking bubble as filled and counting the number and position of filled bubbles)