unitfield 0.1.0__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.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 GrayJou
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,377 @@
1
+ Metadata-Version: 2.4
2
+ Name: unitfield
3
+ Version: 0.1.0
4
+ Summary: High-performance N-dimensional unit field transformations with interpolation
5
+ Author-email: GrayJou <grayjou@users.noreply.github.com>
6
+ Maintainer-email: GrayJou <grayjou@users.noreply.github.com>
7
+ License: MIT
8
+ Project-URL: Homepage, https://github.com/Grayjou/UnitField
9
+ Project-URL: Documentation, https://github.com/Grayjou/UnitField#readme
10
+ Project-URL: Repository, https://github.com/Grayjou/UnitField
11
+ Project-URL: Issues, https://github.com/Grayjou/UnitField/issues
12
+ Project-URL: Changelog, https://github.com/Grayjou/UnitField/blob/main/CHANGELOG.md
13
+ Keywords: interpolation,transformation,unit-field,computer-vision,image-processing,numpy,opencv
14
+ Classifier: Development Status :: 4 - Beta
15
+ Classifier: Intended Audience :: Developers
16
+ Classifier: Intended Audience :: Science/Research
17
+ Classifier: License :: OSI Approved :: MIT License
18
+ Classifier: Operating System :: OS Independent
19
+ Classifier: Programming Language :: Python :: 3
20
+ Classifier: Programming Language :: Python :: 3.8
21
+ Classifier: Programming Language :: Python :: 3.9
22
+ Classifier: Programming Language :: Python :: 3.10
23
+ Classifier: Programming Language :: Python :: 3.11
24
+ Classifier: Programming Language :: Python :: 3.12
25
+ Classifier: Topic :: Scientific/Engineering
26
+ Classifier: Topic :: Scientific/Engineering :: Image Processing
27
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
28
+ Classifier: Typing :: Typed
29
+ Requires-Python: >=3.8
30
+ Description-Content-Type: text/markdown
31
+ License-File: LICENSE
32
+ Requires-Dist: numpy>=1.20.0
33
+ Requires-Dist: opencv-python>=4.5.0
34
+ Requires-Dist: boundednumbers>=0.1.0
35
+ Requires-Dist: typing-extensions>=4.0.0
36
+ Provides-Extra: dev
37
+ Requires-Dist: pytest>=7.0.0; extra == "dev"
38
+ Requires-Dist: pytest-cov>=4.0.0; extra == "dev"
39
+ Requires-Dist: pytest-benchmark>=4.0.0; extra == "dev"
40
+ Requires-Dist: ruff>=0.1.0; extra == "dev"
41
+ Requires-Dist: mypy>=1.0.0; extra == "dev"
42
+ Requires-Dist: black>=23.0.0; extra == "dev"
43
+ Requires-Dist: isort>=5.12.0; extra == "dev"
44
+ Provides-Extra: docs
45
+ Requires-Dist: sphinx>=5.0.0; extra == "docs"
46
+ Requires-Dist: sphinx-rtd-theme>=1.2.0; extra == "docs"
47
+ Requires-Dist: sphinx-autodoc-typehints>=1.22.0; extra == "docs"
48
+ Provides-Extra: test
49
+ Requires-Dist: pytest>=7.0.0; extra == "test"
50
+ Requires-Dist: pytest-cov>=4.0.0; extra == "test"
51
+ Requires-Dist: pytest-benchmark>=4.0.0; extra == "test"
52
+ Dynamic: license-file
53
+
54
+ # UnitField
55
+
56
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
57
+ [![Python 3.8+](https://img.shields.io/badge/python-3.8+-blue.svg)](https://www.python.org/downloads/)
58
+
59
+ **UnitField** is a high-performance Python library for N-dimensional unit field transformations with interpolation. It provides efficient tools for mapping unit-space coordinates (values in [0, 1]) to transformed coordinates, with support for various interpolation methods and optimized backends.
60
+
61
+ ## Features
62
+
63
+ - **N-dimensional unit field transformations** with flexible interpolation
64
+ - **Multiple interpolation methods**: Nearest neighbor (Manhattan/Euclidean), Linear, Cubic, Lanczos4
65
+ - **Dual backends**: NumPy for N-dimensional fields, OpenCV for optimized 2D operations
66
+ - **2D image remapping** with endomorphism composition
67
+ - **Type-safe** with comprehensive type hints
68
+ - **Well-tested** with extensive test coverage
69
+ - **Performance optimized** with LRU caching and vectorized operations
70
+
71
+ ## Installation
72
+
73
+ ### From Source
74
+
75
+ ```bash
76
+ git clone https://github.com/Grayjou/UnitField.git
77
+ cd UnitField
78
+ pip install -e .
79
+ ```
80
+
81
+ ### Requirements
82
+
83
+ - Python >= 3.8
84
+ - NumPy >= 1.20.0
85
+ - OpenCV (cv2) >= 4.5.0
86
+ - boundednumbers >= 0.1.0
87
+ - typing-extensions >= 4.0.0
88
+
89
+ ## Quick Start
90
+
91
+ ### Basic Unit Field Usage
92
+
93
+ ```python
94
+ import numpy as np
95
+ from unitfield.core.unitfield import MappedUnitField
96
+ from unitfield.core.enums import InterpMethod
97
+
98
+ # Create a 2D unit field (5x5 grid mapping to 2D vectors)
99
+ x, y = np.meshgrid(np.linspace(0, 1, 5), np.linspace(0, 1, 5))
100
+ data = np.stack([x, y], axis=-1)
101
+
102
+ # Create the field with linear interpolation
103
+ field = MappedUnitField(data=data, interp_method=InterpMethod.LINEAR)
104
+
105
+ # Query single coordinate
106
+ result = field.get_value((0.5, 0.5))
107
+ print(f"Value at (0.5, 0.5): {result}")
108
+
109
+ # Query multiple coordinates
110
+ coords = np.array([[0.0, 0.0], [0.5, 0.5], [1.0, 1.0]])
111
+ results = field.get_values(coords)
112
+ print(f"Batch results shape: {results.shape}")
113
+ ```
114
+
115
+ ### 2D Image Remapping with Endomorphisms
116
+
117
+ ```python
118
+ import numpy as np
119
+ import cv2
120
+ from unitfield.core.unitfield import Unit2DMappedEndomorphism
121
+ from unitfield.core.enums import InterpMethod
122
+
123
+ # Create an identity endomorphism
124
+ height, width = 100, 100
125
+ xs, ys = np.meshgrid(
126
+ np.linspace(0, 1, width),
127
+ np.linspace(0, 1, height),
128
+ indexing='xy'
129
+ )
130
+ identity_data = np.stack([xs, ys], axis=-1)
131
+
132
+ # Create endomorphism with cubic interpolation
133
+ endo = Unit2DMappedEndomorphism(
134
+ data=identity_data,
135
+ interp_method=InterpMethod.CUBIC
136
+ )
137
+
138
+ # Remap an image
139
+ image = cv2.imread('input.jpg')
140
+ remapped = endo.remap(image, interpolation=cv2.INTER_LINEAR)
141
+
142
+ # Compose two endomorphisms
143
+ endo2 = Unit2DMappedEndomorphism(data=other_data)
144
+ composed = endo.compose(endo2)
145
+ ```
146
+
147
+ ## API Reference
148
+
149
+ ### Core Classes
150
+
151
+ #### `MappedUnitField`
152
+
153
+ N-dimensional unit field with interpolation.
154
+
155
+ **Parameters:**
156
+ - `data` (UnitArray): N+1 dimensional array of shape (*spatial_dims, N)
157
+ - `interp_method` (InterpMethod): Interpolation strategy (default: NEAREST_MANHATTAN)
158
+ - `cache_size` (int, optional): LRU cache size for single queries (default: 128)
159
+
160
+ **Methods:**
161
+ - `get_value(coords)`: Get value at single coordinate
162
+ - `get_values(coords_array)`: Get values at multiple coordinates
163
+ - `with_interp_method(method)`: Create copy with different interpolation
164
+
165
+ #### `Unit2DMappedEndomorphism`
166
+
167
+ 2D unit field endomorphism with optimized OpenCV backend.
168
+
169
+ **Parameters:**
170
+ - `data` (UnitArray): 3-dimensional array of shape (H, W, 2)
171
+ - `interp_method` (InterpMethod): Interpolation strategy
172
+ - `cache_size` (int, optional): LRU cache size
173
+
174
+ **Methods:**
175
+ - `get_value(coords)`: Get single coordinate value
176
+ - `get_values(coords_array)`: Get multiple coordinate values
177
+ - `rasterize_mapping(width, height)`: Convert to pixel-space mapping
178
+ - `remap(data)`: Remap arbitrary (H, W, J) array
179
+ - `compose(other)`: Compose with another endomorphism
180
+
181
+ ### Interpolation Methods
182
+
183
+ ```python
184
+ from unitfield.core.enums import InterpMethod
185
+
186
+ # Available methods:
187
+ InterpMethod.NEAREST_MANHATTAN # Nearest neighbor (Manhattan distance)
188
+ InterpMethod.NEAREST_EUCLIDEAN # Nearest neighbor (Euclidean distance)
189
+ InterpMethod.LINEAR # Linear/bilinear interpolation
190
+ InterpMethod.CUBIC # Cubic/bicubic interpolation
191
+ InterpMethod.LANCZOS4 # Lanczos-4 interpolation
192
+ ```
193
+
194
+ ### Utility Functions
195
+
196
+ #### `remap_tensor_cv2`
197
+
198
+ Remap arbitrary tensors using pixel-space mappings.
199
+
200
+ ```python
201
+ from unitfield.core.unitfield import remap_tensor_cv2
202
+
203
+ result = remap_tensor_cv2(
204
+ data=tensor,
205
+ mapping=pixel_mapping,
206
+ interpolation=cv2.INTER_LINEAR,
207
+ border_mode=cv2.BORDER_REPLICATE,
208
+ border_value=0.0
209
+ )
210
+ ```
211
+
212
+ ## Coordinate System
213
+
214
+ UnitField operates in **unit space** where coordinates are in the range [0, 1]:
215
+ - `0.0` represents the start of each dimension
216
+ - `1.0` represents the end of each dimension
217
+ - Coordinates are automatically scaled to array indices
218
+
219
+ ### Coordinate Constraints and Behavior
220
+
221
+ **Important Limitations:**
222
+
223
+ 1. **Infinite and NaN coordinates are NOT supported** and will produce undefined behavior. This is by design to keep the functions simple and avoid overhead:
224
+ ```python
225
+ # ❌ AVOID - undefined behavior
226
+ field.get_value((np.inf, 0.5))
227
+ field.get_value((np.nan, 0.5))
228
+ ```
229
+
230
+ 2. **Out-of-bounds coordinates** (< 0 or > 1) are handled via clipping to [0, 1] range:
231
+ ```python
232
+ # ✓ OK - will be clipped to valid range
233
+ field.get_value((-0.5, 1.5)) # Treated as (0.0, 1.0)
234
+ ```
235
+
236
+ 3. **Why this design?**
237
+ - Unit field transformations are intended for normalized coordinate spaces
238
+ - Checking for inf/NaN on every coordinate adds unnecessary overhead
239
+ - Out-of-bounds handling beyond [0, 1] is simple to implement externally if needed
240
+ - Keeps the core functions fast and focused
241
+
242
+ **Best Practices:**
243
+ - Validate coordinates before passing to UnitField methods if they may contain special values
244
+ - For out-of-bounds behavior beyond simple clipping, preprocess coordinates externally
245
+
246
+ ## Examples
247
+
248
+ ### Creating Different Field Types
249
+
250
+ ```python
251
+ # 1D field
252
+ data_1d = np.linspace(0, 1, 100).reshape(-1, 1)
253
+ field_1d = MappedUnitField(data=data_1d, interp_method=InterpMethod.LINEAR)
254
+
255
+ # 3D field
256
+ data_3d = np.random.rand(10, 10, 10, 3)
257
+ field_3d = MappedUnitField(data=data_3d, interp_method=InterpMethod.CUBIC)
258
+ ```
259
+
260
+ ### Switching Interpolation Methods
261
+
262
+ ```python
263
+ # Create field with one method
264
+ field = MappedUnitField(data=data, interp_method=InterpMethod.LINEAR)
265
+
266
+ # Switch to another method
267
+ cubic_field = field.with_interp_method(InterpMethod.CUBIC)
268
+ ```
269
+
270
+ ### Batch Processing
271
+
272
+ ```python
273
+ # Process large batches efficiently
274
+ batch_size = 1000
275
+ coords = np.random.rand(batch_size, 2)
276
+ results = field.get_values(coords)
277
+ ```
278
+
279
+ ### Image Warping Example
280
+
281
+ ```python
282
+ import numpy as np
283
+ import cv2
284
+ from unitfield.core.unitfield import Unit2DMappedEndomorphism
285
+
286
+ # Create a simple distortion field (barrel distortion)
287
+ h, w = 256, 256
288
+ y, x = np.ogrid[:h, :w]
289
+ center_x, center_y = w / 2, h / 2
290
+
291
+ # Calculate distance from center
292
+ dx = (x - center_x) / center_x
293
+ dy = (y - center_y) / center_y
294
+ r = np.sqrt(dx**2 + dy**2)
295
+
296
+ # Apply barrel distortion
297
+ distortion = 1 + 0.3 * r**2
298
+ new_x = center_x + dx * distortion * center_x
299
+ new_y = center_y + dy * distortion * center_y
300
+
301
+ # Normalize to unit space
302
+ unit_x = new_x / (w - 1)
303
+ unit_y = new_y / (h - 1)
304
+ distortion_field = np.stack([unit_x, unit_y], axis=-1).astype(np.float32)
305
+
306
+ # Create endomorphism and apply
307
+ endo = Unit2DMappedEndomorphism(data=distortion_field)
308
+ image = cv2.imread('input.jpg')
309
+ warped = endo.remap(image)
310
+ cv2.imwrite('output.jpg', warped)
311
+ ```
312
+
313
+ ## Performance Tips
314
+
315
+ 1. **Use caching for repeated queries**: Set appropriate `cache_size` when creating fields
316
+ 2. **Batch operations**: Use `get_values()` instead of multiple `get_value()` calls
317
+ 3. **Choose the right backend**: Use `Unit2DMappedEndomorphism` for 2D operations (faster via OpenCV)
318
+ 4. **Appropriate interpolation**: Nearest neighbor is fastest, cubic/Lanczos are slower but smoother
319
+
320
+ ## Development
321
+
322
+ ### Running Tests
323
+
324
+ ```bash
325
+ pip install pytest pytest-benchmark
326
+ pytest tests/ -v
327
+ ```
328
+
329
+ ### Code Style
330
+
331
+ This project follows modern Python conventions:
332
+ - PEP 8 style guide
333
+ - Type hints throughout
334
+ - Comprehensive docstrings (Google style)
335
+
336
+ ## Known Limitations
337
+
338
+ 1. **Inf/NaN coordinates**: Not supported in remapping functions (see Coordinate Constraints section)
339
+ 2. **Memory usage**: Large N-dimensional fields may consume significant memory
340
+ 3. **2D optimization**: Only 2D endomorphisms benefit from OpenCV backend optimization
341
+
342
+ ## Contributing
343
+
344
+ Contributions are welcome! Please:
345
+ 1. Fork the repository
346
+ 2. Create a feature branch
347
+ 3. Add tests for new functionality
348
+ 4. Ensure all tests pass
349
+ 5. Submit a pull request
350
+
351
+ ## License
352
+
353
+ This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
354
+
355
+ ## Citation
356
+
357
+ If you use UnitField in your research, please cite:
358
+
359
+ ```bibtex
360
+ @software{unitfield2025,
361
+ author = {GrayJou},
362
+ title = {UnitField: N-dimensional Unit Field Transformations},
363
+ year = {2025},
364
+ url = {https://github.com/Grayjou/UnitField}
365
+ }
366
+ ```
367
+
368
+ ## Acknowledgments
369
+
370
+ - Built with NumPy and OpenCV
371
+ - Inspired by coordinate transformation needs in computer vision and graphics
372
+
373
+ ## Support
374
+
375
+ For issues, questions, or contributions, please visit:
376
+ - **Issues**: https://github.com/Grayjou/UnitField/issues
377
+ - **Discussions**: https://github.com/Grayjou/UnitField/discussions