File size: 1,066 Bytes
0e39d80
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
import cv2
import numpy as np

from ml_utils.confidence import FFT_MAX


def fft_anomaly_score(image_bgr: np.ndarray) -> tuple[float, list[str]]:
    flags = []
    gray = cv2.cvtColor(image_bgr, cv2.COLOR_BGR2GRAY)
    h, w = gray.shape
    block = 64
    variances = []

    for y in range(0, h - block, block):
        for x in range(0, w - block, block):
            patch = gray[y : y + block, x : x + block].astype(np.float32)
            f = np.fft.fft2(patch)
            fshift = np.fft.fftshift(f)
            magnitude = np.log(np.abs(fshift) + 1)
            variances.append(float(np.var(magnitude)))

    if len(variances) < 2:
        return FFT_MAX * 0.5, flags

    mean_v = np.mean(variances)
    std_v = np.std(variances)
    cv = std_v / (mean_v + 1e-6)

    if cv > 0.45:
        flags.append("FFT_ANOMALY_HIGH")
        score = max(5.0, FFT_MAX - (cv - 0.45) * 45)
    elif cv > 0.25:
        score = FFT_MAX - (cv - 0.25) * 37.5
    else:
        score = (FFT_MAX - 5.0) + (0.25 - cv) * 15

    return float(np.clip(score, 0, FFT_MAX)), flags