THE CODE READER / PYTHON
Download raw .py ↓verify_cv.py
Your snippet, in context. Explore the file or visualize its recorded example.
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()