File size: 3,755 Bytes
6361699
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
import numpy as np
import numpy as np
from PIL import Image, ImageFilter, ImageOps
import io
import base64

class FrequencyAnalyzer:
    def __init__(self):
        pass

    def generate_spectrum(self, image: Image.Image) -> str:
        """

        Generates a 2D Frequency Spectrum (Magnitude Plot) from a PIL Image.

        Returns a base64 encoded PNG string of the spectrum.

        """
        try:
            # 1. Convert to Grayscale
            img_gray = image.convert('L')
            
            # 2. Convert to Numpy Array
            img_array = np.array(img_gray)
            
            # 3. Compute FFT (Fast Fourier Transform)
            # f = np.fft.fft2(img_array)
            # fshift = np.fft.fftshift(f)
            # magnitude_spectrum = 20 * np.log(np.abs(fshift))
             
            # Use a slightly more robust method for visualization
            f = np.fft.fft2(img_array)
            fshift = np.fft.fftshift(f)
            # Add epsilon to avoid log(0)
            magnitude_spectrum = 20 * np.log(np.abs(fshift) + 1e-9)

            # 4. Normalize to 0-255 for standard image display
            mag_min = magnitude_spectrum.min()
            mag_max = magnitude_spectrum.max()
            
            # Avoid division by zero if image is blank
            if mag_max == mag_min:
                normalized = np.zeros_like(magnitude_spectrum, dtype=np.uint8)
            else:
                normalized = 255 * (magnitude_spectrum - mag_min) / (mag_max - mag_min)
                normalized = np.uint8(normalized)

            # 5. Convert back to PIL Image
            spectrum_img = Image.fromarray(normalized)

            # 6. Encode to Base64
            buffered = io.BytesIO()
            spectrum_img.save(buffered, format="PNG")
            img_str = base64.b64encode(buffered.getvalue()).decode("utf-8")
            
            return img_str
            
        except Exception as e:
            print(f"Error generating frequency spectrum: {e}")
            return ""

    def generate_pattern_map(self, image: Image.Image) -> str:
        """

        Generates a Noise Pattern Map (High-Pass/Laplacian) to visualize

        checkerboard artifacts.

        """
        try:
            # 1. Convert to Grayscale
            img_gray = image.convert('L')
            
            # 2. Apply Laplacian Filter (High-Pass)
            # This removes smooth areas and keeps edges/noise
            noise_map = img_gray.filter(ImageFilter.FIND_EDGES) 
            # Note: FIND_EDGES is a simple approximation. For better grid visualization,
            # we can use a Kernel, but this is usually sufficient for "seeing" the grid.
            
            # 3. Invert to make lines black on white (easier to see)
            # noise_map = ImageOps.invert(noise_map)
            # Actually, white on black (default) effectively shows the "glowing" grid lines.
            
            # 4. Enhance Contrast/Brightness to make faint artifacts visible
            # We convert to numpy to scale
            arr = np.array(noise_map).astype(float)
            
            # Amplify
            arr = arr * 5.0 # Boost signal
            arr = np.clip(arr, 0, 255).astype(np.uint8)
            
            enhanced_map = Image.fromarray(arr)
            
            # 5. Encode
            buffered = io.BytesIO()
            enhanced_map.save(buffered, format="PNG")
            img_str = base64.b64encode(buffered.getvalue()).decode("utf-8")
            
            return img_str
            
        except Exception as e:
            print(f"Error generating pattern map: {e}")
            return ""