Click here to Skip to main content
15,881,812 members
Articles / Programming Languages / C#

C# - Optical Marks Recognition (OMR) Engine 2.1a (Mar, 2016)

Rate me:
Please Sign up or sign in to vote.
4.93/5 (30 votes)
23 Jan 2018CPOL9 min read 225.7K   974   58   97
An API for creating, detecting and analyzing Optical Marks Sheets (also known as bubble sheets) - it's an upgrade of version of C# OMR Engine 1.0 I wrote back in 2012
OMR (wiki) are answer sheets that are not intended to be read by a human being. This project eliminates the need to buy OMR reading machines and even a photo scanner for a computer. Any >3MP mobile phone camera with autofocus will do the job.

[Important Notice]

I receive emails on a routine basis reporting/asking me about the possible issues and future of this project. It is a poignant situation when I don't find any time to reply to all these messages. I wrote it in 2016 and have since been involved in more important research. Kindly, don't mind if I take longer than usual to answer your messages about this article.

Who Should Read?

  • Desktop, .NET and ASP.NET developers finding a solution to integrate OMR recognition in their own applications
  • Those finding a solution to implement in their academic institutes to automate Bubble Sheet Checking.
  • Student learning Image processing related to OMRs
  • Those who are new to AForge.Net and want to learn some basics

The first kind of followers should keep an eye on these tags: OMR Engine, OMR Console, and OMR Reader.

The second kind should look for an executable called, OMR Tools.

The third and fourth kind of followers should pay more attention to OMR Reader and image Utils.

Background

This article discusses another update in the 2nd version of OMR engine I originally wrote in 2012. It is highly recommended for readers to experience the first version of engine first which is located at C# - Optical Marks Recognition (OMR) Engine 1.0.

I might have given up a long time ago on this project because the world has very less time left to waste on such old-age projects. We have moved to Kinect 2 in Xbox One which is an image processing marvel. But the support and update request I get from developers and students has given me enough push to write the latest release and this article as well.

I'm sorry for those followers of the article who were disappointed earlier because I eliminated the source code but I had my reasons. It's here now and I've tried to make it even more understandable through line-by-line comments.

Some people may ask, "Why reinvent the wheel?" because there are numerous OMR engines and even embedded systems available in the market. But this project is open source and written in high-level language. So, integration with other .NET application is not an issue. This is the main reason I've been devoting time since it started.

What's New?

V2.1 Update (December 2015) "Let's make it open for C# and start making it cross-platform".

  • Added source code in the CodeProject article
  • Added ToolTip Texts to Help you through the GUI interfaces
  • Removed Many Bugs Including registry related exceptions
  • Added a new tool for creating Answer sheets supporting Random answer keys
  • Added a Command Line tool for those who don't want to be bothered by the .NET Environment or want to access the engine from other desktop applications
  • Added Comments for each line of OMR Engine Class, the most used class of the Solution
  • Added inbuilt support for answer scores calculation
  • And many small improvements to avoid exceptions and failures
  • Added a better Event Driven approach to keep an eye on what's going on during a process. Those will love this who cannot bear with a process that doesn't give visual progress update (Like Me)
  • Small Improvements, tweaks, and optimizations in the OMR sheet extraction code (Algorithm remains the same)

V2 is equipped with many tweaks, updates, additions, and removals. Unfortunately, it removes altogether, the backward compatibility of OMR sheets.

  1. Image detection and analysis is now more precise, much reliable and faster
  2. Added a whole class to manage OMR sheet in more like Object-oriented approach
  3. Image color correction method changed from hit-and-trial to absolute
  4. Ability to process images in async threads
  5. XML sheet storage changed to access 2007 database
  6. Added OMR.helpers.dbOps class for managing all database operations in one place
  7. Improved image detection algorithm to consume less memory
  8. Parameter-based output quality and performance adjustment
  9. A nice GUI to create your own OMR sheets.

[FAQ] Terms Used and Basic Concepts

This section contains answers to most asked questions. I recommend everyone to read this section before proceeding any step further.

Most of us know that OMR sheets look like this:

The black markings on this sheet are used for page alignment detection (mostly).

However, this engine DOES NOT use such sheets. Sheets used in this engine look like:

Source images taken from the camera may look as rough as:

The four square blocks on the corners are used to extract OMR sheet from a camera image.

Sheet definitions are saved in an Access Database for portability. Structure of this database is very simple and self-explanatory. However, you don't need to understand it unless you want to make some concept level changes in the engine.

Creating an OMR Sheet

You don't need to know how to create these sheets because there is a class in the solution named, "OMR.forms.asnwerSheetDesigner".

Alternatively, you could simply choose to run the OMR Tools executable to quickly access this window.

The form looks like this:

OMR Sheet Designer

