jpeg_quality_estimate — IMGFORENSICS compression op

• Datenarten: image2d → table

• Aufruf: import fullseye as fs; fs.ledger.jpeg_quality_estimate(image, max_step: 'int' = 64, n_coeff: 'int' = 21) -> 'dict' (die Implementierung direkt: import imgforensics; imgforensics.jpeg_quality_estimate(image, max_step: 'int' = 64, n_coeff: 'int' = 21) -> 'dict'; aus dem Register: opsimgforensics.get("jpeg_quality_estimate"))

Verwendung

Blinde Schätzung der Quantisierungstabelle und der JPEG-Qualität aus einem decodierten Bild. table.

Es liest nicht die DQT der Datei, sondern schätzt allein aus den Pixeln (das ist der Kern:

selbst bei einem als PNG neu gespeicherten / eingefügten Bild wird "es war ursprünglich JPEG-Qualität N" sichtbar). Es nimmt 8x8-Block-DCTs, schätzt je Koeffizient den Kammabstand (Fan & de Queiroz 2003) und wählt aus der Familie von Standardtabellen, die mit der öffentlichen Skalierungsregel der IJG erzeugt sind, die am besten passende Qualität.

Rückgabe (dict):

jpeg_compressed bool, entschieden danach, wie viele der n_coeff Koeffizienten einen Kamm zeigten.

Kein Beweis, dass "es ein JPEG ist" (siehe caveats unten)

quality geschätzte Qualität 1..100 (None, wenn kein Kamm)

table geschätzte (8, 8)-Quantisierungsschritte (0 = nicht schätzbar)

n_quantized Anzahl der Koeffizienten mit Kamm / n_coeff

fit_error mittlere absolute Differenz zur Standardtabelle der gewählten Qualität

caveats was diese Zahl nicht aussagen kann

Gemessen (tests/test_imgforensics.py::test_jpeg_quality_estimate_recovers_quality, 256x256-Bilder mit 1/f^1.6 per Pillow kodiert → dekodiert, dann geschätzt):

======= ========= =============== ============

Wahr Q Schätz Q Kamm-Koeff. fit_error

======= ========= =============== ============

95 95 11/20 0.091

90 90 19/20 0.579

80 80 13/20 1.308

70 71 12/20 2.083

60 60 9/20 2.111

50 52 7/20 1.857

40 40 6/20 3.333

30 None 4/20 —

======= ========= =============== ============

Das Versagen auf der Seite niedriger Qualität ist eine prinzipielle Grenze. Je niedriger die Qualität, desto mehr hochfrequente Koeffizienten werden auf 0 quantisiert, und das Material zum Lesen des Kamms verschwindet selbst aus dem Bild (die Spalte "Kamm-Koeff." zeigt, wie es verschwindet). Bei Qualität 30 reicht das Material nicht, und es wird keine Schätzung zurückgegeben (quality=None). Hier keine Antwort zu erzwingen, ist die Designlinie dieses op.

Und bei unkomprimiertem PNG jpeg_compressed=False / quality=None (mit 4 seeds bestätigt, im selben Test fixiert). Entscheidend ist, hier nicht stillschweigend "Qualität 100" zu antworten; sonst ergäben "unkomprimiert" und "nahezu verlustfreies JPEG" dieselbe Antwort.

Referenzen (Beispieldaten, Literatur)

• 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.

Ausführbare Beispiele (verifizierte Samples, die diesen Operator wirklich aufrufen)

• image_forensics_audit — py -3.11 examples/image_forensics_audit.py

Typkompatible Folge-Operatoren (nehmen table als Eingabe)

evidence_quantile

Gleiche Kategorie (compression)

error_level_map · jpeg_ghost_map · jpeg_ghost_quality


*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.