# /// script # requires-python = ">=3.10" # dependencies = ["numpy"] # /// """ @effect threshold @version 1.0.0 @author artdag @description Threshold effect. Converts to high-contrast black and white. Creates stark, graphic look by converting grayscale to pure black/white based on a threshold value. @param level int @range 0 255 @default 128 Threshold level. Pixels above = white, below = black. @param invert bool @default false Swap black and white. @param color_mode string @enum bw color @default bw Output mode: - bw: pure black and white - color: keep original colors where above threshold @example (effect threshold :level 100) @example ;; Beat-reactive threshold (effect threshold :level (bind bass :range [80 180]) :invert true) """ import numpy as np def process_frame(frame: np.ndarray, params: dict, state: dict) -> tuple: """ Apply threshold effect to a video frame. Args: frame: Input frame as numpy array (H, W, 3) RGB uint8 params: Effect parameters - level: threshold 0-255 (default 128) - invert: swap black/white (default False) - color_mode: bw or color (default bw) state: Persistent state dict Returns: Tuple of (processed_frame, new_state) """ level = int(np.clip(params.get("level", 128), 0, 255)) invert = params.get("invert", False) color_mode = params.get("color_mode", "bw") if state is None: state = {} # Convert to grayscale for threshold comparison if len(frame.shape) == 3: gray = np.mean(frame, axis=2) else: gray = frame # Apply threshold mask = gray > level if invert: mask = ~mask if color_mode == "bw": # Pure black and white result = np.where(mask[:, :, np.newaxis], 255, 0).astype(np.uint8) if len(frame.shape) == 3: result = np.repeat(result, frame.shape[2], axis=2) else: # Keep original colors where above threshold result = np.where(mask[:, :, np.newaxis], frame, 0).astype(np.uint8) return result, state