THE CODE READER / PYTHON

verify_cv.py

Your snippet, in context. Explore the file or visualize its recorded example.

Download raw .py ↓
Complete file
PYTHON / LINE NUMBERS
  1"""Run: python verify_cv.py. No downloads, GPU, or training required."""
  2from __future__ import annotations
  3
  4from collections.abc import Callable
  5import json
  6import platform
  7
  8import cv2
  9import numpy as np
 10import scipy
 11from scipy.ndimage import distance_transform_edt
 12from scipy.spatial.distance import directed_hausdorff
 13
 14from cv_channels import FloatImage, channel_planes, channel_statistics, alpha_example, composite_over, srgb_to_linear, linear_to_srgb
 15from cv_arrays import pixel_demo, to_unit_rgb, model_input
 16from cv_masks import scene, threshold_mask, clean_mask
 17from cv_metrics import Mask, boundary, directed_distances, hausdorff, metric_cases, overlap
 18
 19
 20def rejects(run: Callable[[], object]) -> None:
 21    try:
 22        run()
 23    except ValueError:
 24        return
 25    raise AssertionError("Expected input contract rejection")
 26
 27
 28def slow_boundary(mask: Mask) -> Mask:
 29    """Independent Python neighbor check, with outside-image background."""
 30    result: Mask = np.zeros_like(mask)
 31    height, width = mask.shape
 32    for row in range(height):
 33        for col in range(width):
 34            if not mask[row, col]:
 35                continue
 36            for dr, dc in [(-1, 0), (1, 0), (0, -1), (0, 1)]:
 37                rr, cc = row + dr, col + dc
 38                if not (0 <= rr < height and 0 <= cc < width) or not mask[rr, cc]:
 39                    result[row, col] = True
 40                    break
 41    return result
 42
 43
 44def check_channels() -> None:
 45    bgr, rgb, _ = pixel_demo()
 46    red, green, blue, rebuilt = channel_planes(rgb)
 47    np.testing.assert_array_equal(rebuilt, rgb)
 48    np.testing.assert_array_equal(red, [[255,0],[0,90]])
 49    red[0,0] = 0
 50    assert rgb[0,0,0] == 255
 51    unit = to_unit_rgb(bgr)
 52    averages, pixels, mask, selected = channel_statistics(unit)
 53    np.testing.assert_allclose(averages, np.array([345,315,285]) / 1020, rtol=1e-6)
 54    np.testing.assert_allclose(pixels, np.array([[1/3,1/3],[1/3,60/255]], dtype=np.float32), rtol=1e-6)
 55    np.testing.assert_array_equal(mask, [[True,False],[False,True]])
 56    expected = unit.copy(); expected[0,1] = 0; expected[1,0] = 0
 57    np.testing.assert_array_equal(selected, expected)
 58    f, b, a = alpha_example()
 59    actual = composite_over(f,b,a)
 60    np.testing.assert_allclose(actual, np.array([[[0,0,1],[.25,0,.75],[.5,0,.5],[1,0,0]]], dtype=np.float32))
 61    # Independent scalar oracle on non-square random inputs.
 62    rng = np.random.default_rng(21)
 63    fg: FloatImage = rng.random((3,5,3), dtype=np.float32)
 64    bg: FloatImage = rng.random((3,5,3), dtype=np.float32)
 65    opacity: FloatImage = rng.random((3,5,1), dtype=np.float32)
 66    oracle: FloatImage = np.zeros_like(fg)
 67    for row in range(3):
 68        for col in range(5):
 69            for channel in range(3):
 70                weight = float(opacity[row,col,0])
 71                oracle[row,col,channel] = weight * float(fg[row,col,channel]) + (1-weight) * float(bg[row,col,channel])
 72    np.testing.assert_allclose(composite_over(fg,bg,opacity), oracle, atol=1e-7)
 73    np.testing.assert_array_equal(composite_over(fg,bg,np.zeros_like(opacity)), bg)
 74    np.testing.assert_array_equal(composite_over(fg,bg,np.ones_like(opacity)), fg)
 75    rejects(lambda: composite_over(fg,bg,opacity[:1]))
 76    rejects(lambda: composite_over(fg,bg,-np.ones_like(opacity)))
 77    rejects(lambda: composite_over(fg,bg,np.full_like(opacity,np.nan)))
 78    rejects(lambda: channel_planes(rgb.astype(np.float32)))
 79    np.testing.assert_allclose(srgb_to_linear(linear_to_srgb(fg)),fg,atol=3e-7)
 80    np.testing.assert_allclose(linear_to_srgb(srgb_to_linear(fg)),fg,atol=3e-7)
 81    np.testing.assert_allclose(linear_to_srgb(np.full((1,1,3),.5,dtype=np.float32)),.73535698,atol=1e-7)
 82    np.testing.assert_allclose(srgb_to_linear(np.full((1,1,3),.04045,dtype=np.float32)),.04045/12.92,atol=1e-8)
 83    print("PASS: channel planes, axis meanings, selection, alpha endpoints, scalar compositing oracle, color transfer and invalid contracts")
 84
 85
 86def check() -> None:
 87    check_channels()
 88    bgr, rgb, crop = pixel_demo()
 89    assert rgb[0, 0].tolist() == [255, 0, 0]
 90    assert rgb[1, 1].tolist() == [90, 60, 30] and crop[0, 0].tolist() == [0, 60, 30]
 91    assert not np.shares_memory(crop, rgb)
 92    batch = model_input(to_unit_rgb(bgr))
 93    assert batch.shape == (1, 3, 2, 2) and batch.flags.c_contiguous
 94    np.testing.assert_allclose(batch[0, :, 1, 1], [90/255, 60/255, 30/255])
 95    rejects(lambda: to_unit_rgb(bgr.astype(np.float32)))
 96    rejects(lambda: model_input(rgb.astype(np.float32)))
 97    gray, target = scene()
 98    raw = threshold_mask(gray)
 99    closed, cleaned = clean_mask(raw)
