A Dictionary<string, QuestionAnswers> that associates fields with their answers.
public Dictionary<string, QuestionAnswers> QuestionsAnswers { get; set; }
public String getQuestionsAnswers();
public void setQuestionsAnswers(
java.util.Map<java.lang.String string
QuestionAnswers> questionAnswers
);
public:
property Dictionary<String^, QuestionAnswers^>^ QuestionsAnswers
{
Dictionary<String^, QuestionAnswers^>^ get()
void set(Dictionary<String^, QuestionAnswers^>^ value)
}
QuestionsAnswers # get and set (OmrAnalysisEngine)
Dictionary<string, QuestionAnswers> object
The key in this dictionary is a string that identifies a field. This string should be unique and mapped to a field. To generate a unique string the formatted string contains the page number, the field name and the OmrCollection name, where PageNumber specifies the form page where the OMR field exists. OmrFieldName
is the name for the OMR field. OmrCollectionName
is the name of the OMR collection of interest inside the OMR field.
using Leadtools;
using Leadtools.Barcode;
using Leadtools.Codecs;
using Leadtools.Forms.Processing.Omr;
using Leadtools.Ocr;
private static void GenerateStatistics(List<IRecognitionForm> recognitionForms, IRecognitionForm answers)
{
OmrAnalysisEngine omrAnalysisEngine = new OmrAnalysisEngine(recognitionForms, answers);
omrAnalysisEngine.GradeForms();
// Table generation helpers
const string columnSeparator = " ";
List<List<string>> lines = new List<List<string>>();
List<int> widths = new List<int>();
void AddLine(List<string> line)
{
while (widths.Count < line.Count)
widths.Add(0);
for (int i = 0; i < line.Count; i++)
widths[i] = Math.Max(widths[i], line[i].Length);
lines.Add(line);
}
// Generate the table
foreach (KeyValuePair<string, QuestionAnswers> kvp in omrAnalysisEngine.QuestionsAnswers)
{
List<string> line = new List<string>() { kvp.Key, kvp.Value.Answer };
foreach (KeyValuePair<string, int> stat in kvp.Value.AnswersCount)
line.Add($"{stat.Key}: {stat.Value}");
AddLine(line);
}
// Display the header
if (widths.Count < 2)
Console.WriteLine($"Field{columnSeparator}Answer{columnSeparator}Breakdown");
else
{
widths[0] = Math.Max(widths[0], "Field".Length);
widths[1] = Math.Max(widths[1], "Answer".Length);
Console.WriteLine($"{"Field".PadRight(widths[0])}{columnSeparator}{"Answer".PadRight(widths[1])}{columnSeparator}Breakdown");
}
// Display the results
foreach (List<string> line in lines)
{
for (int i = 0; i < line.Count; i++)
{
if (i > 0)
Console.Write(columnSeparator);
Console.Write($"{line[i].PadRight(widths[i])}");
}
Console.WriteLine();
}
}
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Map;
import java.util.List;
import org.junit.*;
import org.junit.runner.JUnitCore;
import org.junit.runner.Result;
import org.junit.runner.notification.Failure;
import static org.junit.Assert.*;
import leadtools.*;
import leadtools.barcode.*;
import leadtools.codecs.*;
import leadtools.forms.processing.omr.*;
import leadtools.forms.processing.omr.fields.*;
import leadtools.ocr.*;
static final String columnSeparator = " ";
static ArrayList<List<String>> lines = new ArrayList<List<String>>();
static ArrayList<Integer> widths = new ArrayList<Integer>();
private static void AddLine(List<String> line) {
while (widths.size() < line.size())
widths.add(0);
for (int i = 0; i < line.size(); i++)
widths.set(i, Math.max(widths.get(i), line.get(i).length()));
lines.add(line);
}
public static String padRight(String s, int n) {
return String.format("%-" + n + "s", s);
}
public OmrEngine CreateOmrEngine() {
final String OCR_LEAD_RUNTIME_DIR = "C:\\LEADTOOLS23\\Bin\\Common\\OcrLEADRuntime";
OmrEngine omrEngine = new OmrEngine();
// the OmrEngine requires an OcrEngine to be associated with it and for that
// engine to be started
OcrEngine engine = OcrEngineManager.createEngine(OcrEngineType.LEAD);
engine.startup(null, null, null, OCR_LEAD_RUNTIME_DIR);
omrEngine.getEnginesObject().setOcrEngine(engine);
omrEngine.getEnginesObject().setBarcodeEngine(new BarcodeEngine());
// the OmrEngine also has a property for a RasterCodecs object we can use for
// convenience
RasterCodecs codecs = new RasterCodecs();
codecs.getOptions().getLoad().setResolution(300);
codecs.getOptions().getLoad().setXResolution(300);
codecs.getOptions().getLoad().setYResolution(300);
codecs.getOptions().getRasterizeDocument().getLoad().setResolution(300);
codecs.getOptions().getRasterizeDocument().getLoad().setXResolution(300);
codecs.getOptions().getRasterizeDocument().getLoad().setYResolution(300);
omrEngine.getEnginesObject().setRasterCodecs(codecs);
return omrEngine;
}
public ITemplateForm CreateNewTemplate(RasterImage templateImage, OmrEngine engine) {
ITemplateForm template = engine.createTemplateForm();
template.setName("Example Template");
for (int i = 0; i < templateImage.getPageCount(); i++) {
templateImage.setPage(i + 1);
template.getPages().addPage(templateImage);
}
return template;
}
public void AddZonesToTemplate(ITemplateForm template) {
// create two different zones with definitive boundaries
OmrField firstNameField = new OmrField();
firstNameField.setBounds(new LeadRect(152, 768, 788, 1276));
firstNameField.setName("FirstName");
firstNameField.setPageNumber(1);
OmrField testField = new OmrField();
testField.setBounds(new LeadRect(148, 2067, 384, 900));
testField.setPageNumber(1);
testField.setName("Questions 1-15");
// parse the template document for any Omr regions in the boundaries
template.extractInfo(1, new Field[] { firstNameField, testField });
// get the options for the first field (this field is an Alphabetic "Name"
// field)
OmrFieldOptions firstNameOptions = firstNameField.getOptions();
firstNameOptions.setFieldOrientation(OmrFieldOrientation.COLUMN_WISE); // this region should be decomposed into
// columns
firstNameOptions.setTextFormat(OmrTextFormat.AGGREGATED); // these values are contiguous and merged together (such
// as individual letters in a name)
firstNameOptions.setGradeThisField(false); // this region will not be included in statistics generation
firstNameField.setOptions(firstNameOptions);
OmrFieldOptions testFieldOptions = testField.getOptions();
testFieldOptions.setFieldOrientation(OmrFieldOrientation.ROW_WISE); // this region should be decomposed into rows
testFieldOptions.setTextFormat(OmrTextFormat.CSV); // these values are independent and kept separate (such as
// multiple choice answers)
testFieldOptions.setGradeThisField(true); // this region will have statistics generated for it
testFieldOptions.setCorrectGrade(1.0); // the relative weight of this region if this matches the answer key
// (reward for correct answer)
testFieldOptions.setIncorrectGrade(0.0); // relative weight of this region if it does not match the answer key
// (active penalty for incorrect answers)
testFieldOptions.setNoResponseGrade(0.0); // relative weight of this region if no response present (active penalty
// for failing to answer)
testField.setOptions(testFieldOptions);
List<List<String>> availableFirstNameRanges = GenerateOmrFieldValues.generate(firstNameField.getRowsCount(),
firstNameField.getColumnsCount(), firstNameField.getOptions().getFieldOrientation());
firstNameField.setValues(availableFirstNameRanges.get(4)); // this index contains the basic English alphabet
testField.setValues(new ArrayList<String>(List.of("A", "B", "C", "D")));
template.getPages().getPage(1).getFields().add(firstNameField);
template.getPages().getPage(1).getFields().add(testField);
}
public IRecognitionForm GenerateQuestionAnswersRecognitionForm() {
final String LEAD_VARS_IMAGES_DIR = "C:\\LEADTOOLS23\\Resources\\Images";
OmrEngine omrEngine = CreateOmrEngine();
// create template for recognition
String templateFileName = combine(LEAD_VARS_IMAGES_DIR, "Forms\\OMR Processing\\Exam\\exam.tif");
RasterImage templateImage = omrEngine.getEnginesObject().getRasterCodecs().load(templateFileName, 0,
CodecsLoadByteOrder.BGR, 1, 1);
ITemplateForm template = CreateNewTemplate(templateImage, omrEngine);
AddZonesToTemplate(template);
// create an IRecognitionForm which will contain the results of the recognition
// operation
String answerKey = combine(LEAD_VARS_IMAGES_DIR, "Forms\\OMR Processing\\Exam\\answer-key.tif");
IRecognitionForm answers = omrEngine.createRecognitionForm();
answers.setName("Answers");
RasterImage answerKeyImage = omrEngine.getEnginesObject().getRasterCodecs().load(answerKey);
// add each page in the image to the IRecognitionForm
for (int i = 0; i < answerKeyImage.getPageCount(); i++) {
answerKeyImage.setPage(i + 1);
answers.getPages().addPage(answerKeyImage);
}
// this recognizes the IRecognitionForm against the specified template
answers.recognize(template);
return answers;
}
public List<IRecognitionForm> GenerateRecognitionForms() {
final String LEAD_VARS_IMAGES_DIR = "C:\\LEADTOOLS23\\Resources\\Images";
OmrEngine omrEngine = CreateOmrEngine();
// create template for recognition
String templateFileName = combine(LEAD_VARS_IMAGES_DIR, "Forms\\OMR Processing\\Exam\\exam.tif");
RasterImage templateImage = omrEngine.getEnginesObject().getRasterCodecs().load(templateFileName, 0,
CodecsLoadByteOrder.BGR, 1, 1);
ITemplateForm template = CreateNewTemplate(templateImage, omrEngine);
AddZonesToTemplate(template);
// gather filled forms for recognition
String absPath = combine(LEAD_VARS_IMAGES_DIR, "Forms\\OMR Processing\\Exam\\filled");
File dir = new File(absPath);
dir.mkdirs();
String[] inputs = dir.list();
List<IRecognitionForm> recognizedForms = new ArrayList<IRecognitionForm>();
for (int i = 0; i < inputs.length; i++) {
assertTrue(inputs[i] != null);
}
// each filled form is recognized separately
for (int i = 0; i < inputs.length; i++) {
String fileToRecognize = inputs[i];
IRecognitionForm formToRecognize = omrEngine.createRecognitionForm();
formToRecognize.setName(String.format("Exam %s", i + 1));
RasterImage fileToRecognizeImage = omrEngine.getEnginesObject().getRasterCodecs()
.load(combine(absPath, fileToRecognize));
for (int j = 0; j < fileToRecognizeImage.getPageCount(); j++) {
fileToRecognizeImage.setPage(j + 1);
formToRecognize.getPages().addPage(fileToRecognizeImage);
}
formToRecognize.recognize(template);
recognizedForms.add(formToRecognize);
}
return recognizedForms;
}
public void GenerateStatistics() {
List<IRecognitionForm> recognitionForms = GenerateRecognitionForms();
IRecognitionForm answers = GenerateQuestionAnswersRecognitionForm();
OmrAnalysisEngine omrAnalysisEngine = new OmrAnalysisEngine(recognitionForms, answers);
assertTrue(recognitionForms.size() > 1);
assertTrue(answers != null);
omrAnalysisEngine.gradeForms();
// Generate the table
for (Map.Entry<String, QuestionAnswers> kvp : omrAnalysisEngine.getQuestionsAnswers().entrySet()) {
List<String> line = new ArrayList<String>(List.of(kvp.getKey(), kvp.getValue().getAnswer()));
for (Map.Entry<String, Integer> stat : kvp.getValue().getAnswersCount().entrySet())
line.add(String.format("%s: %s", stat.getKey(), stat.getValue()));
AddLine(line);
}
// Display the header
if (widths.size() < 2)
System.out
.println(String.format("Field%sAnswer%sBreakdown", columnSeparator, columnSeparator));
else {
widths.set(0, Math.max(widths.get(0), "Field".length()));
widths.set(1, Math.max(widths.get(1), "Answer".length()));
System.out.println(
String.format("%s%sBreakdown", padRight("Field", widths.get(0)), padRight("Answer", widths.get(0))));
}
// Display the results
for (List<String> line : lines) {
for (int i = 0; i < line.size(); i++) {
if (i > 0)
System.out.print(columnSeparator);
System.out.print(padRight(line.get(i), widths.get(i)));
}
System.out.println();
}
}
Help Collections
Raster .NET | C API | C++ Class Library | HTML5 JavaScript
Document .NET | C API | C++ Class Library | HTML5 JavaScript
Medical .NET | C API | C++ Class Library | HTML5 JavaScript
Medical Web Viewer .NET
Multimedia
Direct Show .NET | C API | Filters
Media Foundation .NET | C API | Transforms
Supported Platforms
.NET, Java, Android, and iOS/macOS Assemblies
Imaging, Medical, and Document
C API/C++ Class Libraries
Imaging, Medical, and Document
HTML5 JavaScript Libraries
Imaging, Medical, and Document
Your email has been sent to support! Someone should be in touch! If your matter is urgent please come back into chat.
Chat Hours:
Monday - Friday, 8:30am to 6pm ET
Thank you for your feedback!
Please fill out the form again to start a new chat.
All agents are currently offline.
Chat Hours:
Monday - Friday
8:30AM - 6PM EST
To contact us please fill out this form and we will contact you via email.