evaluators 2.1.0__tar.gz → 2.1.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. {evaluators-2.1.0 → evaluators-2.1.1}/PKG-INFO +2 -1
  2. {evaluators-2.1.0 → evaluators-2.1.1}/pyproject.toml +2 -1
  3. evaluators-2.1.1/sources/evaluators/memory/utils/encoding.py +148 -0
  4. evaluators-2.1.0/sources/evaluators/memory/utils/encoding.py +0 -102
  5. {evaluators-2.1.0 → evaluators-2.1.1}/README.md +0 -0
  6. {evaluators-2.1.0 → evaluators-2.1.1}/sources/evaluators/__init__.py +0 -0
  7. {evaluators-2.1.0 → evaluators-2.1.1}/sources/evaluators/_engine.py +0 -0
  8. {evaluators-2.1.0 → evaluators-2.1.1}/sources/evaluators/_streams.py +0 -0
  9. {evaluators-2.1.0 → evaluators-2.1.1}/sources/evaluators/cli/__main__.py +0 -0
  10. {evaluators-2.1.0 → evaluators-2.1.1}/sources/evaluators/cli/memory.py +0 -0
  11. {evaluators-2.1.0 → evaluators-2.1.1}/sources/evaluators/constants.py +0 -0
  12. {evaluators-2.1.0 → evaluators-2.1.1}/sources/evaluators/integrations/lightning.py +0 -0
  13. {evaluators-2.1.0 → evaluators-2.1.1}/sources/evaluators/memory/__init__.py +0 -0
  14. {evaluators-2.1.0 → evaluators-2.1.1}/sources/evaluators/memory/encoded_memmap/__init__.py +0 -0
  15. {evaluators-2.1.0 → evaluators-2.1.1}/sources/evaluators/memory/encoded_memmap/_reader.py +0 -0
  16. {evaluators-2.1.0 → evaluators-2.1.1}/sources/evaluators/memory/encoded_memmap/_writer.py +0 -0
  17. {evaluators-2.1.0 → evaluators-2.1.1}/sources/evaluators/memory/interfaces.py +0 -0
  18. {evaluators-2.1.0 → evaluators-2.1.1}/sources/evaluators/memory/lmdb/__init__.py +0 -0
  19. {evaluators-2.1.0 → evaluators-2.1.1}/sources/evaluators/memory/lmdb/_reader.py +0 -0
  20. {evaluators-2.1.0 → evaluators-2.1.1}/sources/evaluators/memory/lmdb/_writer.py +0 -0
  21. {evaluators-2.1.0 → evaluators-2.1.1}/sources/evaluators/memory/memmap/__init__.py +0 -0
  22. {evaluators-2.1.0 → evaluators-2.1.1}/sources/evaluators/memory/memmap/_buffers.py +0 -0
  23. {evaluators-2.1.0 → evaluators-2.1.1}/sources/evaluators/memory/memmap/_reader.py +0 -0
  24. {evaluators-2.1.0 → evaluators-2.1.1}/sources/evaluators/memory/memmap/_writer.py +0 -0
  25. {evaluators-2.1.0 → evaluators-2.1.1}/sources/evaluators/memory/schema.py +0 -0
  26. {evaluators-2.1.0 → evaluators-2.1.1}/sources/evaluators/metrics/__init__.py +0 -0
  27. {evaluators-2.1.0 → evaluators-2.1.1}/sources/evaluators/metrics/adapters/coco.py +0 -0
  28. {evaluators-2.1.0 → evaluators-2.1.1}/sources/evaluators/metrics/adapters/trackeval.py +0 -0
  29. {evaluators-2.1.0 → evaluators-2.1.1}/sources/evaluators/metrics/domain/depth.py +0 -0
  30. {evaluators-2.1.0 → evaluators-2.1.1}/sources/evaluators/metrics/domain/dvps.py +0 -0
  31. {evaluators-2.1.0 → evaluators-2.1.1}/sources/evaluators/metrics/domain/segmentation/__init__.py +0 -0
  32. {evaluators-2.1.0 → evaluators-2.1.1}/sources/evaluators/metrics/domain/segmentation/_utils.py +0 -0
  33. {evaluators-2.1.0 → evaluators-2.1.1}/sources/evaluators/metrics/domain/segmentation/panoptic.py +0 -0
  34. {evaluators-2.1.0 → evaluators-2.1.1}/sources/evaluators/metrics/domain/segmentation/semantic.py +0 -0
  35. {evaluators-2.1.0 → evaluators-2.1.1}/sources/evaluators/metrics/domain/step.py +0 -0
  36. {evaluators-2.1.0 → evaluators-2.1.1}/sources/evaluators/metrics/domain/tracking.py +0 -0
  37. {evaluators-2.1.0 → evaluators-2.1.1}/sources/evaluators/metrics/stats.py +0 -0
  38. {evaluators-2.1.0 → evaluators-2.1.1}/sources/evaluators/presets/__init__.py +0 -0
  39. {evaluators-2.1.0 → evaluators-2.1.1}/sources/evaluators/presets/cityscapes.py +0 -0
  40. {evaluators-2.1.0 → evaluators-2.1.1}/sources/evaluators/presets/kitti.py +0 -0
  41. {evaluators-2.1.0 → evaluators-2.1.1}/sources/evaluators/presets/semkitti.py +0 -0
  42. {evaluators-2.1.0 → evaluators-2.1.1}/sources/evaluators/scheduling/__init__.py +0 -0
  43. {evaluators-2.1.0 → evaluators-2.1.1}/sources/evaluators/scheduling/_catalog.py +0 -0
  44. {evaluators-2.1.0 → evaluators-2.1.1}/sources/evaluators/scheduling/_partitioner.py +0 -0
  45. {evaluators-2.1.0 → evaluators-2.1.1}/sources/evaluators/types.py +0 -0
  46. {evaluators-2.1.0 → evaluators-2.1.1}/sources/evaluators/utils/comms.py +0 -0
  47. {evaluators-2.1.0 → evaluators-2.1.1}/sources/evaluators/utils/tensor_ops.py +0 -0
  48. {evaluators-2.1.0 → evaluators-2.1.1}/sources/evaluators/visuals/__init__.py +0 -0
  49. {evaluators-2.1.0 → evaluators-2.1.1}/sources/evaluators/visuals/metric.py +0 -0
  50. {evaluators-2.1.0 → evaluators-2.1.1}/sources/evaluators/visuals/tools/__init__.py +0 -0
  51. {evaluators-2.1.0 → evaluators-2.1.1}/sources/evaluators/visuals/tools/_visualizer.py +0 -0
  52. {evaluators-2.1.0 → evaluators-2.1.1}/sources/evaluators/visuals/tools/transform.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: evaluators
