anky2002 commited on
Commit
bb46227
Β·
verified Β·
1 Parent(s): d6d0dff

Upload agents/modality_detector.py with huggingface_hub

Browse files
Files changed (1) hide show
  1. agents/modality_detector.py +43 -12
agents/modality_detector.py CHANGED
@@ -30,6 +30,25 @@ def detect_modality(img: Image.Image) -> ModalityResult:
30
 
31
  w, h = img.size
32
  gray = np.array(img.convert("L")).astype(np.float64)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
33
 
34
  # ═══ CONTENT-BASED DETECTION (works without metadata) ═════════════
35
 
@@ -75,18 +94,22 @@ def detect_modality(img: Image.Image) -> ModalityResult:
75
  indicators["transition_abruptness"] = round(transition, 2)
76
  indicators["has_detail"] = has_detail
77
 
78
- # Portrait mode scoring β€” multiple independent signals
 
 
 
 
79
  portrait_score = 0.0
80
- if has_detail and bimodal_ratio > 1.0:
81
- portrait_score += 0.25 # Strong bimodal sharpness
82
- if has_detail and blur_uniformity > 0.5:
83
- portrait_score += 0.2 # Uniform blur region
84
- if has_detail and transition > 4.0:
85
- portrait_score += 0.2 # Abrupt sharp/blur boundary
86
- if has_detail and blur_frac > 0.2 and sharp_frac > 0.1:
87
- portrait_score += 0.15 # Distinct regions exist
88
-
89
- if portrait_score > 0.3:
90
  scores["PORTRAIT_MODE"] = portrait_score
91
  indicators["portrait_detected"] = True
92
 
@@ -174,12 +197,20 @@ def detect_modality(img: Image.Image) -> ModalityResult:
174
  modality = "PORTRAIT_MODE"
175
  conf = min(1.0, scores["PORTRAIT_MODE"])
176
 
177
- # SAFETY GUARD: No detail = possible AI. Disable all suppression.
178
  if not has_detail:
179
  modality = "UNKNOWN"
180
  conf = 0.2
181
  indicators["safety_override"] = "Low-detail image β€” suppression disabled"
182
 
 
 
 
 
 
 
 
 
183
  # ═══ BUILD ADJUSTMENTS ════════════════════════════════════════════
184
 
185
  adjustments = _get_modality_adjustments(modality)
 
30
 
31
  w, h = img.size
32
  gray = np.array(img.convert("L")).astype(np.float64)
33
+ rgb = np.array(img.convert("RGB")).astype(np.float64)
34
+
35
+ # ═══ CRITICAL PRE-CHECK: Bayer CFA pattern ═══════════════════════
36
+ # Real camera images have Bayer demosaicing traces: Οƒ_green < Οƒ_red β‰ˆ Οƒ_blue
37
+ # If this is absent, the image CANNOT be from a real camera sensor.
38
+ # This blocks portrait mode suppression from protecting AI images.
39
+ noise_std = {}
40
+ for c, nm in enumerate(["red", "green", "blue"]):
41
+ ch = rgb[:, :, c]
42
+ dn = gaussian_filter(ch, sigma=1.5)
43
+ noise_std[nm] = float(np.std(ch - dn))
44
+
45
+ has_bayer = noise_std["green"] < min(noise_std["red"], noise_std["blue"])
46
+ bayer_margin = min(noise_std["red"], noise_std["blue"]) - noise_std["green"]
47
+ indicators["has_bayer"] = has_bayer
48
+ indicators["bayer_margin"] = round(bayer_margin, 4)
49
+ indicators["noise_g"] = round(noise_std["green"], 3)
50
+ indicators["noise_r"] = round(noise_std["red"], 3)
51
+ indicators["noise_b"] = round(noise_std["blue"], 3)
52
 
53
  # ═══ CONTENT-BASED DETECTION (works without metadata) ═════════════
54
 
 
94
  indicators["transition_abruptness"] = round(transition, 2)
95
  indicators["has_detail"] = has_detail
96
 
97
+ # Portrait mode scoring β€” requires BOTH content signals AND real camera evidence
98
+ # CRITICAL: If no Bayer pattern, this CANNOT be a smartphone portrait photo.
99
+ # AI images that happen to have blurred backgrounds must NOT get portrait suppression.
100
+ can_be_portrait = has_detail and has_bayer
101
+
102
  portrait_score = 0.0
103
+ if can_be_portrait and bimodal_ratio > 1.0:
104
+ portrait_score += 0.25
105
+ if can_be_portrait and blur_uniformity > 0.5:
106
+ portrait_score += 0.2
107
+ if can_be_portrait and transition > 4.0:
108
+ portrait_score += 0.2
109
+ if can_be_portrait and blur_frac > 0.2 and sharp_frac > 0.1:
110
+ portrait_score += 0.15
111
+
112
+ if portrait_score > 0.3 and has_bayer:
113
  scores["PORTRAIT_MODE"] = portrait_score
114
  indicators["portrait_detected"] = True
115
 
 
197
  modality = "PORTRAIT_MODE"
198
  conf = min(1.0, scores["PORTRAIT_MODE"])
199
 
200
+ # SAFETY GUARD 1: No detail = possible AI. Disable all suppression.
201
  if not has_detail:
202
  modality = "UNKNOWN"
203
  conf = 0.2
204
  indicators["safety_override"] = "Low-detail image β€” suppression disabled"
205
 
206
+ # SAFETY GUARD 2: No Bayer pattern = not from a real camera sensor.
207
+ # AI-generated images lack Bayer demosaicing traces.
208
+ # Never apply camera-related suppression without Bayer evidence.
209
+ if not has_bayer and modality in ("PORTRAIT_MODE", "SMARTPHONE", "MESSAGING"):
210
+ modality = "UNKNOWN"
211
+ conf = 0.2
212
+ indicators["safety_override"] = f"No Bayer CFA pattern (margin={bayer_margin:.3f}) β€” not from a real camera sensor. All suppression disabled."
213
+
214
  # ═══ BUILD ADJUSTMENTS ════════════════════════════════════════════
215
 
216
  adjustments = _get_modality_adjustments(modality)