import numpy as np from scipy.ndimage import gaussian_filter def extract_gaze_sequence( saliency: np.ndarray, num_fixations: int = 5, inhibition_radius_fraction: float = 0.1, ) -> list[dict]: """ Extract predicted fixation sequence using iterative peak finding with inhibition-of-return. """ sal = saliency.copy().astype(np.float64) h, w = sal.shape inhibition_radius = int(max(h, w) * inhibition_radius_fraction) fixations = [] for rank in range(1, num_fixations + 1): smoothed = gaussian_filter(sal, sigma=max(h, w) * 0.01) if smoothed.max() < 1e-10: break peak_idx = np.unravel_index(np.argmax(smoothed), smoothed.shape) y, x = int(peak_idx[0]), int(peak_idx[1]) prob = float(saliency[y, x]) fixations.append({ "rank": rank, "x": x, "y": y, "x_pct": round(x / w * 100, 1), "y_pct": round(y / h * 100, 1), "probability": round(prob, 4), }) # Inhibition of return yy, xx = np.ogrid[:h, :w] mask = (xx - x) ** 2 + (yy - y) ** 2 <= inhibition_radius ** 2 sal[mask] = 0.0 return fixations