Optical Mark Recognition (OMR)
π Overview
Photograph a paper answer sheet and it automatically reads the options the student filled in and scores the result: locate the sheet, correct the perspective, find the option cells, and decide the answer from how dark each cell is.
A classic education application whose whole pipeline rests on the fundamentals of OpenCV image processing - thresholding, contour detection, perspective transform, and pixel statistics. Comprehensive and well worth building.
π§° What you need
- Computer + camera (or a phone photo of the sheet)
- Python 3.7+ environment
- pip install: opencv-python, numpy
- A printed answer sheet (and a copy of the answer key for marking)
π§ Step by step
Locate the answer sheet
Use edge detection plus contour detection to find the sheet quadrilateral
Warp the perspective so the sheet becomes a standard, straightened view
Grayscale and threshold
Convert to grayscale and then binary to separate filled areas from blank ones
Adaptive thresholding copes better with uneven lighting
Locate the option cells
Use row and column projections to find each question's option area
Or compute the cell positions from the fixed sheet layout
Decide what is filled
Measure the proportion of dark pixels inside each cell
Cells above the threshold count as filled
Build the answer and mark it
Concatenate the filled options into the student's answers
Compare against the answer key to compute the score
Output the result
Annotate each question right or wrong on the sheet and show the total
Batch-process many sheets and export a CSV
π‘ Tips
- Add fiducial marks (black squares in the corners) when designing the sheet - robustness improves dramatically
- Pick the fill threshold from the midpoint between a blank cell and a fully filled cell's pixel ratio
- A very oblique camera angle distorts the perspective correction, so shoot as close to head-on as you can