Metadata-Version: 2.5
Name: pharmacode-toolkit
Version: 0.3.0
Summary: Generate, detect and decode one-track Pharmacode barcodes in images
Project-URL: Homepage, https://github.com/Dotsen/pharmacode-toolkit
Project-URL: Repository, https://github.com/Dotsen/pharmacode-toolkit
Project-URL: Issues, https://github.com/Dotsen/pharmacode-toolkit/issues
Project-URL: Changelog, https://github.com/Dotsen/pharmacode-toolkit/blob/main/CHANGELOG.md
Project-URL: Author, https://www.linkedin.com/in/dotsen/
Author-email: Konstantin Dotsenko <konstantin@dotsenko.pro>
License-Expression: MIT
License-File: LICENSE
Keywords: barcode,computer-vision,laetus,opencv,pharmacode
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Scientific/Engineering :: Image Recognition
Classifier: Typing :: Typed
Requires-Python: >=3.10
Requires-Dist: numpy>=1.26
Requires-Dist: opencv-python-headless>=4.8
Provides-Extra: dev
Requires-Dist: build>=1.2; extra == 'dev'
Requires-Dist: pytest>=8; extra == 'dev'
Requires-Dist: ruff>=0.5; extra == 'dev'
Description-Content-Type: text/markdown

# pharmacode-toolkit

Generate, detect and decode one-track [Pharmacode](https://en.wikipedia.org/wiki/Pharmacode)
barcodes in PNG, JPEG and TIFF images. Pure Python on numpy and OpenCV.

![Three codes found and annotated](https://raw.githubusercontent.com/Dotsen/pharmacode-toolkit/main/examples/annotated/three_codes_scanned.jpg)

```json
{
  "detections": [
    {"bbox": {"x": 45, "y": 63, "width": 149, "height": 94}, "orientation_deg": 0.0,
     "bars": ["narrow", "wide", "wide", "wide", "narrow", "narrow"],
     "bar_widths_px": [3, 9, 9, 9, 3, 3],
     "value": 91, "mirror_value": 77, "confidence": 1.0, "warnings": []}
  ],
  "errors": []
}
```

## What it does

- Encodes any value from 3 to 131070 into the 2..16 narrow/wide bars of the format.
- Writes codes as SVG in exact millimetres, ready for packaging artwork.
- Renders synthetic codes with the Laetus physical dimensions at any DPI, with
  optional rotation, blur, noise, JPEG artefacts, contrast loss, uneven lighting,
  perspective and scaling, all seeded and reproducible.
- Finds one or more codes in an image at 0, 90, 180 and 270 degrees and small tilts,
  dark on light or, with `--polarity light` or `auto`, light on dark.
- Classifies bars, checks quiet zones and geometry, and reports **both** reading
  directions, because the format has no start or stop pattern.
- Writes a JSON result with stable error codes and an annotated image; optionally checks
  the code against an expected value and reports bar, gap and quiet-zone sizes in mm
  against the Laetus tolerances.
- Decodes whole directories in parallel into JSON Lines and CSV, and shows every
  intermediate step of a decode for diagnosis.
- Ships a benchmark that reports a matrix of conditions, not one number.

## Install

```bash
pip install pharmacode-toolkit
```

From a clone of the repository: `pip install .` (or `pip install -e .[dev]` for
development). Requires Python 3.10 or newer. Runtime dependencies: numpy,
opencv-python-headless.

## Quick start

```bash
pharmacode generate --value 12345 --dpi 300 --output sample.png
pharmacode generate --value 12345 --output artwork.svg     # vector, in mm
pharmacode decode sample.png --dpi 300
pharmacode decode sample.png --dpi 300 --json result.json --annotated result.png
pharmacode decode sample.png --dpi 300 --min-confidence 0.8
pharmacode decode sample.png --dpi auto    # the DPI generate stored in the file
pharmacode decode sample.png --dpi 300 --expect 12345      # exit 0 only if it reads 12345
pharmacode decode sample.png --dpi 300 --report-geometry   # sizes in mm vs Laetus tolerances
pharmacode decode photo.jpg --debug-dir debug/              # every intermediate step, to see why
pharmacode batch scans/ --dpi auto --jsonl out.jsonl --csv out.csv --jobs 4
```

`python -m pharmacode ...` works the same as the `pharmacode` command above,
for environments where installing a console script is inconvenient.

From Python:

```python
from pharmacode import DecoderConfig, decode_file, decode_image, load_image

result = decode_image(load_image("sample.png"), DecoderConfig(dpi=300))
for code in result.detections:
    print(code.value, code.mirror_value, code.confidence)

# load, take the DPI from the file's metadata, decode; check against an expected value
result = decode_file("sample.png", DecoderConfig(polarity="auto"), auto_dpi=True)
print(result.matches(12345), result.to_dict(include_geometry=True))
```

## Supported input

8-bit grayscale or colour PNG, JPEG and TIFF; dark bars on a light background
(or light on dark with `--polarity light` or `auto`); codes upright, rotated by multiples of 90 degrees, or tilted a few degrees.
Pass `--dpi` whenever you know the resolution: it enables physical checks and
reliable classification of codes that use a single bar width. `--dpi auto`
takes it from a scan's or a generated image's metadata.

## Limitations

See [docs/limitations.md](https://github.com/Dotsen/pharmacode-toolkit/blob/main/docs/limitations.md). In short: no two-track or colour
Pharmacode, and no DPI from a camera photo's metadata. Thresholds come from the
specification and a synthetic benchmark; on top of that the decoder is checked
against real-world sample images (codes as they appear in the wild: with captions,
tightly cropped, with a rule drawn across the bars, inside a chart of symbologies).

## Documentation

- [Algorithm and threshold provenance](https://github.com/Dotsen/pharmacode-toolkit/blob/main/docs/algorithm.md)
- [Command line and exit codes](https://github.com/Dotsen/pharmacode-toolkit/blob/main/docs/cli.md)
- [Benchmark](https://github.com/Dotsen/pharmacode-toolkit/blob/main/docs/benchmark.md)
- [Provenance](https://github.com/Dotsen/pharmacode-toolkit/blob/main/docs/provenance.md)
- [Changelog](https://github.com/Dotsen/pharmacode-toolkit/blob/main/CHANGELOG.md)

## Disclaimer

This project is an independent implementation from public descriptions of the
format. It is **not validated** for regulated pharmaceutical packaging control and
must not be used as the sole check in such a process.

## Author

Konstantin Dotsenko ([LinkedIn](https://www.linkedin.com/in/dotsen/)).

## License

MIT, see [LICENSE](https://github.com/Dotsen/pharmacode-toolkit/blob/main/LICENSE).
