Metadata-Version: 2.5
Name: pharmacode-toolkit
Version: 0.2.1
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
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.
- 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.
- 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.
- 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 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
```

`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_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)
```

## Supported input

8-bit grayscale or colour PNG, JPEG and TIFF; dark bars on a light background;
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.

## Limitations

See [docs/limitations.md](https://github.com/Dotsen/pharmacode-toolkit/blob/main/docs/limitations.md). In short: no inverted codes, no
two-track or colour Pharmacode, no DPI from file 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).
