File size: 4,309 Bytes
dfc2650
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
---
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.