shuishen
10 hours ago fbb068ec702338d609c1ca6eddbdb9f182d8f211
capabilities/00-change-detection/scan_change_detection_parameters.py
@@ -34,7 +34,7 @@
    return cleaned, count - 1
def preview(image: np.ndarray, mask: np.ndarray, max_dimension: int = 720) -> Image.Image:
def preview(image: np.ndarray, mask: np.ndarray, generic_mask: np.ndarray | None = None, max_dimension: int = 720) -> Image.Image:
    height, width = image.shape[:2]
    scale = min(1.0, max_dimension / max(height, width))
    size = (max(1, int(round(width * scale))), max(1, int(round(height * scale))))
@@ -42,6 +42,13 @@
    small_mask = Image.fromarray((mask > 0).astype(np.uint8) * 255).resize(size, Image.Resampling.NEAREST)
    base_array = np.asarray(base).copy()
    mask_array = np.asarray(small_mask) > 0
    if generic_mask is not None:
        small_generic = Image.fromarray((generic_mask > 0).astype(np.uint8) * 255).resize(size, Image.Resampling.NEAREST)
        generic_array = np.asarray(small_generic) > 0
        cyan = np.zeros_like(base_array)
        cyan[..., 1] = 220
        cyan[..., 2] = 255
        base_array[generic_array] = (base_array[generic_array].astype(np.float32) * 0.45 + cyan[generic_array].astype(np.float32) * 0.55).astype(np.uint8)
    red = np.zeros_like(base_array)
    red[..., 0] = 255
    base_array[mask_array] = (base_array[mask_array].astype(np.float32) * 0.45 + red[mask_array].astype(np.float32) * 0.55).astype(np.uint8)
@@ -60,6 +67,11 @@
        crs = probability_dataset.crs.to_string() if probability_dataset.crs else None
    with rasterio.open(input_path) as input_dataset:
        image = np.transpose(input_dataset.read([1, 2, 3]), (1, 2, 0))
    generic_path = run_dir / "generic_difference_mask.tif"
    generic_mask = None
    if generic_path.is_file():
        with rasterio.open(generic_path) as generic_dataset:
            generic_mask = generic_dataset.read(1) > 0
    output_dir.mkdir(parents=True, exist_ok=False)
    rows: list[dict] = []
    contact_items: list[tuple[str, Image.Image]] = []
@@ -78,7 +90,7 @@
            # polygons are expensive and are not needed to compare thresholds.
            features = demo._feature_summary(cleaned, probability, transform, crs is not None)
            (item_dir / "regions.json").write_text(json.dumps({"features": features}, ensure_ascii=False, indent=2), encoding="utf-8")
            overlay = preview(image, cleaned)
            overlay = preview(image, cleaned, generic_mask)
            overlay.save(item_dir / "overlay_preview.jpg", quality=90)
            row = {
                "threshold": threshold,