camera-client 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.
- camera_client-0.1.0/LICENSE +21 -0
- camera_client-0.1.0/MANIFEST.in +3 -0
- camera_client-0.1.0/PKG-INFO +284 -0
- camera_client-0.1.0/README.md +255 -0
- camera_client-0.1.0/camera_client/__init__.py +3 -0
- camera_client-0.1.0/camera_client/client.py +305 -0
- camera_client-0.1.0/camera_client/loading.py +84 -0
- camera_client-0.1.0/camera_client/utils.py +178 -0
- camera_client-0.1.0/camera_client.egg-info/PKG-INFO +284 -0
- camera_client-0.1.0/camera_client.egg-info/SOURCES.txt +16 -0
- camera_client-0.1.0/camera_client.egg-info/dependency_links.txt +1 -0
- camera_client-0.1.0/camera_client.egg-info/entry_points.txt +2 -0
- camera_client-0.1.0/camera_client.egg-info/requires.txt +1 -0
- camera_client-0.1.0/camera_client.egg-info/top_level.txt +1 -0
- camera_client-0.1.0/pyproject.toml +48 -0
- camera_client-0.1.0/requirements.txt +3 -0
- camera_client-0.1.0/setup.cfg +4 -0
- camera_client-0.1.0/setup.py +5 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Alexandr
|
|
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,284 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: camera-client
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Python SDK for camera calibration projection data - transform between distorted, corrected, and world coordinates.
|
|
5
|
+
Author-email: Alexander Abramov <extremal.ru@gmail.com>
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/avabr/camera-client
|
|
8
|
+
Project-URL: Repository, https://github.com/avabr/camera-client
|
|
9
|
+
Project-URL: Issues, https://github.com/avabr/camera-client/issues
|
|
10
|
+
Keywords: camera,calibration,projection,3d,mathematics
|
|
11
|
+
Classifier: Development Status :: 3 - Alpha
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: Intended Audience :: Science/Research
|
|
14
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.7
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
22
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
23
|
+
Classifier: Topic :: Scientific/Engineering :: Mathematics
|
|
24
|
+
Requires-Python: >=3.7
|
|
25
|
+
Description-Content-Type: text/markdown
|
|
26
|
+
License-File: LICENSE
|
|
27
|
+
Requires-Dist: numpy>=1.20.0
|
|
28
|
+
Dynamic: license-file
|
|
29
|
+
|
|
30
|
+
# camera-client
|
|
31
|
+
|
|
32
|
+
Python SDK for camera calibration and projection transformations. Transform coordinates between distorted image space, corrected image space, and real-world 3D coordinates using pre-computed calibration data.
|
|
33
|
+
|
|
34
|
+
## Features
|
|
35
|
+
|
|
36
|
+
- **Vectorized operations** - Process multiple points simultaneously for high performance
|
|
37
|
+
- **Multiple coordinate systems** - Transform between source (distorted), corrected, and ground (3D world) coordinates
|
|
38
|
+
- **Lens distortion handling** - Correct for camera lens distortion using calibration lookup tables
|
|
39
|
+
- **Ground plane projection** - Project image coordinates to 3D world coordinates and vice versa
|
|
40
|
+
- **NumPy-based** - Fast array operations with minimal dependencies
|
|
41
|
+
|
|
42
|
+
## Installation
|
|
43
|
+
|
|
44
|
+
Install from PyPI:
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
pip install camera-client
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## Quick Start
|
|
51
|
+
|
|
52
|
+
```python
|
|
53
|
+
import numpy as np
|
|
54
|
+
from camera_client import CameraProjection
|
|
55
|
+
|
|
56
|
+
# Load camera calibration data from NPZ archive
|
|
57
|
+
camera = CameraProjection.load("camera_calibration.npz")
|
|
58
|
+
|
|
59
|
+
# Transform single or multiple points (vectorized operations)
|
|
60
|
+
source_points = np.array([
|
|
61
|
+
[100, 200],
|
|
62
|
+
[300, 400],
|
|
63
|
+
[500, 600]
|
|
64
|
+
])
|
|
65
|
+
|
|
66
|
+
# Remove lens distortion
|
|
67
|
+
corrected_points = camera.src_to_ctd(source_points)
|
|
68
|
+
|
|
69
|
+
# Project to ground plane (height = 0)
|
|
70
|
+
ground_points = camera.src_to_gnd(source_points, h=0)
|
|
71
|
+
print(ground_points) # Returns (N, 3) array with [x, y, z] coordinates
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
## Coordinate Systems
|
|
75
|
+
|
|
76
|
+
This library handles transformations between three coordinate systems:
|
|
77
|
+
|
|
78
|
+
- **src** (Source): Distorted image coordinates from the camera
|
|
79
|
+
- **ctd** (Corrected): Undistorted image coordinates after lens correction
|
|
80
|
+
- **gnd** (Ground): Real-world 3D coordinates (x, y, z)
|
|
81
|
+
|
|
82
|
+
```
|
|
83
|
+
Distorted Undistorted World 3D
|
|
84
|
+
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
|
|
85
|
+
│ │ │ │ │ │
|
|
86
|
+
│ Source (src) │ <──> │ Corrected (ctd) │ <──> │ Ground (gnd) │
|
|
87
|
+
│ │ │ │ │ │
|
|
88
|
+
└─────────────────┘ └─────────────────┘ └─────────────────┘
|
|
89
|
+
Lens distortion Lens correction 3D projection
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
## Usage Examples
|
|
93
|
+
|
|
94
|
+
### Basic Coordinate Transformations
|
|
95
|
+
|
|
96
|
+
```python
|
|
97
|
+
from camera_client import CameraProjection
|
|
98
|
+
import numpy as np
|
|
99
|
+
|
|
100
|
+
# Load calibration data
|
|
101
|
+
camera = CameraProjection.load("camera_calibration.npz")
|
|
102
|
+
|
|
103
|
+
# Source (distorted) to Corrected (undistorted)
|
|
104
|
+
src_points = np.array([[640, 480], [1280, 720]])
|
|
105
|
+
ctd_points = camera.src_to_ctd(src_points)
|
|
106
|
+
|
|
107
|
+
# Corrected back to Source
|
|
108
|
+
src_points_back = camera.ctd_to_src(ctd_points)
|
|
109
|
+
|
|
110
|
+
# Check round-trip accuracy
|
|
111
|
+
error = np.linalg.norm(src_points - src_points_back, axis=1)
|
|
112
|
+
print(f"Round-trip error: {error}")
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
### 3D Ground Projection
|
|
116
|
+
|
|
117
|
+
```python
|
|
118
|
+
# Project image points to ground plane
|
|
119
|
+
src_points = np.array([[640, 480], [800, 600]])
|
|
120
|
+
|
|
121
|
+
# Project to ground at height = 0 (ground level)
|
|
122
|
+
ground_points = camera.src_to_gnd(src_points, h=0)
|
|
123
|
+
print(ground_points) # Shape: (2, 3) with [x, y, z] coordinates
|
|
124
|
+
|
|
125
|
+
# Project to elevated plane (e.g., 1.5 meters above ground)
|
|
126
|
+
elevated_points = camera.src_to_gnd(src_points, h=1.5)
|
|
127
|
+
|
|
128
|
+
# Different height for each point
|
|
129
|
+
heights = np.array([0, 1.5])
|
|
130
|
+
mixed_points = camera.src_to_gnd(src_points, h=heights)
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
### Reverse Projection (3D to Image)
|
|
134
|
+
|
|
135
|
+
```python
|
|
136
|
+
# Project 3D world coordinates back to image
|
|
137
|
+
world_points = np.array([
|
|
138
|
+
[10.0, 5.0, 0.0], # x, y, z in meters
|
|
139
|
+
[15.0, 8.0, 1.5]
|
|
140
|
+
])
|
|
141
|
+
|
|
142
|
+
# Get corrected image coordinates
|
|
143
|
+
ctd_points = camera.gnd_to_ctd(world_points)
|
|
144
|
+
|
|
145
|
+
# Get source (distorted) image coordinates
|
|
146
|
+
src_points = camera.gnd_to_src(world_points)
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
### Batch Processing
|
|
150
|
+
|
|
151
|
+
```python
|
|
152
|
+
# Process large batches of points efficiently
|
|
153
|
+
num_points = 10000
|
|
154
|
+
random_points = np.random.rand(num_points, 2) * [1920, 1080]
|
|
155
|
+
|
|
156
|
+
# Vectorized transformation (fast!)
|
|
157
|
+
corrected = camera.src_to_ctd(random_points)
|
|
158
|
+
ground = camera.src_to_gnd(random_points, h=0)
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
### Accessing Camera Properties
|
|
162
|
+
|
|
163
|
+
```python
|
|
164
|
+
# Get camera dimensions
|
|
165
|
+
print(f"Image size: {camera.im_width} x {camera.im_height}")
|
|
166
|
+
print(f"Image WH: {camera.im_wh_size}")
|
|
167
|
+
print(f"Plan scale: {camera.plan_scale}")
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
## API Reference
|
|
171
|
+
|
|
172
|
+
### `CameraProjection.load(archive_path)`
|
|
173
|
+
|
|
174
|
+
Load camera calibration from NPZ file.
|
|
175
|
+
|
|
176
|
+
**Parameters:**
|
|
177
|
+
- `archive_path` (str): Path to .npz calibration archive
|
|
178
|
+
|
|
179
|
+
**Returns:**
|
|
180
|
+
- `CameraProjection` instance
|
|
181
|
+
|
|
182
|
+
---
|
|
183
|
+
|
|
184
|
+
### `src_to_ctd(points)`
|
|
185
|
+
|
|
186
|
+
Transform from source (distorted) to corrected coordinates.
|
|
187
|
+
|
|
188
|
+
**Parameters:**
|
|
189
|
+
- `points` (np.ndarray): Shape (N, 2) array of [x, y] coordinates
|
|
190
|
+
|
|
191
|
+
**Returns:**
|
|
192
|
+
- `np.ndarray`: Shape (N, 2) corrected coordinates
|
|
193
|
+
|
|
194
|
+
---
|
|
195
|
+
|
|
196
|
+
### `ctd_to_src(points)`
|
|
197
|
+
|
|
198
|
+
Transform from corrected to source (distorted) coordinates.
|
|
199
|
+
|
|
200
|
+
**Parameters:**
|
|
201
|
+
- `points` (np.ndarray): Shape (N, 2) array of [x, y] coordinates
|
|
202
|
+
|
|
203
|
+
**Returns:**
|
|
204
|
+
- `np.ndarray`: Shape (N, 2) source coordinates
|
|
205
|
+
|
|
206
|
+
---
|
|
207
|
+
|
|
208
|
+
### `src_to_gnd(points, h)`
|
|
209
|
+
|
|
210
|
+
Transform from source coordinates to 3D ground coordinates.
|
|
211
|
+
|
|
212
|
+
**Parameters:**
|
|
213
|
+
- `points` (np.ndarray): Shape (N, 2) array of [x, y] coordinates
|
|
214
|
+
- `h` (float or np.ndarray): Height(s) above ground. Scalar or shape (N,) array
|
|
215
|
+
|
|
216
|
+
**Returns:**
|
|
217
|
+
- `np.ndarray`: Shape (N, 3) ground coordinates [x, y, z]
|
|
218
|
+
|
|
219
|
+
---
|
|
220
|
+
|
|
221
|
+
### `gnd_to_src(points)`
|
|
222
|
+
|
|
223
|
+
Transform from 3D ground coordinates to source coordinates.
|
|
224
|
+
|
|
225
|
+
**Parameters:**
|
|
226
|
+
- `points` (np.ndarray): Shape (N, 3) array of [x, y, z] coordinates
|
|
227
|
+
|
|
228
|
+
**Returns:**
|
|
229
|
+
- `np.ndarray`: Shape (N, 2) source coordinates
|
|
230
|
+
|
|
231
|
+
---
|
|
232
|
+
|
|
233
|
+
### `ctd_to_gnd(points, h)`
|
|
234
|
+
|
|
235
|
+
Transform from corrected coordinates to 3D ground coordinates.
|
|
236
|
+
|
|
237
|
+
**Parameters:**
|
|
238
|
+
- `points` (np.ndarray): Shape (N, 2) array of [x, y] coordinates
|
|
239
|
+
- `h` (float or np.ndarray): Height(s) above ground
|
|
240
|
+
|
|
241
|
+
**Returns:**
|
|
242
|
+
- `np.ndarray`: Shape (N, 3) ground coordinates
|
|
243
|
+
|
|
244
|
+
---
|
|
245
|
+
|
|
246
|
+
### `gnd_to_ctd(points)`
|
|
247
|
+
|
|
248
|
+
Transform from 3D ground coordinates to corrected coordinates.
|
|
249
|
+
|
|
250
|
+
**Parameters:**
|
|
251
|
+
- `points` (np.ndarray): Shape (N, 3) array of [x, y, z] coordinates
|
|
252
|
+
|
|
253
|
+
**Returns:**
|
|
254
|
+
- `np.ndarray`: Shape (N, 2) corrected coordinates
|
|
255
|
+
|
|
256
|
+
## Calibration File Format
|
|
257
|
+
|
|
258
|
+
The calibration file is a NumPy `.npz` archive containing:
|
|
259
|
+
|
|
260
|
+
- `src2ctd`: Lookup table for source to corrected transformation (H x W x 2)
|
|
261
|
+
- `ctd2src`: Lookup table for corrected to source transformation (H x W x 2)
|
|
262
|
+
- `x_gnd`, `y_gnd`, `z_gnd`: Expression strings for corrected to ground transformation
|
|
263
|
+
- `x_im`, `y_im`: Expression strings for ground to corrected transformation
|
|
264
|
+
- `im_width`, `im_height`: Image dimensions
|
|
265
|
+
- `plan_scale`: Scale factor for ground plane
|
|
266
|
+
|
|
267
|
+
## Requirements
|
|
268
|
+
|
|
269
|
+
- Python >= 3.7
|
|
270
|
+
- NumPy >= 1.20.0
|
|
271
|
+
|
|
272
|
+
## Links
|
|
273
|
+
|
|
274
|
+
- **Repository**: [https://github.com/avabr/camera-client](https://github.com/avabr/camera-client)
|
|
275
|
+
- **Issues**: [https://github.com/avabr/camera-client/issues](https://github.com/avabr/camera-client/issues)
|
|
276
|
+
- **PyPI**: [https://pypi.org/project/camera-client/](https://pypi.org/project/camera-client/)
|
|
277
|
+
|
|
278
|
+
## License
|
|
279
|
+
|
|
280
|
+
MIT License - see [LICENSE](LICENSE) file for details.
|
|
281
|
+
|
|
282
|
+
## Author
|
|
283
|
+
|
|
284
|
+
Alexander Abramov ([extremal.ru@gmail.com](mailto:extremal.ru@gmail.com))
|
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
# camera-client
|
|
2
|
+
|
|
3
|
+
Python SDK for camera calibration and projection transformations. Transform coordinates between distorted image space, corrected image space, and real-world 3D coordinates using pre-computed calibration data.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- **Vectorized operations** - Process multiple points simultaneously for high performance
|
|
8
|
+
- **Multiple coordinate systems** - Transform between source (distorted), corrected, and ground (3D world) coordinates
|
|
9
|
+
- **Lens distortion handling** - Correct for camera lens distortion using calibration lookup tables
|
|
10
|
+
- **Ground plane projection** - Project image coordinates to 3D world coordinates and vice versa
|
|
11
|
+
- **NumPy-based** - Fast array operations with minimal dependencies
|
|
12
|
+
|
|
13
|
+
## Installation
|
|
14
|
+
|
|
15
|
+
Install from PyPI:
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
pip install camera-client
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Quick Start
|
|
22
|
+
|
|
23
|
+
```python
|
|
24
|
+
import numpy as np
|
|
25
|
+
from camera_client import CameraProjection
|
|
26
|
+
|
|
27
|
+
# Load camera calibration data from NPZ archive
|
|
28
|
+
camera = CameraProjection.load("camera_calibration.npz")
|
|
29
|
+
|
|
30
|
+
# Transform single or multiple points (vectorized operations)
|
|
31
|
+
source_points = np.array([
|
|
32
|
+
[100, 200],
|
|
33
|
+
[300, 400],
|
|
34
|
+
[500, 600]
|
|
35
|
+
])
|
|
36
|
+
|
|
37
|
+
# Remove lens distortion
|
|
38
|
+
corrected_points = camera.src_to_ctd(source_points)
|
|
39
|
+
|
|
40
|
+
# Project to ground plane (height = 0)
|
|
41
|
+
ground_points = camera.src_to_gnd(source_points, h=0)
|
|
42
|
+
print(ground_points) # Returns (N, 3) array with [x, y, z] coordinates
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## Coordinate Systems
|
|
46
|
+
|
|
47
|
+
This library handles transformations between three coordinate systems:
|
|
48
|
+
|
|
49
|
+
- **src** (Source): Distorted image coordinates from the camera
|
|
50
|
+
- **ctd** (Corrected): Undistorted image coordinates after lens correction
|
|
51
|
+
- **gnd** (Ground): Real-world 3D coordinates (x, y, z)
|
|
52
|
+
|
|
53
|
+
```
|
|
54
|
+
Distorted Undistorted World 3D
|
|
55
|
+
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
|
|
56
|
+
│ │ │ │ │ │
|
|
57
|
+
│ Source (src) │ <──> │ Corrected (ctd) │ <──> │ Ground (gnd) │
|
|
58
|
+
│ │ │ │ │ │
|
|
59
|
+
└─────────────────┘ └─────────────────┘ └─────────────────┘
|
|
60
|
+
Lens distortion Lens correction 3D projection
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## Usage Examples
|
|
64
|
+
|
|
65
|
+
### Basic Coordinate Transformations
|
|
66
|
+
|
|
67
|
+
```python
|
|
68
|
+
from camera_client import CameraProjection
|
|
69
|
+
import numpy as np
|
|
70
|
+
|
|
71
|
+
# Load calibration data
|
|
72
|
+
camera = CameraProjection.load("camera_calibration.npz")
|
|
73
|
+
|
|
74
|
+
# Source (distorted) to Corrected (undistorted)
|
|
75
|
+
src_points = np.array([[640, 480], [1280, 720]])
|
|
76
|
+
ctd_points = camera.src_to_ctd(src_points)
|
|
77
|
+
|
|
78
|
+
# Corrected back to Source
|
|
79
|
+
src_points_back = camera.ctd_to_src(ctd_points)
|
|
80
|
+
|
|
81
|
+
# Check round-trip accuracy
|
|
82
|
+
error = np.linalg.norm(src_points - src_points_back, axis=1)
|
|
83
|
+
print(f"Round-trip error: {error}")
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
### 3D Ground Projection
|
|
87
|
+
|
|
88
|
+
```python
|
|
89
|
+
# Project image points to ground plane
|
|
90
|
+
src_points = np.array([[640, 480], [800, 600]])
|
|
91
|
+
|
|
92
|
+
# Project to ground at height = 0 (ground level)
|
|
93
|
+
ground_points = camera.src_to_gnd(src_points, h=0)
|
|
94
|
+
print(ground_points) # Shape: (2, 3) with [x, y, z] coordinates
|
|
95
|
+
|
|
96
|
+
# Project to elevated plane (e.g., 1.5 meters above ground)
|
|
97
|
+
elevated_points = camera.src_to_gnd(src_points, h=1.5)
|
|
98
|
+
|
|
99
|
+
# Different height for each point
|
|
100
|
+
heights = np.array([0, 1.5])
|
|
101
|
+
mixed_points = camera.src_to_gnd(src_points, h=heights)
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
### Reverse Projection (3D to Image)
|
|
105
|
+
|
|
106
|
+
```python
|
|
107
|
+
# Project 3D world coordinates back to image
|
|
108
|
+
world_points = np.array([
|
|
109
|
+
[10.0, 5.0, 0.0], # x, y, z in meters
|
|
110
|
+
[15.0, 8.0, 1.5]
|
|
111
|
+
])
|
|
112
|
+
|
|
113
|
+
# Get corrected image coordinates
|
|
114
|
+
ctd_points = camera.gnd_to_ctd(world_points)
|
|
115
|
+
|
|
116
|
+
# Get source (distorted) image coordinates
|
|
117
|
+
src_points = camera.gnd_to_src(world_points)
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
### Batch Processing
|
|
121
|
+
|
|
122
|
+
```python
|
|
123
|
+
# Process large batches of points efficiently
|
|
124
|
+
num_points = 10000
|
|
125
|
+
random_points = np.random.rand(num_points, 2) * [1920, 1080]
|
|
126
|
+
|
|
127
|
+
# Vectorized transformation (fast!)
|
|
128
|
+
corrected = camera.src_to_ctd(random_points)
|
|
129
|
+
ground = camera.src_to_gnd(random_points, h=0)
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
### Accessing Camera Properties
|
|
133
|
+
|
|
134
|
+
```python
|
|
135
|
+
# Get camera dimensions
|
|
136
|
+
print(f"Image size: {camera.im_width} x {camera.im_height}")
|
|
137
|
+
print(f"Image WH: {camera.im_wh_size}")
|
|
138
|
+
print(f"Plan scale: {camera.plan_scale}")
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
## API Reference
|
|
142
|
+
|
|
143
|
+
### `CameraProjection.load(archive_path)`
|
|
144
|
+
|
|
145
|
+
Load camera calibration from NPZ file.
|
|
146
|
+
|
|
147
|
+
**Parameters:**
|
|
148
|
+
- `archive_path` (str): Path to .npz calibration archive
|
|
149
|
+
|
|
150
|
+
**Returns:**
|
|
151
|
+
- `CameraProjection` instance
|
|
152
|
+
|
|
153
|
+
---
|
|
154
|
+
|
|
155
|
+
### `src_to_ctd(points)`
|
|
156
|
+
|
|
157
|
+
Transform from source (distorted) to corrected coordinates.
|
|
158
|
+
|
|
159
|
+
**Parameters:**
|
|
160
|
+
- `points` (np.ndarray): Shape (N, 2) array of [x, y] coordinates
|
|
161
|
+
|
|
162
|
+
**Returns:**
|
|
163
|
+
- `np.ndarray`: Shape (N, 2) corrected coordinates
|
|
164
|
+
|
|
165
|
+
---
|
|
166
|
+
|
|
167
|
+
### `ctd_to_src(points)`
|
|
168
|
+
|
|
169
|
+
Transform from corrected to source (distorted) coordinates.
|
|
170
|
+
|
|
171
|
+
**Parameters:**
|
|
172
|
+
- `points` (np.ndarray): Shape (N, 2) array of [x, y] coordinates
|
|
173
|
+
|
|
174
|
+
**Returns:**
|
|
175
|
+
- `np.ndarray`: Shape (N, 2) source coordinates
|
|
176
|
+
|
|
177
|
+
---
|
|
178
|
+
|
|
179
|
+
### `src_to_gnd(points, h)`
|
|
180
|
+
|
|
181
|
+
Transform from source coordinates to 3D ground coordinates.
|
|
182
|
+
|
|
183
|
+
**Parameters:**
|
|
184
|
+
- `points` (np.ndarray): Shape (N, 2) array of [x, y] coordinates
|
|
185
|
+
- `h` (float or np.ndarray): Height(s) above ground. Scalar or shape (N,) array
|
|
186
|
+
|
|
187
|
+
**Returns:**
|
|
188
|
+
- `np.ndarray`: Shape (N, 3) ground coordinates [x, y, z]
|
|
189
|
+
|
|
190
|
+
---
|
|
191
|
+
|
|
192
|
+
### `gnd_to_src(points)`
|
|
193
|
+
|
|
194
|
+
Transform from 3D ground coordinates to source coordinates.
|
|
195
|
+
|
|
196
|
+
**Parameters:**
|
|
197
|
+
- `points` (np.ndarray): Shape (N, 3) array of [x, y, z] coordinates
|
|
198
|
+
|
|
199
|
+
**Returns:**
|
|
200
|
+
- `np.ndarray`: Shape (N, 2) source coordinates
|
|
201
|
+
|
|
202
|
+
---
|
|
203
|
+
|
|
204
|
+
### `ctd_to_gnd(points, h)`
|
|
205
|
+
|
|
206
|
+
Transform from corrected coordinates to 3D ground coordinates.
|
|
207
|
+
|
|
208
|
+
**Parameters:**
|
|
209
|
+
- `points` (np.ndarray): Shape (N, 2) array of [x, y] coordinates
|
|
210
|
+
- `h` (float or np.ndarray): Height(s) above ground
|
|
211
|
+
|
|
212
|
+
**Returns:**
|
|
213
|
+
- `np.ndarray`: Shape (N, 3) ground coordinates
|
|
214
|
+
|
|
215
|
+
---
|
|
216
|
+
|
|
217
|
+
### `gnd_to_ctd(points)`
|
|
218
|
+
|
|
219
|
+
Transform from 3D ground coordinates to corrected coordinates.
|
|
220
|
+
|
|
221
|
+
**Parameters:**
|
|
222
|
+
- `points` (np.ndarray): Shape (N, 3) array of [x, y, z] coordinates
|
|
223
|
+
|
|
224
|
+
**Returns:**
|
|
225
|
+
- `np.ndarray`: Shape (N, 2) corrected coordinates
|
|
226
|
+
|
|
227
|
+
## Calibration File Format
|
|
228
|
+
|
|
229
|
+
The calibration file is a NumPy `.npz` archive containing:
|
|
230
|
+
|
|
231
|
+
- `src2ctd`: Lookup table for source to corrected transformation (H x W x 2)
|
|
232
|
+
- `ctd2src`: Lookup table for corrected to source transformation (H x W x 2)
|
|
233
|
+
- `x_gnd`, `y_gnd`, `z_gnd`: Expression strings for corrected to ground transformation
|
|
234
|
+
- `x_im`, `y_im`: Expression strings for ground to corrected transformation
|
|
235
|
+
- `im_width`, `im_height`: Image dimensions
|
|
236
|
+
- `plan_scale`: Scale factor for ground plane
|
|
237
|
+
|
|
238
|
+
## Requirements
|
|
239
|
+
|
|
240
|
+
- Python >= 3.7
|
|
241
|
+
- NumPy >= 1.20.0
|
|
242
|
+
|
|
243
|
+
## Links
|
|
244
|
+
|
|
245
|
+
- **Repository**: [https://github.com/avabr/camera-client](https://github.com/avabr/camera-client)
|
|
246
|
+
- **Issues**: [https://github.com/avabr/camera-client/issues](https://github.com/avabr/camera-client/issues)
|
|
247
|
+
- **PyPI**: [https://pypi.org/project/camera-client/](https://pypi.org/project/camera-client/)
|
|
248
|
+
|
|
249
|
+
## License
|
|
250
|
+
|
|
251
|
+
MIT License - see [LICENSE](LICENSE) file for details.
|
|
252
|
+
|
|
253
|
+
## Author
|
|
254
|
+
|
|
255
|
+
Alexander Abramov ([extremal.ru@gmail.com](mailto:extremal.ru@gmail.com))
|