feat: add screenshot-specific disclosure and court brief conclusion text
Browse files- Forensic report: adds screenshot disclosure explaining that photographic forensic
tests don't apply to UI screenshots, LCD pixel grid artifacts mimic diffusion
harmonics, and verdict should be interpreted with this limitation in mind
- Court brief: overrides conclusion/recommendation text when screenshot detected,
recommending manual content review instead of photographic forensics
- explanation.py +40 -1
explanation.py
CHANGED
|
@@ -179,6 +179,28 @@ are normal for images shared via WhatsApp, Telegram, Signal, etc. The following
|
|
| 179 |
been suppressed: EXIF Completeness, Compression Ghosts, ICC Profile, Maker Note,
|
| 180 |
Thumbnail Check, Software Detection, JPEG Quantization, and CFA Nyquist.
|
| 181 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 182 |
"""
|
| 183 |
|
| 184 |
report += f"""---
|
|
@@ -263,7 +285,24 @@ def generate_court_brief(verdict: ForensicVerdict) -> str:
|
|
| 263 |
timestamp = datetime.datetime.now().strftime("%B %d, %Y at %H:%M UTC")
|
| 264 |
|
| 265 |
# Determine language based on verdict
|
| 266 |
-
if
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 267 |
conclusion = "the analyzed media exhibits multiple physical and statistical anomalies inconsistent with authentic photographic capture"
|
| 268 |
recommendation = "This evidence supports the conclusion that the media has been synthetically generated or significantly manipulated."
|
| 269 |
elif verdict.verdict == "INCONCLUSIVE":
|
|
|
|
| 179 |
been suppressed: EXIF Completeness, Compression Ghosts, ICC Profile, Maker Note,
|
| 180 |
Thumbnail Check, Software Detection, JPEG Quantization, and CFA Nyquist.
|
| 181 |
|
| 182 |
+
"""
|
| 183 |
+
elif detected_modality == "SCREENSHOT":
|
| 184 |
+
report += """**Screenshot / screen capture disclosure:** This image appears to be a screen capture
|
| 185 |
+
or photograph of a digital display. **FORENSIQ's methodology is designed for photographic
|
| 186 |
+
images captured by cameras, not for UI screenshots or screen recordings.**
|
| 187 |
+
|
| 188 |
+
Screenshots inherently lack camera sensor characteristics (no Bayer CFA pattern, no PRNU
|
| 189 |
+
fingerprint, no lens physics) and have color distributions that violate natural-image
|
| 190 |
+
statistical priors (few exact UI colors, dark theme backgrounds, Benford's Law violations
|
| 191 |
+
in DCT coefficients). If the screenshot was captured by *photographing a screen*, the
|
| 192 |
+
display's LCD/OLED pixel grid creates periodic frequency artifacts that mimic diffusion
|
| 193 |
+
model noise harmonics — these are display physics, not AI generation signatures.
|
| 194 |
+
|
| 195 |
+
The following test categories have been suppressed or heavily discounted: all optical lens
|
| 196 |
+
tests, all sensor characteristic tests, frequency-domain diffusion detection, and
|
| 197 |
+
natural-image statistical priors (Benford's Law, Color Histogram, DCT/Wavelet Kurtosis).
|
| 198 |
+
|
| 199 |
+
**Interpretation guidance:** For screenshots, FORENSIQ can assess whether visible text is
|
| 200 |
+
coherent and whether semantic content is plausible, but cannot make reliable determinations
|
| 201 |
+
about image authenticity using signal-processing methods. The verdict should be interpreted
|
| 202 |
+
with this limitation in mind.
|
| 203 |
+
|
| 204 |
"""
|
| 205 |
|
| 206 |
report += f"""---
|
|
|
|
| 285 |
timestamp = datetime.datetime.now().strftime("%B %d, %Y at %H:%M UTC")
|
| 286 |
|
| 287 |
# Determine language based on verdict
|
| 288 |
+
# Check if this is a screenshot — override conclusion text if so
|
| 289 |
+
modality_info = verdict.reasoning_tree.get("modality", {})
|
| 290 |
+
is_screenshot = modality_info.get("detected") == "SCREENSHOT"
|
| 291 |
+
|
| 292 |
+
if is_screenshot:
|
| 293 |
+
conclusion = ("the submitted media appears to be a screen capture or photograph of a digital "
|
| 294 |
+
"display interface, not a photographic image captured by a camera. FORENSIQ's "
|
| 295 |
+
"signal-processing methodology is designed for photographic images and has "
|
| 296 |
+
"limited applicability to screenshots. The visible content (text, UI elements) "
|
| 297 |
+
"appears consistent with a genuine application interface, but this assessment "
|
| 298 |
+
"is based on semantic and typographic analysis rather than physical forensics")
|
| 299 |
+
recommendation = ("This image is a screen capture, not a photograph. Standard photographic "
|
| 300 |
+
"forensic tests (lens physics, sensor noise, frequency analysis) are not "
|
| 301 |
+
"applicable to this image type. To verify the authenticity of the depicted "
|
| 302 |
+
"content, manual review of the application data, cross-referencing with "
|
| 303 |
+
"the original source system, or metadata analysis of the screen capture "
|
| 304 |
+
"file itself is recommended.")
|
| 305 |
+
elif verdict.verdict in ["FAKE", "LIKELY FAKE"]:
|
| 306 |
conclusion = "the analyzed media exhibits multiple physical and statistical anomalies inconsistent with authentic photographic capture"
|
| 307 |
recommendation = "This evidence supports the conclusion that the media has been synthetically generated or significantly manipulated."
|
| 308 |
elif verdict.verdict == "INCONCLUSIVE":
|