Aluode's picture
Upload folder using huggingface_hub
3bb804c verified
"""
iFFT Cochlea Node - Reconstructs an image from a complex spectrum.
Based on the hardwired iFFTCochleaNode from anttis_perception_laboratory.py
Requires: pip install scipy
Place this file in the 'nodes' folder
"""
import numpy as np
from PyQt6 import QtGui
import cv2
# --- !! CRITICAL IMPORT BLOCK !! ---
import __main__
BaseNode = __main__.BaseNode
QtGui = __main__.QtGui
PA_INSTANCE = getattr(__main__, "PA_INSTANCE", None)
# -----------------------------------
try:
from scipy.fft import irfft
SCIPY_AVAILABLE = True
except ImportError:
SCIPY_AVAILABLE = False
print("Warning: iFFTCochleaNode requires 'scipy'.")
print("Please run: pip install scipy")
class iFFTCochleaNode(BaseNode):
"""
Performs an Inverse Real FFT on a complex spectrum (from FFTCochleaNode)
to reconstruct a 2D image.
"""
NODE_CATEGORY = "Transform"
NODE_COLOR = QtGui.QColor(200, 100, 60)
def __init__(self, height=120, width=160):
super().__init__()
self.node_title = "iFFT Cochlea"
self.inputs = {'complex_spectrum': 'complex_spectrum'}
self.outputs = {'image': 'image'}
self.h, self.w = height, width
self.reconstructed_img = np.zeros((self.h, self.w), dtype=np.float32)
def step(self):
if not SCIPY_AVAILABLE:
return
complex_spec = self.get_blended_input('complex_spectrum', 'mean')
if complex_spec is not None and complex_spec.ndim == 2:
try:
# Perform inverse real FFT
img = irfft(complex_spec, axis=1).astype(np.float32)
# Resize to target output size (just in case)
self.reconstructed_img = cv2.resize(img, (self.w, self.h))
# Normalize for viewing (0-1)
min_v, max_v = np.min(self.reconstructed_img), np.max(self.reconstructed_img)
if (max_v - min_v) > 1e-6:
self.reconstructed_img = (self.reconstructed_img - min_v) / (max_v - min_v)
else:
self.reconstructed_img.fill(0.5)
except Exception as e:
print(f"iFFT Error: {e}")
self.reconstructed_img.fill(0.0)
else:
# Fade to black if no input
self.reconstructed_img *= 0.9
def get_output(self, port_name):
if port_name == 'image':
return self.reconstructed_img
return None
def get_display_image(self):
img_u8 = (np.clip(self.reconstructed_img, 0, 1) * 255).astype(np.uint8)
img_u8 = np.ascontiguousarray(img_u8)
return QtGui.QImage(img_u8.data, self.w, self.h, self.w, QtGui.QImage.Format.Format_Grayscale8)
def get_config_options(self):
return [
("Height", "height", self.h, None),
("Width", "width", self.w, None)
]