Upload explanation.py with huggingface_hub
Browse files- explanation.py +57 -1
explanation.py
CHANGED
|
@@ -25,6 +25,9 @@ def generate_forensic_report(verdict: ForensicVerdict) -> str:
|
|
| 25 |
elif verdict.verdict == "SUSPICIOUS":
|
| 26 |
verdict_emoji = "🟡"
|
| 27 |
verdict_color = "yellow"
|
|
|
|
|
|
|
|
|
|
| 28 |
elif verdict.verdict == "LIKELY AUTHENTIC":
|
| 29 |
verdict_emoji = "🟢"
|
| 30 |
verdict_color = "lightgreen"
|
|
@@ -99,7 +102,57 @@ def generate_forensic_report(verdict: ForensicVerdict) -> str:
|
|
| 99 |
- **Calibration:** Temperature-scaled (τ=1.3) for ECE < 0.02
|
| 100 |
- **Independence Correction:** Applied with α=0.3 correlation penalty
|
| 101 |
|
| 102 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 103 |
|
| 104 |
## ⚖️ Methodology Statement
|
| 105 |
|
|
@@ -184,6 +237,9 @@ def generate_court_brief(verdict: ForensicVerdict) -> str:
|
|
| 184 |
if verdict.verdict in ["FAKE", "LIKELY FAKE"]:
|
| 185 |
conclusion = "the analyzed media exhibits multiple physical and statistical anomalies inconsistent with authentic photographic capture"
|
| 186 |
recommendation = "This evidence supports the conclusion that the media has been synthetically generated or significantly manipulated."
|
|
|
|
|
|
|
|
|
|
| 187 |
elif verdict.verdict == "SUSPICIOUS":
|
| 188 |
conclusion = "the analyzed media exhibits some anomalies that warrant further investigation"
|
| 189 |
recommendation = "Additional forensic examination by a qualified expert is recommended before drawing conclusions."
|
|
|
|
| 25 |
elif verdict.verdict == "SUSPICIOUS":
|
| 26 |
verdict_emoji = "🟡"
|
| 27 |
verdict_color = "yellow"
|
| 28 |
+
elif verdict.verdict == "INCONCLUSIVE":
|
| 29 |
+
verdict_emoji = "⚪"
|
| 30 |
+
verdict_color = "gray"
|
| 31 |
elif verdict.verdict == "LIKELY AUTHENTIC":
|
| 32 |
verdict_emoji = "🟢"
|
| 33 |
verdict_color = "lightgreen"
|
|
|
|
| 102 |
- **Calibration:** Temperature-scaled (τ=1.3) for ECE < 0.02
|
| 103 |
- **Independence Correction:** Applied with α=0.3 correlation penalty
|
| 104 |
|
| 105 |
+
"""
|
| 106 |
+
|
| 107 |
+
# Fix 5: Add modality disclosure when suppression was active
|
| 108 |
+
modality_info = verdict.reasoning_tree.get("modality", {})
|
| 109 |
+
detected_modality = modality_info.get("detected", "UNKNOWN")
|
| 110 |
+
n_adjustments = modality_info.get("adjustments_applied", 0)
|
| 111 |
+
|
| 112 |
+
if detected_modality != "UNKNOWN" and n_adjustments > 0:
|
| 113 |
+
modality_labels = {
|
| 114 |
+
"PORTRAIT_MODE": "smartphone portrait/bokeh mode",
|
| 115 |
+
"MESSAGING": "messaging app (WhatsApp, Telegram, etc.)",
|
| 116 |
+
"SOCIAL_MEDIA": "social media platform",
|
| 117 |
+
"SCREENSHOT": "screen capture",
|
| 118 |
+
"SMARTPHONE": "standard smartphone camera",
|
| 119 |
+
"DSLR": "DSLR/mirrorless camera",
|
| 120 |
+
}
|
| 121 |
+
label = modality_labels.get(detected_modality, detected_modality)
|
| 122 |
+
|
| 123 |
+
report += f"""---
|
| 124 |
+
|
| 125 |
+
## 📱 Capture Modality Notice
|
| 126 |
+
|
| 127 |
+
**Detected modality:** {label} (confidence: {modality_info.get('confidence', 0):.0%})
|
| 128 |
+
|
| 129 |
+
This image appears to have been captured with **{label}**. {n_adjustments} forensic tests
|
| 130 |
+
have been recalibrated to account for known characteristics of this capture modality that
|
| 131 |
+
would otherwise produce false positive signals.
|
| 132 |
+
|
| 133 |
+
"""
|
| 134 |
+
if detected_modality == "PORTRAIT_MODE":
|
| 135 |
+
report += """**Portrait mode disclosure:** Smartphone portrait/bokeh mode uses computational
|
| 136 |
+
neural depth estimation to synthetically blur the background. This produces artifacts
|
| 137 |
+
(autocorrelation peaks, uniform noise regions, abrupt blur transitions, patch-based
|
| 138 |
+
segmentation boundaries) that mimic AI-generation signatures but are normal features
|
| 139 |
+
of authentic portrait mode photography. The following tests have been suppressed:
|
| 140 |
+
Autocorrelation Peak, Texture Repetition, VAE Patch Boundaries, PRNU Uniformity,
|
| 141 |
+
DoF Consistency, Vignetting, HF Noise Structure, Noise Spatial Frequency, CFA Nyquist,
|
| 142 |
+
and Poisson-Gaussian Model.
|
| 143 |
+
|
| 144 |
+
"""
|
| 145 |
+
elif detected_modality == "MESSAGING":
|
| 146 |
+
report += """**Messaging compression disclosure:** Images transmitted via messaging apps are
|
| 147 |
+
re-encoded with lossy JPEG compression and have all EXIF metadata stripped. This produces
|
| 148 |
+
double-compression artifacts and missing metadata that mimic manipulation signatures but
|
| 149 |
+
are normal for images shared via WhatsApp, Telegram, Signal, etc. The following tests have
|
| 150 |
+
been suppressed: EXIF Completeness, Compression Ghosts, ICC Profile, Maker Note,
|
| 151 |
+
Thumbnail Check, Software Detection, JPEG Quantization, and CFA Nyquist.
|
| 152 |
+
|
| 153 |
+
"""
|
| 154 |
+
|
| 155 |
+
report += f"""---
|
| 156 |
|
| 157 |
## ⚖️ Methodology Statement
|
| 158 |
|
|
|
|
| 237 |
if verdict.verdict in ["FAKE", "LIKELY FAKE"]:
|
| 238 |
conclusion = "the analyzed media exhibits multiple physical and statistical anomalies inconsistent with authentic photographic capture"
|
| 239 |
recommendation = "This evidence supports the conclusion that the media has been synthetically generated or significantly manipulated."
|
| 240 |
+
elif verdict.verdict == "INCONCLUSIVE":
|
| 241 |
+
conclusion = "the forensic evidence is insufficient to determine whether the media is authentic or manipulated. The posterior probability is near the prior (50%), indicating the evidence contributed no net signal in either direction"
|
| 242 |
+
recommendation = "No determination can be made from this analysis. The evidence neither supports nor contradicts authenticity. Additional forensic examination with access to the original capture device or higher-resolution source material is recommended."
|
| 243 |
elif verdict.verdict == "SUSPICIOUS":
|
| 244 |
conclusion = "the analyzed media exhibits some anomalies that warrant further investigation"
|
| 245 |
recommendation = "Additional forensic examination by a qualified expert is recommended before drawing conclusions."
|