File size: 12,547 Bytes
e7f1d57
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
# Dependencies
from enum import Enum
from dataclasses import dataclass


class DetectionStatus(str, Enum):
    """
    Overall detection status
    """
    LIKELY_AUTHENTIC = "LIKELY_AUTHENTIC"
    REVIEW_REQUIRED  = "REVIEW_REQUIRED"


class SignalStatus(str, Enum):
    """
    Individual signal status
    """
    PASSED  = "passed"
    WARNING = "warning"
    FLAGGED = "flagged"


class FileFormat(str, Enum):
    """
    Supported file formats
    """
    JPG  = ".jpg"
    JPEG = ".jpeg"
    PNG  = ".png"
    WEBP = ".webp"


class MetricType(str, Enum):
    """
    Detection metric types
    """
    GRADIENT  = "gradient"
    FREQUENCY = "frequency"
    NOISE     = "noise"
    TEXTURE   = "texture"
    COLOR     = "color"



# Signal thresholds
SIGNAL_THRESHOLDS          = {SignalStatus.FLAGGED : 0.7,
                              SignalStatus.WARNING : 0.4,
                              SignalStatus.PASSED  : 0.0,
                             }

# Metric explanations
METRIC_EXPLANATIONS        = {MetricType.GRADIENT  : {'high'     : "Detected irregular gradient patterns typical of diffusion models. Natural photos show consistent lighting gradients shaped by physics.",
                                                      'moderate' : "Some gradient inconsistencies detected. May indicate AI generation or heavy editing.",
                                                      'normal'   : "Gradient patterns are consistent with natural lighting and camera optics."
                                                     },
                              MetricType.FREQUENCY : {'high'     : "Unusual frequency distribution detected. AI-generated images often show unnatural spectral patterns.",
                                                      'moderate' : "Frequency patterns show some irregularities. Requires further review.",
                                                      'normal'   : "Frequency distribution matches expected patterns for authentic photographs."
                                                     },
                              MetricType.NOISE     : {'high'     : "Noise pattern is unnaturally uniform. Real camera sensors produce characteristic noise patterns.",
                                                      'moderate' : "Noise distribution shows some anomalies. May indicate synthetic generation.",
                                                      'normal'   : "Noise characteristics are consistent with genuine camera sensor behavior."
                                                     },
                              MetricType.TEXTURE   : {'high'     : "Detected suspiciously smooth regions. Natural photos have organic texture variation.",
                                                      'moderate' : "Some texture regions appear overly uniform. Further analysis recommended.",
                                                      'normal'   : "Texture variation is within expected ranges for authentic photographs."
                                                     },
                              MetricType.COLOR     : {'high'     : "Color distribution shows impossible or highly unlikely patterns.",
                                                      'moderate' : "Some color histogram irregularities detected.",
                                                      'normal'   : "Color distribution is within normal ranges for real photographs."
                                                     }
                             }

# Basic Image Processing Constants
MIN_IMAGE_DIMENSION        = 64
MAX_IMAGE_DIMENSION        = 8192
LUMINANCE_WEIGHTS          = (0.2126, 0.7152, 0.0722)  # ITU-R BT.709
IMAGE_RESIZE_MAX_DIMENSION = 1024


# Gradient-Field PCA Detection Parameters
@dataclass(frozen = True)
class GradientFieldPCAParams:
    """
    Parameters for Gradient-Field PCA detection
    """
    # Random Seed For Reproducibility 
    RANDOM_SEED                : int   = 1234

    # NEUTRAL_SCORE
    NEUTRAL_SCORE              : float = 0.5

    # PCA Configuration
    SAMPLE_SIZE                : int   = 10000  # Max gradient samples for PCA
    
    # Thresholds
    MAGNITUDE_THRESHOLD        : float = 1e-6   # Minimum gradient magnitude to consider
    MIN_SAMPLES                : int   = 10     # Minimum samples required for PCA
    VARIANCE_THRESHOLD         : float = 1e-10  # Minimum total variance
    EIGENVALUE_RATIO_THRESHOLD : float = 0.85   # Real photos typically > 0.85



