Metadata-Version: 2.4
Name: afis
Version: 1.2.0
Summary: AFIS library: minutiae extraction, matching, and quality (classical + LEADER ONNX)
Author-email: Ashok Pant <asokpant@gmail.com>
Maintainer-email: Ashok Pant <asokpant@gmail.com>
License-Expression: MIT
Project-URL: Homepage, https://github.com/ashokpant/afis
Project-URL: Repository, https://github.com/ashokpant/afis
Project-URL: Issues, https://github.com/ashokpant/afis/issues
Keywords: fingerprint,afis,biometrics,minutiae,mindtct,bozorth3,mcc,nfiq,nbis,leader,onnx
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Science/Research
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: Programming Language :: Python :: 3.14
Classifier: Topic :: Scientific/Engineering :: Image Recognition
Classifier: Topic :: Security
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: numpy>=1.24
Requires-Dist: scipy>=1.10
Requires-Dist: scikit-image>=0.20
Provides-Extra: fast
Requires-Dist: numba>=0.58; extra == "fast"
Provides-Extra: io
Requires-Dist: pillow>=9.0; extra == "io"
Provides-Extra: leader
Requires-Dist: onnxruntime<1.20,>=1.16; python_version < "3.11" and extra == "leader"
Requires-Dist: onnxruntime>=1.16; python_version >= "3.11" and extra == "leader"
Provides-Extra: test
Requires-Dist: pytest>=7.0; extra == "test"
Requires-Dist: pillow>=9.0; extra == "test"
Dynamic: license-file

# afis

AFIS toolkit for fingerprint minutiae extraction, matching, and quality assessment.
Classical extractors (NBIS/MINDTCT, Gabor, STFT, SAFIS) plus optional **LEADER** ONNX.

## Install

```bash
pip install afis
# or
uv add afis

# Optional: LEADER deep minutiae extractor
pip install 'afis[leader]'
```

From source (includes the optional native NBIS library):

```bash
make install          # uv sync + make native
```

## Quickstart

```python
from afis import NbisExtractor, MindtctExtractor, SafisExtractor, compute_nfiq2

# NIST NBIS (native) — requires make native
nbis = NbisExtractor()
a = nbis.extract_minutiae("finger_a.png")
b = nbis.extract_minutiae("finger_b.png")
print(a.n_minutiae, a.header.image_quality)
print(nbis.match(a, b))

# Pure-Python NBIS-compatible (no native lib)
py = MindtctExtractor()
t = py.extract_minutiae("finger_a.png")

# SourceAFIS-equivalent edge matching (not Bozorth3)
safis = SafisExtractor()
s = safis.extract_minutiae("finger_a.png")
print(safis.match(s, s))

# LEADER ONNX (requires: pip install 'afis[leader]')
from afis import LeaderExtractor
leader = LeaderExtractor()
lt = leader.extract_minutiae("finger_a.png")
print(lt.n_minutiae, leader.match(lt, lt))

# Quality only (NFIQ2, 0–100)
q = compute_nfiq2(image)
print(q.score)
```

## Choose a stack

| Class              | Extract        | Match           | When to use                                  |
|--------------------|----------------|-----------------|----------------------------------------------|
| `NbisExtractor`    | `nbis_mindtct` | `nbis_bozorth3` | NIST NBIS parity, production with native lib |
| `MindtctExtractor` | `mindtct`      | `bozorth3`      | Same NBIS *flow*, pure Python / portable     |
| `SafisExtractor`   | `safis`        | `safis`         | SourceAFIS-style edge pairing                |
| `LeaderExtractor`  | `leader`       | `mcc`           | LEADER ONNX minutiae; needs `afis[leader]`   |

Mix and match freely:

```python
from afis import NbisExtractor

# Classical Gabor enhance + MCC matching
proc = NbisExtractor(extractor="gabor", matcher="mcc")

# STFT enhance + geometric matcher
proc = NbisExtractor(extractor="stft", matcher="geometric")

# LEADER extract + Bozorth3 match
proc = NbisExtractor(extractor="leader", matcher="bozorth3")
```

## Extractors

