Spaces:
Sleeping
Sleeping
| import numpy as np | |
| from app.preprocessing.base import PreprocessingStep, PreprocessingContext, PreprocessingError | |
| class NormalizeStep(PreprocessingStep): | |
| name = "normalize" | |
| description = "Normalize pixel values using imagenet stats, minmax, or standard scaling" | |
| version = "1.0.0" | |
| order = 5 | |
| enabled = True | |
| required = False | |
| async def process(self, ctx: PreprocessingContext, params: dict) -> PreprocessingContext: | |
| if ctx.image is None: | |
| raise PreprocessingError("No image to normalize — decode step must run first") | |
| method = params.get("method", "imagenet") | |
| arr = np.array(ctx.image, dtype=np.float32) | |
| if method == "imagenet": | |
| mean = np.array(params.get("mean", [0.485, 0.456, 0.406]), dtype=np.float32) | |
| std = np.array(params.get("std", [0.229, 0.224, 0.225]), dtype=np.float32) | |
| arr = arr / 255.0 | |
| if arr.ndim == 3 and arr.shape[2] == 3: | |
| arr = (arr - mean) / std | |
| elif arr.ndim == 2: | |
| arr = (arr - mean[0]) / std[0] | |
| elif method == "minmax": | |
| arr = arr / 255.0 | |
| elif method == "standard": | |
| mean_val = arr.mean() | |
| std_val = arr.std() | |
| if std_val > 0: | |
| arr = (arr - mean_val) / std_val | |
| elif method == "none": | |
| pass | |
| ctx.image_array = arr | |
| pixel_min = float(arr.min()) | |
| pixel_max = float(arr.max()) | |
| ctx.step_outputs["normalize"] = { | |
| "method": method, | |
| "shape": list(arr.shape), | |
| "dtype": str(arr.dtype), | |
| "pixel_range": [round(pixel_min, 4), round(pixel_max, 4)], | |
| } | |
| return ctx | |