# Frequency Analysis Parameters
@dataclass(frozen = True)
class FrequencyAnalysisParams:
    """
    Parameters for FFT-based frequency analysis
    """
    # NEUTRAL_SCORE
    NEUTRAL_SCORE       : float = 0.5

    # FFT Configuration
    BINS                : int   = 64
    HIGH_FREQ_THRESHOLD : float = 0.6     # Radial position where high-freq starts
    
    # Analysis Thresholds
    MIN_SPECTRUM_SAMPLES : int   = 10
    HF_RATIO_UPPER       : float = 0.35   # High-frequency ratio upper bound
    HF_RATIO_LOWER       : float = 0.08   # High-frequency ratio lower bound
    
    # Scaling Factors
    HF_UPPER_SCALE       : float = 3.0
    HF_LOWER_SCALE       : float = 5.0
    ROUGHNESS_SCALE      : float = 10.0
    DEVIATION_SCALE      : float = 2.0
    
    # Sub-metric Weights
    SUBMETRIC_WEIGHTS    : dict  = None
    
    def __post_init__(self):
        if self.SUBMETRIC_WEIGHTS is None:
            object.__setattr__(self, 'SUBMETRIC_WEIGHTS', {'hf_anomaly' : 0.4,
                                                           'roughness'  : 0.3,
                                                           'deviation'  : 0.3,
                                                          }
                              )


# Noise Analysis Parameters
@dataclass(frozen = True)
class NoiseAnalysisParams:
    """
    Parameters for noise pattern analysis
    """
    # NEUTRAL SCORE 
    NEUTRAL_SCORE            : float = 0.5

    # Patch Configuration
    PATCH_SIZE               : int   = 32
    STRIDE                   : int   = 16
    SAMPLES                  : int   = 100
    
    # Variance Thresholds
    VARIANCE_LOW_THRESHOLD   : float = 1.0     # Skip too uniform patches
    VARIANCE_HIGH_THRESHOLD  : float = 1000.0  # Skip too structured patches
    
    # MAD Conversion
    MAD_TO_STD_FACTOR        : float = 1.4826  # Gaussian: σ ≈ 1.4826 × MAD
    
    # Distribution Analysis
    MIN_ESTIMATES            : int   = 10
    MIN_FILTERED_SAMPLES     : int   = 5
    OUTLIER_PERCENTILE_LOW   : int   = 10
    OUTLIER_PERCENTILE_HIGH  : int   = 90
    
    # CV (Coefficient of Variation) Thresholds
    CV_UNIFORM_THRESHOLD     : float = 0.15
    CV_VARIABLE_THRESHOLD    : float = 1.2
    CV_UNIFORM_SCALE         : float = 5.0
    CV_VARIABLE_SCALE        : float = 2.0
    
    # Noise Level Thresholds
    LEVEL_CLEAN_THRESHOLD    : float = 1.5
    LEVEL_LOW_THRESHOLD      : float = 2.5
    
    # IQR Analysis
    IQR_THRESHOLD            : float = 0.3
    IQR_SCALE                : float = 2.0
    IQR_PERCENTILE_LOW       : int   = 25
    IQR_PERCENTILE_HIGH      : int   = 75
    
    # Sub-metric Weights
    SUBMETRIC_WEIGHTS        : dict  = None
    
    def __post_init__(self):
        if self.SUBMETRIC_WEIGHTS is None:
            object.__setattr__(self, 'SUBMETRIC_WEIGHTS', {'cv_anomaly'          : 0.4,
                                                           'noise_level_anomaly' : 0.4,
                                                           'iqr_anomaly'         : 0.2,
                                                          }
                              )


# Texture Analysis Parameters
@dataclass(frozen = True)
class TextureAnalysisParams:
    """
    Parameters for texture analysis
    """
    # Random Seed for reproducibility
    RANDOM_SEED                : int   = 1234

    # Neutral Score 
    NEUTRAL_SCORE              : float = 0.5

    # Patch Configuration
    PATCH_SIZE                 : int   = 64
    N_PATCHES                  : int   = 50
    
    # Histogram Configuration
    HISTOGRAM_BINS             : int   = 32
    HISTOGRAM_RANGE            : tuple = (0, 255)
    
    # Edge Detection
    EDGE_THRESHOLD             : float = 10.0
    
    # Smoothness Analysis
    SMOOTHNESS_THRESHOLD       : float = 0.5
    SMOOTH_RATIO_THRESHOLD     : float = 0.4
    SMOOTH_RATIO_SCALE         : float = 2.5
    
    # Entropy Analysis
    ENTROPY_CV_THRESHOLD       : float = 0.15
    ENTROPY_SCALE              : float = 5.0
    
    # Contrast Analysis
    CONTRAST_CV_LOW            : float = 0.3
    CONTRAST_CV_HIGH           : float = 1.5
    CONTRAST_LOW_SCALE         : float = 2.0
    CONTRAST_HIGH_SCALE        : float = 0.5
    
    # Edge Density Analysis
    EDGE_CV_THRESHOLD          : float = 0.4
    EDGE_SCALE                 : float = 1.5
    
    # Sub-metric Weights
    SUBMETRIC_WEIGHTS          : dict  = None
    
    def __post_init__(self):
        if self.SUBMETRIC_WEIGHTS is None:
            object.__setattr__(self, 'SUBMETRIC_WEIGHTS', {'smoothness_anomaly' : 0.35,
                                                           'entropy_anomaly'    : 0.25,
                                                           'contrast_anomaly'   : 0.25,
                                                           'edge_anomaly'       : 0.15,
                                                          }
                              )


