Spaces:
Running
Running
Update app.py
Browse files
app.py
CHANGED
|
@@ -70,16 +70,24 @@ def normalise_sar(sar5: np.ndarray) -> np.ndarray:
|
|
| 70 |
stds = np.array(cfg.SAR_STDS, dtype=np.float32).reshape(5, 1, 1)
|
| 71 |
return (sar5 - means) / (stds + 1e-8)
|
| 72 |
|
| 73 |
-
def load_jrc_channel(img_path: Path, shape: tuple) -> np.ndarray:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 74 |
stem = img_path.stem.replace("_image", "")
|
| 75 |
mask_path = cfg.JRC_DIR / f"{stem}_waterbody.tif"
|
| 76 |
if mask_path.exists():
|
| 77 |
with rasterio.open(mask_path) as src:
|
| 78 |
mask = src.read(1).astype(np.float32)
|
| 79 |
mask[mask > 1] = 0.0
|
| 80 |
-
|
| 81 |
-
|
| 82 |
-
|
|
|
|
| 83 |
|
| 84 |
# βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 85 |
# MODEL ARCHITECTURE
|
|
@@ -295,11 +303,13 @@ def sliding_window_predict(model, image_tensor, crop=224, stride=112, device="cu
|
|
| 295 |
|
| 296 |
def predict_image(model, img_path: Path, device="cuda"):
|
| 297 |
raw = read_tif(img_path)
|
| 298 |
-
opt = normalise_optical(raw)
|
| 299 |
-
|
|
|
|
| 300 |
img = torch.from_numpy(np.concatenate([opt, sar, jrc], axis=0)).float()
|
| 301 |
return sliding_window_predict(model, img, cfg.IMG_SIZE, cfg.INFER_STRIDE, device).cpu().numpy()
|
| 302 |
|
|
|
|
| 303 |
def mask_to_rle(mask: np.ndarray) -> str:
|
| 304 |
flat = mask.flatten(order="F").astype(np.uint8)
|
| 305 |
if flat.max() == 0: return "0 0"
|
|
|
|
| 70 |
stds = np.array(cfg.SAR_STDS, dtype=np.float32).reshape(5, 1, 1)
|
| 71 |
return (sar5 - means) / (stds + 1e-8)
|
| 72 |
|
| 73 |
+
def load_jrc_channel(img_path: Path, shape: tuple, raw: np.ndarray = None) -> np.ndarray:
|
| 74 |
+
# Priority 1: embedded as band 7 in the uploaded TIF
|
| 75 |
+
if raw is not None and raw.shape[0] >= 7:
|
| 76 |
+
mask = raw[6].copy()
|
| 77 |
+
mask[mask > 1] = 0.0
|
| 78 |
+
return mask[np.newaxis]
|
| 79 |
+
|
| 80 |
+
# Priority 2: separate *_waterbody.tif on disk
|
| 81 |
stem = img_path.stem.replace("_image", "")
|
| 82 |
mask_path = cfg.JRC_DIR / f"{stem}_waterbody.tif"
|
| 83 |
if mask_path.exists():
|
| 84 |
with rasterio.open(mask_path) as src:
|
| 85 |
mask = src.read(1).astype(np.float32)
|
| 86 |
mask[mask > 1] = 0.0
|
| 87 |
+
return mask[np.newaxis]
|
| 88 |
+
|
| 89 |
+
# Fallback: zeros
|
| 90 |
+
return np.zeros((1, *shape), dtype=np.float32)
|
| 91 |
|
| 92 |
# βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 93 |
# MODEL ARCHITECTURE
|
|
|
|
| 303 |
|
| 304 |
def predict_image(model, img_path: Path, device="cuda"):
|
| 305 |
raw = read_tif(img_path)
|
| 306 |
+
opt = normalise_optical(raw[:6]) # always use first 6 bands for optical
|
| 307 |
+
sar = normalise_sar(compute_sar_features(raw[:6]))
|
| 308 |
+
jrc = load_jrc_channel(img_path, raw.shape[1:], raw) # pass raw for embedded check
|
| 309 |
img = torch.from_numpy(np.concatenate([opt, sar, jrc], axis=0)).float()
|
| 310 |
return sliding_window_predict(model, img, cfg.IMG_SIZE, cfg.INFER_STRIDE, device).cpu().numpy()
|
| 311 |
|
| 312 |
+
|
| 313 |
def mask_to_rle(mask: np.ndarray) -> str:
|
| 314 |
flat = mask.flatten(order="F").astype(np.uint8)
|
| 315 |
if flat.max() == 0: return "0 0"
|