How Recognition Works

How Recognition Works

This page walks through what AsposeOcr.Recognize() actually does internally, from input validation to the final RecognitionResult. Calling AsposeOcr.Recognize(OcrInput) runs a fixed, eight-step pipeline. Every step below is grounded in the library’s own implementation — there are no configurable stages.


1. Input Validation

Before any model is loaded, Recognize() validates the OcrInput: it rejects a null input (ArgumentNullException), an unsupported InputType (NotSupportedException), and any queued path that does not exist on disk (FileNotFoundException). No ONNX session is created until every input passes.

2. PDF Rendering or Raster Loading

For InputType.PDF, each page is rendered to a 24-bit RGB image at 150 DPI using Aspose.PDF.FOSS. For InputType.SingleImage, the raster file is loaded directly. The 150 DPI rendering resolution is fixed and not configurable.

3. Detector Preprocessing

The image is converted to grayscale using Rec. 709 luma weights, which preserve perceived brightness more accurately than a simple channel average. If the image’s longest side exceeds 1000 pixels, it is downscaled with a separable Lanczos-8 filter (two one-dimensional passes) to match the detector model’s training-time preprocessing. A 32-pixel white strip is appended to the bottom of the image for the same reason.

4. Region Detection

The preprocessed image is passed through the first embedded ONNX model, which produces text-probability maps and intermediate visual features. A second ONNX model — the refinement model — strengthens the links between adjacent characters so that a full text line is detected as one region rather than several fragments. Both models run on the CPU with Microsoft.ML.OnnxRuntime configured for 8 intra-operation worker threads.

5. Region Post-Processing

The detector’s text and link probability maps are thresholded, then grouped with a four-connected breadth-first flood fill. Each resulting region is dilated, fitted with a minimum-area rectangle, scaled back to source-image coordinates, and reduced to non-nested, axis-aligned line rectangles. These rectangles are what RecognitionResult.LinesResult.Line ultimately returns.

6. Line Recognition

Each detected rectangle is padded by two pixels, cropped out of the source image, and resized — preserving its aspect ratio — onto a fixed 1200×32 white canvas. The result is converted to an NHWC grayscale tensor and passed to the recognition model.

7. CTC Decoding

The recognition model’s raw output is decoded with greedy CTC (Connectionist Temporal Classification) decoding: repeated predicted classes are collapsed, the blank class is removed, and the remaining classes are mapped through the model’s embedded Latin alphabet to produce the line’s recognized text.

8. Result Assembly

Recognized lines are paired with their source-image rectangles to build each RecognitionResult.LinesResult. All non-empty lines are joined with platform line breaks to produce RecognitionResult.RecognitionText.


Sequential vs. Parallel Work

Input files and, for PDFs, individual pages are processed sequentially — there is no input-level multithreading API. Parallelism exists only inside each ONNX inference call, where Microsoft.ML.OnnxRuntime parallelizes graph execution across its 8 configured intra-operation threads.

See Also