3
- Version: 2.1.0
3
+ Version: 2.1.1
4
4
  Summary: Various scene understanding and perception evaluation metrics.
5
5
  Author: Kurt Stolle
6
6
  Author-email: Kurt Stolle <kurt@computer.org>
@@ -27,6 +27,7 @@ Requires-Dist: lmdb
27
27
  Requires-Dist: tifffile
28
28
  Requires-Dist: pydantic
29
29
  Requires-Dist: opencv-python>=4.13.0.92
30
+ Requires-Dist: imagecodecs>=2026.3.6
30
31
  Requires-Dist: lightning>=2.6.1 ; extra == 'lightning'
31
32
  Requires-Python: >=3.13, <3.14
32
33
  Provides-Extra: lightning
@@ -4,7 +4,7 @@ build-backend = "uv_build"
4
4
 
5
5
  [project]
6
6
  name = "evaluators"
7
- version = "2.1.0"
7
+ version = "2.1.1"
8
8
  description = "Various scene understanding and perception evaluation metrics."
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.13, <3.14"
@@ -35,6 +35,7 @@ dependencies = [
35
35
  "tifffile",
36
36
  "pydantic",
37
37
  "opencv-python>=4.13.0.92",
38
+ "imagecodecs>=2026.3.6",
38
39
  ]
39
40
 
40
41
  [project.optional-dependencies]
