ai / frequency_analysis.py
maddyrox's picture
Upload 23 files
245a4de verified
Raw
History Blame Contribute Delete
3.76 kB
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 ""