100    assert raw.sum() == 36 and target.sum() == 36
101    assert not raw[5, 5] and raw[1, 1]
102    np.testing.assert_array_equal(cleaned, target)
103    edge_values = np.array([[99, 100, 101]], dtype=np.uint8)
104    np.testing.assert_array_equal(threshold_mask(edge_values), [[False, False, True]])
105    # Cleaning is not universally safe: a legitimate single-pixel object vanishes.
106    thin = np.zeros((7, 7), dtype=np.bool_)
107    thin[3, 3] = True
108    assert not clean_mask(thin)[1].any()
109    results: dict[str, dict[str, float | str]] = {}
110    for name, (pred, truth) in metric_cases().items():
111        iou, dice = overlap(pred, truth)
112        hd, hd95 = hausdorff(pred, truth)
113        np.testing.assert_allclose(dice, 2 * iou / (1 + iou))
114        np.testing.assert_allclose(overlap(pred, truth), overlap(truth, pred))
115        np.testing.assert_allclose(hausdorff(pred, truth), hausdorff(truth, pred))
116        if pred.any() and truth.any():
117            ap, at = np.argwhere(boundary(pred)), np.argwhere(boundary(truth))
118            oracle = max(directed_hausdorff(ap, at)[0], directed_hausdorff(at, ap)[0])
119            np.testing.assert_allclose(hd, oracle)
120        results[name] = dict(zip(("iou", "dice", "hd", "hd95"),
121                                [float(v) if np.isfinite(v) else "infinity" for v in (iou, dice, hd, hd95)]))
122    np.testing.assert_allclose([float(value) for value in results["shifted"].values()], [5/7, 5/6, 1, 1])
123    np.testing.assert_allclose([float(value) for value in results["outlier"].values()], [36/37, 72/73, np.sqrt(18), 0])
124    assert results["both-empty"] == dict(iou=1.0, dice=1.0, hd=0.0, hd95=0.0)
125    assert results["one-empty"] == dict(iou=0.0, dice=0.0, hd="infinity", hd95="infinity")
126    # Spacing follows (row,column): a one-column shift is 3 units, not 2.
127    p = np.zeros((5, 5), dtype=np.bool_); t = p.copy()
128    p[2, 2] = True; t[2, 3] = True
129    np.testing.assert_allclose(hausdorff(p, t, (2.0, 3.0)), [3, 3])
130    rejects(lambda: hausdorff(p, t, (0.0, 1.0)))
131    rejects(lambda: overlap(p, t[:2]))
132    rejects(lambda: overlap(p.astype(np.uint8), t))
133    # Independent EDT oracle on random masks, anisotropic and unit spacing.
134    rng = np.random.default_rng(17)
135    for _ in range(24):
136        p, t = rng.random((2, 9, 11)) > 0.65
137        np.testing.assert_array_equal(boundary(p), slow_boundary(p))
138        for spacing in [(1.0, 1.0), (2.0, 0.7)]:
139            ref = distance_transform_edt(~slow_boundary(t), sampling=spacing)[slow_boundary(p)]
140            np.testing.assert_allclose(directed_distances(p, t, spacing), ref)
141    full = np.ones((4, 4), dtype=np.bool_)
142    np.testing.assert_array_equal(boundary(full), slow_boundary(full))
143    print(json.dumps({"environment": {"python": platform.python_version(), "numpy": np.__version__,
144          "opencv": cv2.__version__, "scipy": scipy.__version__}, "cases": results}, indent=2))
145    print("PASS: image/layout contracts; threshold equality; cleaning success/failure; six metric cases; symmetry; spacing; SciPy HD and 48 EDT comparisons")
146
147
148if __name__ == "__main__":
149    check()