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();
}
}