Grain · physically-based ISP
Re-shoot the plate through a camera that never existed.
Generated images are too clean. They lack a color-filter array, a photosite response map, optical falloff, a rolling shutter, and the particular way a manufacturer quantizes a JPEG. Grain is a sequential camera simulation that puts those layers back — so a person reads a photograph, and a forensic model reads a sensor.
Order of operations
The chain matches a real capture: scene → meter → glass → shutter → CFA → ADC → ISP → JPEG. Skipping the mosaic and jumping straight to grain overlays is what most “AI film” filters do. That is not this.
- 01
Meter
Harmonize
Gray-pixel AWB toward the body’s white, a guarded exposure pull, highlight desat, inverse-unsharp. AWB backs off on neon, night, and film.
- 02
Lattice
Sub-pixel warp
Breaks periodic GAN/diffusion spectra with a smooth 0.4–1.5px domain warp.
- 03
Lens
Optics
Barrel, cos⁴ falloff, lateral CA, OLPF, and highlight bloom — real glass, not a kernel.
- 04
Shutter
Capture
Handheld micro-blur, tiny rotation, and rolling-shutter shear from a CMOS readout.
- 05
CFA
Sensor
Bayer mosaic, shot/read noise that follows the wells, PRNU, column FPN, hot pixels, 12-bit ADC.
- 06
Develop
ISP
Hamilton–Adams demosaic, camera color matrix, filmic shoulder, unsharp, chroma NR.
- 07
Fix
JPEG + EXIF
4:2:0 JPEG with camera-scaled quant tables, firmware EXIF, and an embedded thumbnail.
What a detector looks for
| Tell | Counter |
|---|---|
| Periodic frequency fingerprint | Smooth domain warp before optics, then 8×8 JPEG grid. |
| Missing CFA correlations | RGGB mosaic, Hamilton–Adams demosaic, residual zipper. |
| No camera fingerprint | Seeded PRNU, column FPN, hot pixels unique to the body. |
| Poisson-inconsistent noise | Shot + read noise in linear photosites, ISO-scaled. |
| PNG / libjpeg tables | 4:2:0 encoder, camera quality, firmware EXIF + thumbnail-ready APP1. |
| Candy highlights / generator white | Gray-pixel AWB + highlight chroma toward white, only when neutrals exist. |
| Over-clarified midtones | Inverse-unsharp before the camera’s own JPEG sharpen. |
Bodies
Each body is a noise profile, color matrix, JPEG quality, firmware string, and filename grammar — not a LUT.
- Sony α7 IVILCE-7M4 v4.00
Clean dual-gain CMOS. Mild sharpening, cool neutrals.
- Canon EOS R5Firmware 2.1.0
Warm Canon color. Slightly stronger JPEG sharpening.
- Nikon Z8Ver.2.10
Stacked CMOS, fast readout. Neutral, high-ISO capable.
- iPhone 16 Pro18.3.1
Deep Fusion / Smart HDR: lifted shadows, punchy sharpen, heavy NR.
- Fujifilm X-T5Digital Camera X-T5 Ver2.10
X-Trans-ish grain, Classic Chrome lean, green-gold midtones.
- Leica M11M11 2.0.2
Minimal NR, strong optical vignetting, microcontrast over sharpen.
- Kodak Portra 400EZ Controller 6.80.010
Halation, clumped dye clouds, warm highlights, olive shadows.
- Compact JPEGVer.1.0
Small-sensor compact: noisy, crunchy JPEG, haloed sharpen.
Limits
Grain does not invent missing anatomy, fix unreadable type, relight a scene, or clone a real camera’s photo-response non-uniformity. Harmonize is a meter, not a compositor: no depth, no bounce, no foreground mask. PRNU here is statistically plausible, not stolen from a serial-numbered body. Detectors evolve. Semantic tells survive any ISP. Do not use this to impersonate documentary photographs, identity documents, or evidence.