| Name           | Kind                         | Notes                                                 |
|----------------|------------------------------|-------------------------------------------------------|
| `nbis_mindtct` | Native NBIS MINDTCT / LFS V2 | Closest to NIST tooling; needs `libafis_lfs`          |
| `mindtct`      | Pure-Python MINDTCT          | NBIS-compatible without native lib                    |
| `safis`        | SourceAFIS path              | Minutiae for SAFIS edge matching                      |
| `gabor`        | Classical enhance + CN       | Hong/Wan/Jain-style Gabor; good default research path |
| `stft`         | STFT enhance + CN            | Often stronger on noisy / low-contrast prints         |
| `leader`       | LEADER ONNX (pyfing)         | Fully convolutional; optional `onnxruntime` extra     |

## Matchers

| Name            | Kind                  | Notes                                             |
|-----------------|-----------------------|---------------------------------------------------|
| `nbis_bozorth3` | Native Bozorth3       | NIST score scale; needs height (+ width optional) |
| `bozorth3`      | Pure-Python Bozorth3  | Same idea, no native lib                          |
| `safis`         | SourceAFIS edge crawl | Raw threshold ≈ 40; not Bozorth3                  |
| `mcc`           | Minutia Cylinder-Code | Strong classical matcher; good with gabor/stft/leader |
| `geometric`     | Rigid hypothesis      | Simple baseline / debugging                       |

## Quality (NFIQ2)

`compute_nfiq2(image)` and every extractor report return a unified **0–100** score (ISO/IEC 29794-4 / NFIQ 2 style),
with actionable feedback when available.

```python
from afis import compute_nfiq2

r = compute_nfiq2(image)
print(r.score, r.actionable)
```

## Use cases

| Goal                               | Suggested setup                                   |
|------------------------------------|---------------------------------------------------|
| Drop-in NBIS / agency tooling      | `NbisExtractor()`                                 |
| Portable NBIS without C lib        | `MindtctExtractor()`                              |
| SourceAFIS-like verification       | `SafisExtractor()`                                |
| Deep minutiae (LEADER ONNX)        | `LeaderExtractor()` / `afis[leader]`              |
| Preferred classical matcher        | `matcher="mcc"` (post frame-fix); native NBIS still fastest |
| Fast geometric sanity check        | `matcher="geometric"`                             |
| Enrollment quality gate            | `compute_nfiq2` / `template.header.image_quality` |
| ISO template interchange           | `template.to_iso19794_2()` / `.xyt`               |

## CLI

```bash
afis extract finger.png finger.xyt
afis extract finger.png out.xyt --extractor mindtct
afis extract finger.png out.xyt --extractor leader
afis match a.xyt b.xyt --method bozorth3 --height 480
afis match a.xyt b.xyt --method safis
afis match a.xyt b.xyt --method mcc
afis quality finger.png
```

## Develop

```bash
make install
make test
make build
```

## References

- **NIST NBIS** — MINDTCT / LFS V2 /
  Bozorth3. [NIST Biometric Image Software](https://www.nist.gov/services-resources/software/nist-biometric-image-software-nbis)
- **NFIQ 2 / ISO/IEC 29794-4** — Finger image quality. [usnistgov/NFIQ2](https://github.com/usnistgov/NFIQ2)
- **SourceAFIS** — Edge-pairing matcher algorithm (Važan). [algorithm](https://sourceafis.machinezoo.com/algorithm)
- **MCC** — Cappelli, Ferrara & Maltoni (2010). Minutia Cylinder-Code. *IEEE
  TPAMI*. https://doi.org/10.1109/TPAMI.2010.52
- **LEADER** — Fully convolutional minutiae detector (pyfing). [pyfing](https://github.com/raffaele-cappelli/pyfing)
- **Gabor enhancement** — Hong, Wan & Jain (1998). Fingerprint image enhancement. *IEEE TPAMI*
- **ISO/IEC 19794-2** — Finger minutiae data interchange
- **FVC / FVC-onGoing** — Verification benchmarks (EER, FMR, FNMR)

## License

MIT. Copyright (c) 2026 Ashok Pant.
