Introduction
Aspose.OMR FOSS for Python’s public API (omr.api) is intentionally small: OmrEngine, TemplateProcessor, ImageCollection, and the FormValidationLogic enum. This post looks at what each one does and how they connect across a generate → recognize → export workflow.
The library imports as import omr, is MIT licensed, and depends only on numpy, opencv-python, and Pillow.
What’s Included
OmrEngine — a Stateless Factory
OmrEngine holds no state between calls. Generate(source, settings) accepts either a markup-DSL text source or a code-first TemplateConfig tree, and returns a GenerationResult — the page image(s) plus a .omr template JSON describing every element’s location. GetTemplateProcessor(templateSource, validationLogic) loads a previously saved .omr file (or an in-memory descriptor) and returns a TemplateProcessor bound to it.
from omr.api import OmrEngine, FormValidationLogic
engine = OmrEngine()
gen = engine.Generate("final-exam.txt")
gen.Save("out", "final-exam")
processor = engine.GetTemplateProcessor("out/final-exam.omr", FormValidationLogic.Ignore)
GenerationResult and MemoryGenerationResult
GenerationResult exposes ErrorCode, ErrorMessage, Template (the .omr descriptor as a JSON string), TemplateImage, and — for multi-page templates — MultipageTemplateImages. Save(folder, name) writes the image and descriptor to disk; SaveAsPdf() is not implemented in this release and raises NotImplementedError. MemoryGenerationResult wraps the same data as in-memory streams instead: GetImages() returns a list of in-memory image streams, and GetOmr(encoding) returns the descriptor as a stream — useful when a caller does not want to touch the filesystem at all.
TemplateProcessor — Recognizing Scans
TemplateProcessor.Recognize(source, recognitionThreshold) reads one scanned image against the template it was created from and returns a RecognitionResult. RecognizeFolder(folderPath, recognitionThreshold) runs the same recognition over every image in a folder in one call, returning a list of results — convenient for batch-processing a stack of scans. Recalculate(result, recognitionThreshold) re-scores an already-recognized result with a different threshold, without re-reading the source image.
RecognitionResult — Reading the Answers
Each element in RecognitionResult.OmrElements implements IOmrElement, exposing GetAnswer() and GetCsv() per element, alongside QuestionName. At the result level, GetCsv(encoding), GetJson(encoding), and GetXml(encoding) export the whole result, each with a matching ...AsStream variant that returns a BytesIO instead of a plain string.
ImageCollection — Embedding Images in Markup
ImageCollection is an append-only, case-sensitive map from a name to raw image bytes. Add(name, image) registers an image, Contains(name) checks whether a name is already registered, and as_dict() returns the backing map. Markup can then reference a registered image by name (?image=<name>) instead of a filesystem path — useful when the image bytes come from somewhere other than disk, such as a web upload.
Quick Start
git clone https://github.com/aspose-omr-foss/Aspose.OMR-FOSS-for-Python.git
cd Aspose.OMR-FOSS-for-Python
pip install -e .from omr.api import OmrEngine, FormValidationLogic
engine = OmrEngine()
gen = engine.Generate("final-exam.txt") # or a code-first TemplateConfig
gen.Save("out", "final-exam") # -> out/final-exam.png + out/final-exam.omr
processor = engine.GetTemplateProcessor("out/final-exam.omr", FormValidationLogic.Ignore)
result = processor.Recognize("scan.png") # -100 = auto-calibrated threshold
print(result.GetCsv()) # also GetJson() / GetXml()
Open Source & Licensing
Aspose.OMR FOSS for Python is MIT licensed and hosted on GitHub. Commercial use is permitted under the same terms as any MIT-licensed project. For enterprise features and production support, see Aspose.OMR — Enterprise Product Family.