compression op• Data kinds: images → image2d
• Call: import fullseye as fs; fs.ledger.jpeg_ghost_quality(ghosts, qualities=None) -> 'np.ndarray' (implementation को सीधे call करना हो तो import imgforensics; imgforensics.jpeg_ghost_quality(ghosts, qualities=None) -> 'np.ndarray', registry से लेना हो तो opsimgforensics.get("jpeg_ghost_quality"))
ghost map की श्रृंखला → हर pixel के लिए जिस quality पर residual न्यूनतम है उसका map। image2d।
यदि qualities छोड़ दिया जाए, तो jpeg_ghost_map का default (40..95 step 5) माना जाता है —— यदि maps की संख्या मेल नहीं खाती, तो ValueError (यह ऐसा map नहीं लौटाता जिसके indices और qualities तालमेल में न हों)।
आउटपुट एक (H, W) array है जिसमें pixel मानों के रूप में स्वयं quality रखी होती है, इसलिए मान की range [0, 1] नहीं है। दिखाने के लिए इसे normalize करें (यह op संख्याएँ लौटाता है, चित्र नहीं)।
★ यदि composite एक बार भी save हो जाए, तो यह argmin बेकार हो जाता है। 2026-09-06 को मापा गया, 128x128 image पर 32x32 patch चिपकाकर, background q92 और material q60:
==================== ================== ==================
शर्त चिपके भाग का mode q background mode q
==================== ================== ==================
दोबारा save नहीं 60 (सही) 95
q95 पर दोबारा save 95 (= backgr.) 95
==================== ================== ==================
कारण यह है कि sweep residual quality के साथ monotonically घटता है —— यदि अंतिम save की गई quality sweep के ऊपरी सिरे पर है, तो argmin हर pixel के लिए वहीं अटक जाता है (मापा गया: save के बाद mean residual एक सीधी रेखा में गिरता है, 230.7 → 5.9e-02)। वास्तविक दुनिया की छेड़छाड़ हमेशा एक save से गुज़रती है, इसलिए असली images पर यह readout एक constant map बन जाता है। मौजूदा test test_jpeg_ghost_finds_the_pasted_quality केवल इसलिए पास होता है क्योंकि composite कभी save नहीं होता (यह अपने आप में एक सही unit test है, और argmin का implementation गलत नहीं है —— उसे पढ़ने का तरीका वास्तविक उपयोग में फिट नहीं बैठता)।
इसकी जगह क्या उपयोग करें: sweep के साथ residual curve की valley depth (स्थानीय गिरावट)। उसी प्रयोग में per-pixel ROC लेने पर, argmin readout का AUC 0.500 था (random के समान), जबकि valley-depth readout का AUC 0.997 / 1 % false positives पर detection rate 0.944 था (examples/poc_forensics_roc.py)। फिर भी, पूरी image को q60 पर दोबारा save करने से यह 0.475 पर गिर जाता है —— "JPEG ghosts post-processing के विरुद्ध कमज़ोर हैं" सही सारांश है।
• Sample data catalog (DL URL / license) — 2-D के लिए skimage.data (BSD/public) + synthetic, 3-D के लिए real data sources (Stanford/PDS आदि) के DL URL।
• Operators का स्रोत और संदर्भ — इस op family के मूल research/methods के स्रोत।
• Algorithm का मानक स्रोत (लेखक, वर्ष) और उपयोग ऊपर की family usage guide में दिए गए हैं।
• image_forensics_audit — py -3.11 examples/image_forensics_audit.py
• poc_forensics_roc — py -3.11 examples/poc_forensics_roc.py
image2d को input के रूप में लेते हैं)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. यह per-op note tools/opdocs.py md से अपने-आप generate होता है (हाथ से edit न करें)।*
© 2026 Kazufumi Furuse — Fullseye operator documentation. Licensed under Apache-2.0.