@@ -0,0 +1,148 @@
1
+ """
2
+ Serialization Layer for LMDB Backend.
3
+ =====================================
4
+
5
+ Provides functional registries to convert PyTorch tensors to bytes (and back)
6
+ using image-specific codecs (PNG, TIFF) and generic raw formats.
7
+ """
8
+
9
+ import functools
10
+
11
+ import io
12
+ from typing import Callable, Literal
13
+
14
+ import numpy as np
15
+ import tifffile
16
+ import torch
17
+ import torchvision.io
18
+
19
+ __all__ = [
20
+ "decode_png",
21
+ "decode_raw",
22
+ "decode_tiff",
23
+ "encode_png",
24
+ "encode_raw",
25
+ "encode_tiff",
26
+ ]
27
+
28
+
29
+ def encode_png(tensor: torch.Tensor) -> bytes:
30
+ """
31
+ Encode a tensor to PNG.
32
+
33
+ Expects (C, H, W) shape and uint8 dtype.
34
+ """
35
+ if tensor.ndim != 3:
36
+ msg = (
37
+ f"Expected 3D tensor (C, H, W) for PNG encoding, got shape: {tensor.shape}"
38
+ )
39
+ raise ValueError(msg)
40
+ if tensor.dtype != torch.uint8:
41
+ msg = f"Expected uint8 dtype for PNG encoding, got: {tensor.dtype}"
42
+ raise ValueError(msg)
43
+
44
+ encoded = torchvision.io.encode_png(tensor.cpu())
45
+ # encode_png returns a 1D uint8 tensor. Get bytes.
46
+ return encoded.numpy().tobytes()
47
+
48
+
49
+ def decode_png(data: bytes, device: torch.device | None = None) -> torch.Tensor:
50
+ """
51
+ Decode PNG bytes back to a tensor.
52
+ """
53
+ # Try decode_image which auto-detects
54
+ t_1d = torch.frombuffer(bytearray(data), dtype=torch.uint8)
55
+ tensor = torchvision.io.decode_image(
56
+ t_1d, mode=torchvision.io.ImageReadMode.UNCHANGED
57
+ )
58
+ if device is not None:
59
+ tensor = tensor.to(device)
60
+ return tensor
61
+
62
+
63
+ def encode_tiff(tensor: torch.Tensor, **kwargs) -> bytes:
64
+ """
65
+ Encode a tensor to TIFF format using ``tifffile``.
66
+
67
+ Suitable for depth maps.
68
+ """
69
+ if tensor.ndim != 3:
70
+ msg = (
71
+ f"Expected 3D tensor (C, H, W) for TIFF encoding, got shape: {tensor.shape}"
72
+ )
73
+ raise ValueError(msg)
74
+
75
+ # Determine `imwrite` parameters based on dtype
76
+ if len(kwargs) > 0:
77
+ write = functools.partial(tifffile.imwrite, **kwargs)
78
+ elif tensor.is_floating_point():
79
+ # Assume depth maps, use LERC compression with a small error threshold of 1mm
80
+ write = functools.partial(
81
+ tifffile.imwrite,
82
+ compression="lerc",
83
+ compressionargs={"level": 0.001},
84
+ )
85
+ else:
86
+ # Assume segmentation masks
87
+ write = functools.partial(
88
+ tifffile.imwrite, compression="zstd", compressionargs={"level": 3}
89
+ )
90
+
91
+ # Permute to (H, W, C), remove channel if C=1, then move to CPU and convert to numpy
92
+ arr = tensor.permute(1, 2, 0).squeeze(-1).cpu().numpy()
93
+
94
+ # Ensure C-order
95
+ arr = np.ascontiguousarray(arr)
96
+
97
+ # Write to an in-memory buffer and get bytes
98
+ with io.BytesIO() as buf:
99
+ write(buf, arr, **kwargs)
100
+ return buf.getvalue()
101
+
102
+
103
+ def decode_tiff(data: bytes, device: torch.device | None = None) -> torch.Tensor:
104
+ """
105
+ Decode TIFF bytes back to a tensor.
106
+
107
+ Returns a tensor in (C, H, W) format.
108
+ """
109
+ with io.BytesIO(data) as buf:
110
+ arr = tifffile.imread(buf)
111
+
112
+ # tifffile returns numpy array, convert to tensor
113
+ tensor = torch.from_numpy(arr)
114
+
115
+ # Convert (H, W) to (H, W, 1) if single-channel
116
+ if tensor.ndim == 2:
117
+ tensor.unsqueeze_(-1)
118
+
119
+ # Permute back to (C, H, W)
120
+ tensor = tensor.permute(2, 0, 1)
121
+
122
+ # Move to device if specified
123
+ if device is not None:
124
+ tensor = tensor.to(device)
125
+
126
+ # Ensure contiguous memory for better performance in downstream processing
127
+ return tensor.contiguous()
128
+
129
+
130
+ def encode_raw(tensor: torch.Tensor) -> bytes:
131
+ """
132
+ Generic raw serialization using PyTorch's native save (uses zip/pickle).
133
+ Good for small metadata like sequence_ids or unsupported large tensors.
134
+ """
135
+ with io.BytesIO() as buf:
136
+ torch.save(tensor.cpu(), buf)
137
+ return buf.getvalue()
138
+
139
+
140
+ def decode_raw(data: bytes, device: torch.device | None = None) -> torch.Tensor:
141
+ """
142
+ Decode generic raw bytes.
143
+ """
144
+ with io.BytesIO(data) as buf:
145
+ tensor = torch.load(buf, weights_only=True)
146
+ if device is not None:
147
+ tensor = tensor.to(device)
148
+ return tensor
@@ -1,102 +0,0 @@
1
- """
2
- Serialization Layer for LMDB Backend.
3
- =====================================
4
-
5
- Provides functional registries to convert PyTorch tensors to bytes (and back)
6
- using image-specific codecs (PNG, TIFF) and generic raw formats.
7
- """
8
-
9
- import io
10
- from typing import Callable, Literal
11
-
12
- import numpy as np
13
- import tifffile
14
- import torch
15
- import torchvision.io
16
-
17
- __all__ = [
18
- "encode_png",
19
- "decode_png",
20
- "encode_tiff",
21
- "decode_tiff",
22
- "encode_raw",
23
- "decode_raw",
24
- ]
25
-
26
-
27
- def encode_png(tensor: torch.Tensor) -> bytes:
28
- """
29
- Encodes a tensor to PNG.
30
- Expects (C, H, W) or (H, W). If uint8 is not the dtype, it casts (assumes categorical mask).
31
- """
32
- if tensor.ndim == 2:
33
- tensor = tensor.unsqueeze(0)
34
- if tensor.dtype != torch.uint8:
35
- # Warning: For segmentation masks, values > 255 will be clipped if not handled carefully,
36
- # but typically panoptic ids or labels are packed, or we only support uint8 for png.
37
- # Actually, PNG can support 16-bit. torchvision's encode_png only supports uint8.
38
- # If >255, we should probably fall back to raw or use a different encoder.
39
- if tensor.max() > 255:
40
- return encode_raw(tensor)
41
- tensor = tensor.to(torch.uint8)
42
-
43
- encoded = torchvision.io.encode_png(tensor.cpu())
44
- # encode_png returns a 1D uint8 tensor. Get bytes.
45
- return encoded.numpy().tobytes()
46
-
47
-
48
- def decode_png(data: bytes, device: torch.device | None = None) -> torch.Tensor:
49
- """
50
- Decodes PNG bytes back to a tensor.
51
- """
52
- # Try decode_image which auto-detects
53
- t_1d = torch.frombuffer(bytearray(data), dtype=torch.uint8)
54
- tensor = torchvision.io.decode_image(t_1d, mode=torchvision.io.ImageReadMode.UNCHANGED)
55
- if device is not None:
56
- tensor = tensor.to(device)
57
- return tensor
58
-
59
-
60
- def encode_tiff(tensor: torch.Tensor) -> bytes:
61
- """
62
- Encodes a tensor to TIFF format using tifffile. Suitable for depth maps.
63
- """
64
- arr = tensor.cpu().numpy()
65
- with io.BytesIO() as buf:
66
- tifffile.imwrite(buf, arr)
67
- return buf.getvalue()
68
-
69
-
70
- def decode_tiff(data: bytes, device: torch.device | None = None) -> torch.Tensor:
71
- """
72
- Decodes TIFF bytes back to a tensor.
73
- """
74
- with io.BytesIO(data) as buf:
75
- arr = tifffile.imread(buf)
76
-
77
- # tifffile returns numpy array, convert to tensor
78
- tensor = torch.from_numpy(arr)
79
- if device is not None:
80
- tensor = tensor.to(device)
81
- return tensor
82
-
83
-
84
- def encode_raw(tensor: torch.Tensor) -> bytes:
85
- """
86
- Generic raw serialization using PyTorch's native save (uses zip/pickle).
87
- Good for small metadata like sequence_ids or unsupported large tensors.
88
- """
89
- with io.BytesIO() as buf:
90
- torch.save(tensor.cpu(), buf)
91
- return buf.getvalue()
92
-
93
-
94
- def decode_raw(data: bytes, device: torch.device | None = None) -> torch.Tensor:
95
- """
96
- Decodes generic raw bytes.
97
- """
98
- with io.BytesIO(data) as buf:
99
- tensor = torch.load(buf, weights_only=True)
100
- if device is not None:
101
- tensor = tensor.to(device)
102
- return tensor
File without changes