npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@mrbilit/mrz-ocr

v2.0.2

Published

MRZ character recognition using ONNX CNN model

Downloads

140

Readme

@mrbilit/mrz-ocr

MRZ character recognition using a small ONNX CNN. Replaces the HOG+SVM pipeline in the original mrz-detection project. Runs on onnxruntime-web (WASM) in the browser and can use onnxruntime-node in Node.js.

This package is part of mrbilit/mrz-scanner, a fork of alsenet-labs/mrz-scanner.

Install

For browser applications:

npm install @mrbilit/mrz-ocr

For Node.js applications, also install the native ONNX Runtime:

npm install @mrbilit/mrz-ocr onnxruntime-node

Usage (Browser)

import { decode } from 'image-js';
import { MrzOcr } from '@mrbilit/mrz-ocr';

const ocr = new MrzOcr({
  modelPath: '/mrz-cnn.onnx', // served as a static asset
});

await ocr.init();

const image = decode(bytes);
const { lines, confidence } = await ocr.recognize(image);

Usage (Node.js)

import { MrzOcr } from '@mrbilit/mrz-ocr';
import * as ort from 'onnxruntime-node';

const ocr = new MrzOcr({
  modelPath: './models/mrz-cnn.onnx',
  ort, // required in Node.js; browser builds default to onnxruntime-web
});

await ocr.init();

Recognition pipeline

recognize(image) assumes the input is a tight crop of the MRZ band (what @mrbilit/mrz-detection produces):

  1. Greyscale + Otsu threshold on the crop.
  2. Connected-component ROIs; try black-pixel ROIs first, fall back to white.
  3. Filter by aspect ratio (0.3–3.0), cluster into lines by center-Y (line height ≈ image.height / 6).
  4. Drop short lines (minCharsPerLine, default 5) and keep the last maxLines (default 3) — covers TD1 (3 lines) and TD2/TD3 (2 lines).
  5. Sort each line left-to-right, resize each character to 20×20, normalize to [0, 1], and batch into a single (N, 1, 20, 20) tensor.
  6. Run the ONNX session; apply softmax over the 37 output logits; emit the argmax character and its probability as confidence.

Model

  • Architecture: Conv(1→32, 3×3)→ReLU→MaxPool→Conv(32→64, 3×3)→ReLU→MaxPool→ Flatten→Dense(128)→ReLU→Dropout(0.3)→Dense(37).
  • ≈75 K parameters, ≈917 KB ONNX (opset 17).
  • 37 classes: 0-9, A-Z, <.
  • Shipped at models/mrz-cnn.onnx with a models/mrz-cnn.json sidecar recording the symbol table and last test accuracy.

Retraining

From packages/mrz-ocr/training:

cd packages/mrz-ocr/training
pip install -r requirements.txt

python extract_ocrb.py
python train_cnn.py --data-dir ./ocrb_chars --output ../models/mrz-cnn.onnx

# Or synthetic data only:
python train_cnn.py --generate --output ../models/mrz-cnn.onnx

After retraining, rebuild any consumer that bundles the model asset.

Exports

interface MrzOcrOptions {
  modelPath?: string;          // default 'mrz-cnn.onnx'
  minCharsPerLine?: number;    // default 5
  maxLines?: number;           // default 3
  ort?: OrtModule;             // pass onnxruntime-node in Node.js
}

interface MrzOcrResult {
  lines: string[];
  confidence: number[][];      // per-character softmax probabilities
}

class MrzOcr {
  constructor(options?: MrzOcrOptions);
  init(): Promise<void>;
  recognize(image: Image): Promise<MrzOcrResult>;
}

const MRZ_SYMBOLS: readonly string[];

Security

Constructor inputs are validated:

  • modelPath must end in .onnx; .. is rejected; only http(s):// URLs and local paths are allowed (no file://, data:, ftp://).
  • recognize() refuses images above 20 megapixels to bound memory.

Development

From the monorepo root:

yarn install
yarn workspace @mrbilit/mrz-ocr build
yarn workspace @mrbilit/mrz-ocr typecheck

License

This project is distributed under the GNU Affero General Public License, version 3 or later (AGPL-3.0-or-later).

The original project and source code are Copyright © 2018-2025 ALSENET SA.

See LICENSE for the full license text.