Spaces:
Running
Running
File size: 2,024 Bytes
9875bf8 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 | """Preprocessing utilities for satellite imagery."""
import numpy as np
import cv2
from typing import Optional
def preprocess_image(
image: np.ndarray,
target_size: Optional[tuple] = None,
normalize: bool = True
) -> np.ndarray:
"""
Preprocess a satellite image for model input.
Args:
image: Input image (H, W, C), uint8 or float
target_size: Optional (width, height) to resize to
normalize: If True, output is float32 in [0, 1]
Returns:
Preprocessed image as float32 [0,1] or uint8 [0,255]
"""
if image is None:
raise ValueError("Input image is None")
img = image.copy()
# Ensure 3-channel
if img.ndim == 2:
img = np.stack([img, img, img], axis=-1)
elif img.shape[2] == 1:
img = np.concatenate([img, img, img], axis=-1)
elif img.shape[2] > 3:
img = img[:, :, :3]
# Resize if requested
if target_size is not None:
img = cv2.resize(img, target_size, interpolation=cv2.INTER_LINEAR)
# Normalise
if normalize:
if img.dtype == np.uint8:
img = img.astype(np.float32) / 255.0
else:
img = np.clip(img, 0, 1).astype(np.float32)
else:
if img.dtype != np.uint8:
img = (np.clip(img, 0, 1) * 255).astype(np.uint8)
return img
def mask_clouds(
image: np.ndarray,
cloud_mask: np.ndarray,
fill_value: float = 0.0
) -> np.ndarray:
"""
Apply cloud mask to image, replacing cloud pixels with fill_value.
Args:
image: Input image (H, W, C)
cloud_mask: Binary mask (H, W), 1 = cloud
fill_value: Value to fill masked pixels with
Returns:
Masked image same dtype as input
"""
masked = image.copy().astype(np.float32)
mask_bool = cloud_mask.astype(bool)
for c in range(masked.shape[2]):
masked[:, :, c][mask_bool] = fill_value
if image.dtype == np.uint8:
masked = np.clip(masked, 0, 255).astype(np.uint8)
return masked
|