MohsinElis commited on
Commit
dcee7d2
·
verified ·
1 Parent(s): c6f6755

feat: generate seamless RGBA overlay with transparent authentic background

Browse files
Files changed (1) hide show
  1. api/model_server.py +19 -1
api/model_server.py CHANGED
@@ -273,7 +273,10 @@ class TamperingModelServer:
273
  # Directly evaluated from multi-frequency feature map, without artificial color or class overrides.
274
  mask_np = torch.sigmoid(mask)[0, 0].cpu().numpy()
275
 
276
- # Convert raw continuous tampering probabilities [0.0, 1.0] to Turbo false-color RGB heatmap
 
 
 
277
  # 0.0 (Deep Navy/Indigo): Pristine Authentic | 0.50 (Lime Green): Transition | 1.0 (Crimson Red): High Tampering
278
  lut_idx = np.clip(mask_np * 255.0, 0, 255).astype(np.int32)
279
  heatmap_rgb = TURBO_LUT[lut_idx]
@@ -282,6 +285,18 @@ class TamperingModelServer:
282
  mask_pil.save(buf, format="PNG")
283
  mask_b64 = base64.b64encode(buf.getvalue()).decode("utf-8")
284
 
 
 
 
 
 
 
 
 
 
 
 
 
285
  # Frequency bands
286
  bands = self.model.decomposer(tensor)
287
  band_mags = [float(b.abs().mean().item()) for b in bands]
@@ -310,6 +325,9 @@ class TamperingModelServer:
310
  "tampering_detected": pred_idx in [1, 2],
311
  "class_probabilities": class_probs,
312
  "tampering_heatmap_b64": mask_b64,
 
 
 
313
  "frequency_band_contributions": band_dict,
314
  "processing_time_ms": round(elapsed_ms, 2),
315
  "model_variant": self.variant,
 
273
  # Directly evaluated from multi-frequency feature map, without artificial color or class overrides.
274
  mask_np = torch.sigmoid(mask)[0, 0].cpu().numpy()
275
 
276
+ peak_score = round(float(mask_np.max()), 4)
277
+ coverage_ratio = round(float(np.mean(mask_np > 0.50)), 4)
278
+
279
+ # 1. Standalone publication-style Turbo false-color RGB heatmap (Matches Figure 2 Column d in paper)
280
  # 0.0 (Deep Navy/Indigo): Pristine Authentic | 0.50 (Lime Green): Transition | 1.0 (Crimson Red): High Tampering
281
  lut_idx = np.clip(mask_np * 255.0, 0, 255).astype(np.int32)
282
  heatmap_rgb = TURBO_LUT[lut_idx]
 
285
  mask_pil.save(buf, format="PNG")
286
  mask_b64 = base64.b64encode(buf.getvalue()).decode("utf-8")
287
 
288
+ # 2. Seamless RGBA Overlay: Authentic background is 100% transparent (alpha=0),
289
+ # only tampering hotspots glow in vivid Turbo colors without discoloring the original photograph
290
+ overlay_rgba = np.zeros((self.img_size, self.img_size, 4), dtype=np.uint8)
291
+ overlay_rgba[:, :, :3] = heatmap_rgb
292
+ # Threshold: authentic pixels (p < 0.12) are completely transparent; ramps smoothly up to 210 alpha for hotspots
293
+ alpha_map = np.clip((mask_np - 0.12) / 0.25 * 210.0, 0, 210).astype(np.uint8)
294
+ overlay_rgba[:, :, 3] = alpha_map
295
+ overlay_pil = Image.fromarray(overlay_rgba, mode="RGBA")
296
+ buf_overlay = io.BytesIO()
297
+ overlay_pil.save(buf_overlay, format="PNG")
298
+ overlay_b64 = base64.b64encode(buf_overlay.getvalue()).decode("utf-8")
299
+
300
  # Frequency bands
301
  bands = self.model.decomposer(tensor)
302
  band_mags = [float(b.abs().mean().item()) for b in bands]
 
325
  "tampering_detected": pred_idx in [1, 2],
326
  "class_probabilities": class_probs,
327
  "tampering_heatmap_b64": mask_b64,
328
+ "tampering_overlay_b64": overlay_b64,
329
+ "tampering_peak_score": peak_score,
330
+ "tampering_coverage_ratio": coverage_ratio,
331
  "frequency_band_contributions": band_dict,
332
  "processing_time_ms": round(elapsed_ms, 2),
333
  "model_variant": self.variant,