This is the simplest and most comprehensive GUI to create OMR sheets of your own choice. For this, understand these terms:

  • Number Block: Can be used to take registration or roll number of students as well as randomization code of answer sheet. This block can be placed anywhere on the invisible grid. The number of digits can be changed. Just hover over the lower border of a block. The visual style of these blocks can also be changed.
  • Answer Block: Can be used to take answers to Multiple-choice questions (MCQ) or True/False statements. Handling is similar to Registration block. The visual style of these blocks can also be changed.
  • Empty Block/Text Input Region: Some institutes use hand signatures/handwriting marks as record keeping practice and other reasons. This block can be used to identify an empty region on the sheet which requires such input.

One of the most practical features is the background image. You can use any PDF file to make the background of the sheet. This feature can be used typically to add customized text and graphics on the sheet which might and might not be a part of OMR results. Just see above in the sample image for an idea.

Once you are done with the editing, select a sheet name. And save the database. This will generate three files. One Database, one high-resolution rasterized image, and one PDF printable file. Unfortunately, I have forgotten to move the printables to output directory selected, they are copied in the project directory. Kindly don't take it hard.

Answer Key Maker

To automate the process of creating OMR Answer keys, OMR Answer key Maker has been developed. The GUI contains Tooltips for help and doesn't need explanation.

Answer Key Designer

OMR Console

For those who don't want any C# codes and want to use the engine from other applications, may choose to use OMR console. Type "Help" in the command line to read about the usage. The console can also accept command-line start-up parameters and won't need any manual inputs from users.

OMR Console

Code Organisation

I've tried my best to simplify the things from previous versions. Download and extract the source code or the relevant release from above attachments and get to know the code.

After you have set everything up, you will find that there is one main namespace, which contains the engine. Here is what everything is for:

  • OMR >> Namspace which contains the engine
  • OMR.helpers >> contains some classes which act as helping classes like database reading, image utilities, and PDFconversion wrappers
  • OMR.OMRReader >> Core class of engine which actually performs the sheet detection and analysis algorithms.
  • OMR.OMREngine >> Unlike its name, this call is actually a wrapper for OMR.OMRReader. For easiest usage of the namespace, this is the most preferred class.
  • Everything else does something obviously but is irrelevant to you when you start working with OMR.OMREngine.

Setting Up Everything

There is no need to download any external libraries. The only thing missing is Ghost script DLL which will be downloaded automatically when it is needed. Just extract the source and compile it. Use the sample files provided to get you started,

Using the Code

Unless you want to plumb deeper and play in lower layers of the engine, which I find interesting, you will be playing with only one class, "OMR.OMREngine".

Here is how you declare an engine and use it.

You need:

  1. *.jpg file containing the camera/scanner image.
  2. Address of database containing the OMR sheet definitions. You don't need to know the structure of DB. (I will discuss it later.)
  3. Name of OMR sheet from DB. (I will discuss it later.)
C++
OMR.OMREngine engine = new OMREngine(filenamet.Text, "omrSheet1.accdb", "A4_sq_1");
           engine.onAsyncCompletion +=
           new OMR.AsyncCompletionEventHandler(engine_onAsyncCompletion);
           engine.onAsyncProgressUpdated +=
           new OMR.AsyncProgressEventHandler(engine_onAsyncProgressUpdated);
           engine.StartProcessAsync();

Simple enough? yeah. Event declaration is not compulsory. You can use the synchronous methods or get the status of async processes from engine.Progress and engine.ResultReady properties.

If the process exits with ResultReady set to true, it means that there was one sheet detected and analysed as well.

Results are organized in properties of "engine" member. I will discuss later the structure of sheet, but, according to the definitions sought from DB, results will be compiled.

Following might be what you are looking for:

  • engine.NumberBlocks[index]
    • >RecognisedImage
    • >BinaryMaskedOMs
    • >BlockID
    • >NumberOfLines
    • >Options
    • >StartOfInd
  • engine.AnswerBlock[index]
    • >RecognisedImage
    • >BinaryMaskedOMs
    • >BlockID
    • >Digits
  • engine.EmptyBlock[index]
    • >RecognisedImage
    • >BlockID

All these blocks also contain ToString overload which converts the result and score into human readable string.

There are many other useful properties and functions in this class. All have text descriptions written within. Just use Visual Studio to read those details.

The concept of this engine is to give you an API. This is the most fundamental and organized information which needs analysis and image processing. Everything else is on developers concerns. Like:

  • Transforming BinaryMaskedOMs into obtained marks of an answer sheet.
  • Getting registration number of students/randomization code of answer sheet from RegistrationBlocks
  • Organizing results into MS Excel or word format or even emailing them to authorities automatically.

History and Future of Project

This article is a sequel to my other article, C# - Optical Marks Recognition (OMR) Engine 1.0

This release is termed alpha Just because I haven't put every code branch in the test, neither have I put all the quality control checks we usually do. However, I've tested it for very basic usage and it worked like a charm. I'm the only member of my company, can't do so many things voluntarily without getting paid. In coming releases, following things will be done, so keep connected:

  • 100 percent code coverage
  • Removal of all redundant/auxiliary codes
  • Image processing Done in MATLAB for more robust image recognition
  • Removal of debugging helper code
  • Optimisation of performance for multithreading
  • Ability to acquire and convert directly from Webcam Image/scanner Image

