OMR detection
After alignment, Sunbeam converts the image to grayscale, applies a 5 x 5 Gaussian blur, and uses inverse Gaussian adaptive thresholding. It finds contour candidates and treats a candidate as a filled bubble only when all fixed tests pass:
- Contour area is between 80 and 2000.
- Aspect ratio is between 0.5 and 2.0.
- The contour center is in the answer-grid bounds.
- The mean intensity of the blurred region inside the contour is less than 165.
- The contour center is close enough to one of the fixed row and option centers.
These are implementation constants, not configurable calibration settings. Image brightness, blur, pen type, shadows, printing, and camera distortion can alter their result.
Empty and multiple marks
The result always contains keys 1 through 40. A question with no recognized filled bubble has an empty-string answer.
If more than one option is recognized for a question, Sunbeam concatenates the distinct option letters and sorts them alphabetically. For example, marks for A and C become AC. It does not reject, flag, choose between, or otherwise resolve multiple marks. Grading compares the entire detected string to the CSV value, case-insensitively.
The project contains real-sheet coverage for a double-marked AC answer, but this is not a production accuracy guarantee.