compression op• Datenarten: images → image2d
• Aufruf: import fullseye as fs; fs.ledger.jpeg_ghost_quality(ghosts, qualities=None) -> 'np.ndarray' (die Implementierung direkt: import imgforensics; imgforensics.jpeg_ghost_quality(ghosts, qualities=None) -> 'np.ndarray'; aus dem Register: opsimgforensics.get("jpeg_ghost_quality"))
Eine Folge von Geisterkarten → eine Karte der Qualität, bei der das Residuum jedes Pixels minimal ist. image2d.
Wird qualities weggelassen, wird der Default von jpeg_ghost_map (40..95 step 5) angenommen —— stimmt die Anzahl der Karten nicht, ValueError (es wird keine Karte mit gegeneinander verschobenen Indizes und Qualitäten zurückgegeben).
Die Rückgabe ist ein (H, W)-Array mit der Qualität selbst als Pixelwert, der Wertebereich ist also nicht [0, 1]. Zur Anzeige normieren (dieses op liefert Zahlen, kein Bild).
★ Wird das Komposit auch nur einmal gespeichert, ist dieses argmin unbrauchbar. Gemessen am 2026-09-06 an einem 128x128-Bild mit eingefügtem 32x32-Stück, Hintergrund q92, Material q60:
==================== ================== ================
Bedingung Häuf. Q eingefügt Häuf. Q Hintergr.
==================== ================== ================
Ohne Speichern 60 (korrekt) 95
Mit q95 gespeichert 95(=Hintergr.) 95
==================== ================== ================
Der Grund ist, dass das Residuum des Sweeps mit der Qualität monoton abnimmt —— liegt die zuletzt gespeicherte Qualität am oberen Ende des Sweeps, bleibt argmin bei jedem Pixel dort hängen (gemessen: das mittlere Residuum nach dem Speichern fällt geradlinig, 230.7 → 5.9e-02). Reale Manipulationen durchlaufen immer ein Speichern, daher wird diese Auslesung bei realen Bildern zu einer konstanten Karte. Der vorhandene Test test_jpeg_ghost_finds_the_pasted_quality besteht nur, weil das Komposit nie gespeichert wird (an sich ist er ein korrekter Unit-Test, und die Implementierung von argmin ist nicht falsch —— die Art der Auslesung passt nicht zur Praxis).
Was stattdessen zu verwenden ist: die Taltiefe der Residuenkurve entlang des Sweeps (die lokale Mulde). Bei pixelweiser ROC im selben Experiment hatte die argmin-Auslesung AUC 0.500 (wie Zufall), die Taltiefen-Auslesung dagegen AUC 0.997 / Detektionsrate 0.944 bei 1 % falsch positiv (examples/poc_forensics_roc.py). Trotzdem fällt sie, wenn das ganze Bild mit q60 neu gespeichert wird, auf 0.475 —— "JPEG-Ghosts sind anfällig für Nachbearbeitung" ist die korrekte Zusammenfassung.
• Katalog der Beispieldaten (Download-URLs / Lizenzen) — 2-D nutzt skimage.data (BSD/Public Domain) plus synthetische Bilder, 3-D nennt Download-URLs echter Datenquellen (Stanford, PDS, …).
• Herkunft und Literatur der Operatoren — die Quellen der Forschung/Verfahren, auf denen diese Operatorfamilie beruht.
• Der kanonische Algorithmus (Autor, Jahr) und seine Anwendungen stehen im Familienleitfaden oben.
• image_forensics_audit — py -3.11 examples/image_forensics_audit.py
• poc_forensics_roc — py -3.11 examples/poc_forensics_roc.py
image2d als Eingabe)perceptual_hash · fingerprint_correlate · error_level_map · jpeg_quality_estimate · jpeg_ghost_map · noise_inconsistency_map · copy_move_regions · watermark_embed
compression)error_level_map · jpeg_quality_estimate · jpeg_ghost_map
*Provenance: imgforensics.py — IMGFORENSICS Operator-Registry. Diese Notiz wird von tools/opdocs.py md erzeugt (nicht von Hand bearbeiten).*
© 2026 Kazufumi Furuse — Fullseye operator documentation. Licensed under Apache-2.0.