| --- |
| license: other |
| tags: |
| - fingerprint |
| - image-enhancement |
| - biometrics |
| - latent-fingerprint |
| - pytorch |
| library_name: pytorch |
| pipeline_tag: image-to-image |
| --- |
| |
| # G_render — identity-preserving latent-fingerprint enhancement |
| |
| `g_render2` renders a **clean, examiner-friendly fingerprint image from a degraded latent** while |
| **preserving identity** (ridge angles + minutiae positions). It is a conditional inpainter with a |
| window-attention U-Net backbone and a hard **coverage-gate** that forbids inventing ridges where the |
| input has no evidence — the mechanism that keeps enhancement from destroying identity. |
|
|
| - **Backbone:** `RenderGenerator` = UformerCondGenerator (window spatial self-attention U-Net), 2.94M params |
| - **Input:** 6-channel conditioning at 256×256 → **Output:** 1-channel enhanced image |
| - **Trained:** supervised `degrade(clean) → clean` on NIST SD302 (1999 rolled + 2000 plain prints) |
| - **Benchmark:** NIST SD302, 487 latent probes / 1999 rolled gallery |
|
|
| ## Results (ALL 487 probes) |
|
|
| **Image quality** — best of all methods tested: |
|
|
| | Method | RQI ↑ | KID ↓ | NFIQ2 ↑ | |
| |---|---|---|---| |
| | **g_render2 (this)** | **0.811** | **0.165** | **17.1** | |
| | clan_efsroi | 0.672 | 0.197 | 11.1 | |
| | FLARE | 0.624 | 0.165 | 14.2 | |
| | FingerGAN | 0.393 | 0.264 | 36.8 | |
| | raw latent | 0.290 | 0.263 | 8.3 | |
| |
| **Identity (FingerNet → DMD dense-descriptor matcher):** |
|
|
| | Method | Rank-1 ↑ | AUC ↑ | EER ↓ | |
| |---|---|---|---| |
| | g_render2 + classic_lan post-proc | **0.610** | 0.799 | 0.232 | |
| | raw latent | 0.608 | 0.796 | 0.244 | |
| | g_render2 | 0.600 | 0.788 | 0.261 | |
| | FLARE | 0.559 | 0.749 | 0.296 | |
| | FingerGAN | 0.353 | 0.722 | 0.335 | |
| |
| **g_render2 is the only deep enhancer that reaches best-in-class image quality while keeping matcher |
| identity at or above the raw latent** (all published deep enhancers we tested fall below the raw |
| latent on the matcher). Adding a 0-param analytic `classic_lan` post-process nudges identity slightly |
| above the raw latent (Rank-1 0.610 ≥ 0.608). |
|
|
| ## Usage |
|
|
| ```bash |
| python inference.py input_latent.png output_enhanced.png \ |
| [--roi roi_mask.png] [--minu minutiae_xy.txt] [--device cuda] |
| ``` |
|
|
| ```python |
| import torch |
| from g_render.models.render_generator import RenderGenerator |
| from inference import enhance |
| |
| model = RenderGenerator(in_ch=6).eval() |
| model.load_state_dict(torch.load("pytorch_model.bin", map_location="cpu"), strict=False) |
| enhanced = enhance(model, "input_latent.png", roi_path=None, minu=None, device="cpu") # PIL.Image |
| enhanced.save("output.png") |
| ``` |
|
|
| ### Input conditioning (6 channels, built by `inference.build_cond`) |
| |
| | ch | content | |
| |---|---| |
| | 0 | input image (classic_lan-normalized) — the only raw-pixel channel | |
| | 1–2 | robust orientation field `[cos2θ, sin2θ] · coverage` | |
| | 3 | coverage / ROI mask | |
| | 4 | ridge-frequency map `· coverage` | |
| | 5 | minutiae Gaussian heatmap | |
|
|
| `--roi` (foreground mask) and `--minu` (minutiae) are **optional**: without them the ROI is derived |
| from ridge coherence and the minutiae channel is zero. A curated ROI (e.g. a learned segmenter or an |
| examiner-marked region) gives the cleanest result — the coverage-gate blanks everything outside it. |
|
|
| ## Files |
| `pytorch_model.bin` (weights) · `config.json` · `inference.py` (full pipeline) · `g_render/` |
| (self-contained model code, no external repo needed). |
|
|
| ## Limitations |
| - **Does not add identity information** (data-processing-inequality ceiling): it *preserves* the |
| latent's identity, it does not exceed it. For the strongest automated matching, the analytic |
| `classic_lan` baseline still leads (Rank-1 0.706); use `g_render2` when a **clean, realistic image |
| that keeps identity** is the goal (human examiners, visualization). |
| - Trained/evaluated on 500-ppi NIST SD302 latents; other sensors/resolutions may need re-tuning. |
| - Minutiae positions are jittered slightly by the re-render (weaker on the position-only Bozorth3 |
| matcher than on the dense DMD matcher). |
|
|
| ## Citation / provenance |
| Derived from the FDC-LFE project. Bench protocol: FingerNet→DMD / FingerNet→Bozorth3 on NIST SD302 |
| (487 probes / 1999 gallery). Post-processing baseline `classic_lan` = local adaptive contrast norm |
| (target_std 0.18, gain∈[0.5,4], k=13). License follows the NIST SD302 data terms — verify before use. |
| |