History

  • 24th January, 2018: Initial version

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Engineer techCREATIONS
Pakistan Pakistan
Developer, Programmer, Beta Tester; technically, i'm none of these. I'm a mechanical engineer, programming is my passion, my hobby and my amateur non profit profession. I program when ii need and innovate whenever, wherever i want.

Learned:
C#

Mixed:
C#+Applied Mathematicss-Robotics+C++

Developed:
C# OMR Reader
Monopoly (Urdu language)
HybridAutomation Framework
SMS Bomber (Windows Mobile 6 Professional)
Hard disk watch tower
Farmville Super Clicker
Games Profile selector
Windows mobile salat reminder
Windows mobile SMS Pole Host
and alot of other small apps

Comments and Discussions

 
QuestionMan, this wasted my time Pin
act4lmr2-Sep-15 21:41
act4lmr2-Sep-15 21:41 
AnswerRe: Man, this wasted my time Pin
umar.techBOY13-Sep-15 22:39
umar.techBOY13-Sep-15 22:39 
GeneralRe: Man, this wasted my time Pin
umar.techBOY20-Mar-16 2:39
umar.techBOY20-Mar-16 2:39 
QuestionOMREngine.cs is missing Pin
Member 118827683-Aug-15 8:50
Member 118827683-Aug-15 8:50 
AnswerRe: OMREngine.cs is missing Pin
act4lmr2-Sep-15 21:43
act4lmr2-Sep-15 21:43 
QuestionNeed Help ,problem designing omr in A5 landscape. Pin
angel.cass21-May-15 19:21
angel.cass21-May-15 19:21 
Questionhello "Invalid insert Command or DB." Pin
Member 90406352-Apr-15 22:05
Member 90406352-Apr-15 22:05 
AnswerRe: hello "Invalid insert Command or DB." Pin
umar.techBOY4-May-15 14:49
umar.techBOY4-May-15 14:49 
at which specific line do you get this error?

At which specific action does this exception occur?

Run the program through visual studio.

At line where this specific exception occurs, (most hopefully, it would be under a insertCommand() method), look for a string named str, com, or command or similar, It should contain something like "SELECT xxxx.xxx FROM xxxx WHERE xxxxxx . . . ..". Copy that text and show me.
BugRe: hello "Invalid insert Command or DB." Pin
gerfasan2310-Jun-15 5:14
gerfasan2310-Jun-15 5:14 
GeneralRe: hello "Invalid insert Command or DB." Pin
umar.techBOY24-Jul-15 1:47
umar.techBOY24-Jul-15 1:47 
QuestionNo source code, for that: +1 Pin
Axis2312-Mar-15 2:58
Axis2312-Mar-15 2:58 
AnswerRe: No source code, for that: +1 Pin
umar.techBOY12-Mar-15 9:35
umar.techBOY12-Mar-15 9:35 
AnswerRe: No source code, for that: +1 Pin
umar.techBOY20-Mar-16 2:41
umar.techBOY20-Mar-16 2:41 
GeneralRe: No source code, for that: +1 Pin
Axis2320-Mar-16 9:13
Axis2320-Mar-16 9:13 
QuestionOther paper sizes? (for example, U.S. legal 8.5" x 11")? Pin
Member 1114439611-Mar-15 5:00
Member 1114439611-Mar-15 5:00 
AnswerRe: Other paper sizes? (for example, U.S. legal 8.5" x 11")? Pin
umar.techBOY11-Mar-15 6:59
umar.techBOY11-Mar-15 6:59 
QuestionSource Code Pin
Tarun_SJS10-Mar-15 22:00
Tarun_SJS10-Mar-15 22:00 
AnswerRe: Source Code Pin
umar.techBOY11-Mar-15 7:05
umar.techBOY11-Mar-15 7:05 
Questionmissing a file? Pin
Member 1114439610-Mar-15 6:10
Member 1114439610-Mar-15 6:10 
AnswerRe: missing a file? Pin
umar.techBOY11-Mar-15 7:06
umar.techBOY11-Mar-15 7:06 
AnswerRe: missing a file? Pin
virusmaniak18-Apr-15 6:54
virusmaniak18-Apr-15 6:54 
GeneralMy vote of 5 Pin
Humayun Kabir Mamun10-Mar-15 0:45
Humayun Kabir Mamun10-Mar-15 0:45 
QuestionTo all who have been following this topic Pin
umar.techBOY9-Mar-15 8:42
umar.techBOY9-Mar-15 8:42 
AnswerRe: To all who have been following this topic Pin
oscarrd9-Apr-15 9:59
oscarrd9-Apr-15 9:59 
GeneralRe: To all who have been following this topic Pin
umar.techBOY4-May-15 14:45
umar.techBOY4-May-15 14:45 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.