# Color Analysis Parameters
@dataclass(frozen = True)
class ColorAnalysisParams:
    """
    Parameters for color distribution analysis
    """
    # Random Seed for reproducibility
    RANDOM_SEED                  : int   = 1234

    # Neutral Score 
    NEUTRAL_SCORE                : float = 0.5
    # Saturation Analysis
    SAT_HIGH_THRESHOLD           : float = 0.8
    SAT_VERY_HIGH_THRESHOLD      : float = 0.95
    SAT_MEAN_THRESHOLD           : float = 0.65
    SAT_MEAN_SCALE               : float = 3.0
    HIGH_SAT_RATIO_THRESHOLD     : float = 0.20
    HIGH_SAT_SCALE               : float = 2.5
    CLIP_RATIO_THRESHOLD         : float = 0.05
    CLIP_SCALE                   : float = 10.0
    
    # Histogram Analysis
    HISTOGRAM_BINS               : int   = 64
    HISTOGRAM_RANGE              : tuple = (0, 1)
    ROUGHNESS_THRESHOLD          : float = 0.015
    ROUGHNESS_SCALE              : float = 50.0
    CLIP_THRESHOLD               : float = 0.10
    CLIP_SCALE_FACTOR            : float = 5.0
    
    # Hue Analysis
    HUE_SAT_MASK_THRESHOLD       : float = 0.2
    HUE_MIN_PIXELS               : int   = 100
    HUE_BINS                     : int   = 36
    HUE_RANGE                    : tuple = (0, 360)
    HUE_CONCENTRATION_THRESHOLD  : float = 0.6
    HUE_CONCENTRATION_SCALE      : float = 2.5
    HUE_EMPTY_BIN_THRESHOLD      : float = 0.01
    HUE_GAP_RATIO_THRESHOLD      : float = 0.4
    HUE_GAP_SCALE                : float = 1.5
    
    # Sub-metric Weights
    SAT_SUBMETRIC_WEIGHTS        : dict  = None
    HUE_SUBMETRIC_WEIGHTS        : dict  = None
    MAIN_WEIGHTS                 : dict  = None
    
    def __post_init__(self):
        if self.SAT_SUBMETRIC_WEIGHTS is None:
            object.__setattr__(self, 'SAT_SUBMETRIC_WEIGHTS', {'mean_anomaly'     : 0.3,
                                                               'high_sat_anomaly' : 0.4,
                                                               'clip_anomaly'     : 0.3,
                                                              }
                              )

        if self.HUE_SUBMETRIC_WEIGHTS is None:
            object.__setattr__(self, 'HUE_SUBMETRIC_WEIGHTS', {'concentration_anomaly' : 0.6,
                                                               'gap_anomaly'           : 0.4,
                                                              }
                              )

        if self.MAIN_WEIGHTS is None:
            object.__setattr__(self, 'MAIN_WEIGHTS', {'saturation' : 0.4,
                                                      'histogram'  : 0.35,
                                                      'hue'        : 0.25,
                                                     }
                              )



# Singleton instances for parameter classes
GRADIENT_FIELD_PCA_PARAMS = GradientFieldPCAParams()
FREQUENCY_ANALYSIS_PARAMS = FrequencyAnalysisParams()
NOISE_ANALYSIS_PARAMS     = NoiseAnalysisParams()
TEXTURE_ANALYSIS_PARAMS   = TextureAnalysisParams()
COLOR_ANALYSIS_PARAMS     = ColorAnalysisParams()