camera-client 0.2.3__tar.gz → 0.2.5__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.
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.4
1
+ Metadata-Version: 2.1
2
2
  Name: camera-client
3
- Version: 0.2.3
3
+ Version: 0.2.5
4
4
  Summary: Python SDK for camera calibration and projection transformations - handle lens distortion, coordinate transformations, and 3D ray casting with symbolic expressions.
5
5
  Author-email: Alexander Abramov <extremal.ru@gmail.com>
6
6
  License: MIT
@@ -26,7 +26,6 @@ Description-Content-Type: text/markdown
26
26
  License-File: LICENSE
27
27
  Requires-Dist: numpy>=1.20.0
28
28
  Requires-Dist: sympy>=1.10.0
29
- Dynamic: license-file
30
29
 
31
30
  # camera-client
32
31
 
@@ -316,6 +315,58 @@ Get the camera position (key-point) in world space.
316
315
  **Returns:**
317
316
  - `np.ndarray`: Shape (3,) array with [x, y, z] camera position
318
317
 
318
+ ---
319
+
320
+ ### `get_ctd_points_context(ctd_points)`
321
+
322
+ Get scale context values for corrected (CTD) image points.
323
+
324
+ **Parameters:**
325
+ - `ctd_points` (np.ndarray): Shape (N, 2) array of [x, y] corrected coordinates
326
+
327
+ **Returns:**
328
+ - `dict`: Dictionary with keys:
329
+ - `wscale` (np.ndarray): Shape (N,) width scale values
330
+ - `hscale` (np.ndarray): Shape (N,) height scale values
331
+ - `vangle` (np.ndarray): Shape (N,) vertical angle values (radians)
332
+
333
+ **Note:** Out-of-bounds points will have NaN values
334
+
335
+ **Example:**
336
+ ```python
337
+ ctd_points = np.array([[640, 480], [800, 600]])
338
+ context = camera.get_ctd_points_context(ctd_points)
339
+ print(context['wscale']) # Width scale at each point
340
+ print(context['hscale']) # Height scale at each point
341
+ print(context['vangle']) # Vertical angle at each point
342
+ ```
343
+
344
+ ---
345
+
346
+ ### `get_src_points_context(src_points)`
347
+
348
+ Get scale context values for source (distorted) image points.
349
+
350
+ **Parameters:**
351
+ - `src_points` (np.ndarray): Shape (N, 2) array of [x, y] source coordinates
352
+
353
+ **Returns:**
354
+ - `dict`: Dictionary with keys:
355
+ - `wscale` (np.ndarray): Shape (N,) width scale values
356
+ - `hscale` (np.ndarray): Shape (N,) height scale values
357
+ - `vangle` (np.ndarray): Shape (N,) vertical angle values (radians)
358
+
359
+ **Note:** Internally converts source points to CTD coordinates first, then retrieves context
360
+
361
+ **Example:**
362
+ ```python
363
+ src_points = np.array([[640, 480], [800, 600]])
364
+ context = camera.get_src_points_context(src_points)
365
+ print(context['wscale']) # Width scale at each point
366
+ ```
367
+
368
+ ---
369
+
319
370
  ## Calibration File Format
320
371
 
321
372
  The calibration file is a NumPy `.npz` archive containing:
@@ -344,7 +395,7 @@ The calibration file is a NumPy `.npz` archive containing:
344
395
  - `im_ctd_url`: URL or path to the corrected (undistorted) camera image
345
396
  - `im_width`: Width of the camera image in pixels
346
397
  - `im_height`: Height of the camera image in pixels
347
- - `ctd_geometry`: JSON object with geometry data in CTD coordinates (efov_polygons, counting_lines)
398
+ - `ctd_geometry`: JSON object with geometry data in CTD coordinates (efov_polygon, counting_lines)
348
399
 
349
400
  ## Requirements
350
401
 
@@ -286,6 +286,58 @@ Get the camera position (key-point) in world space.
286
286
  **Returns:**
287
287
  - `np.ndarray`: Shape (3,) array with [x, y, z] camera position
288
288
 
289
+ ---
290
+
291
+ ### `get_ctd_points_context(ctd_points)`
292
+
293
+ Get scale context values for corrected (CTD) image points.
294
+
295
+ **Parameters:**
296
+ - `ctd_points` (np.ndarray): Shape (N, 2) array of [x, y] corrected coordinates
297
+
298
+ **Returns:**
299
+ - `dict`: Dictionary with keys:
300
+ - `wscale` (np.ndarray): Shape (N,) width scale values
301
+ - `hscale` (np.ndarray): Shape (N,) height scale values
302
+ - `vangle` (np.ndarray): Shape (N,) vertical angle values (radians)
303
+
304
+ **Note:** Out-of-bounds points will have NaN values
305
+
306
+ **Example:**
307
+ ```python
308
+ ctd_points = np.array([[640, 480], [800, 600]])
309
+ context = camera.get_ctd_points_context(ctd_points)
310
+ print(context['wscale']) # Width scale at each point
311
+ print(context['hscale']) # Height scale at each point
312
+ print(context['vangle']) # Vertical angle at each point
313
+ ```
314
+
315
+ ---
316
+
317
+ ### `get_src_points_context(src_points)`
318
+
319
+ Get scale context values for source (distorted) image points.
320
+
321
+ **Parameters:**
322
+ - `src_points` (np.ndarray): Shape (N, 2) array of [x, y] source coordinates
323
+
324
+ **Returns:**
325
+ - `dict`: Dictionary with keys:
326
+ - `wscale` (np.ndarray): Shape (N,) width scale values
327
+ - `hscale` (np.ndarray): Shape (N,) height scale values
328
+ - `vangle` (np.ndarray): Shape (N,) vertical angle values (radians)
329
+
330
+ **Note:** Internally converts source points to CTD coordinates first, then retrieves context
331
+
332
+ **Example:**
333
+ ```python
334
+ src_points = np.array([[640, 480], [800, 600]])
335
+ context = camera.get_src_points_context(src_points)
336
+ print(context['wscale']) # Width scale at each point
337
+ ```
338
+
339
+ ---
340
+
289
341
  ## Calibration File Format
290
342
 
291
343
  The calibration file is a NumPy `.npz` archive containing:
@@ -314,7 +366,7 @@ The calibration file is a NumPy `.npz` archive containing:
314
366
  - `im_ctd_url`: URL or path to the corrected (undistorted) camera image
315
367
  - `im_width`: Width of the camera image in pixels
316
368
  - `im_height`: Height of the camera image in pixels
317
- - `ctd_geometry`: JSON object with geometry data in CTD coordinates (efov_polygons, counting_lines)
369
+ - `ctd_geometry`: JSON object with geometry data in CTD coordinates (efov_polygon, counting_lines)
318
370
 
319
371
  ## Requirements
320
372
 
@@ -26,6 +26,7 @@ class CameraProjection:
26
26
  - ctd2src: Corrected to source distortion map (H x W x 2)
27
27
  - x_gnd, y_gnd, z_gnd: String expressions for ctd -> ground
28
28
  - x_im, y_im: String expressions for ground -> ctd
29
+ - map_scale_h, map_scale_w, map_scale_vang: Scale context maps (H x W)
29
30
  """
30
31
  data = cam_archive_data
31
32
 
@@ -47,6 +48,11 @@ class CameraProjection:
47
48
  self.src2ctd_points_map = data["src2ctd"]
48
49
  self.ctd2src_points_map = data["ctd2src"]
49
50
 
51
+ # Store scale context maps
52
+ self.map_scale_h = data["map_scale_h"]
53
+ self.map_scale_w = data["map_scale_w"]
54
+ self.map_scale_vang = data["map_scale_vang"]
55
+
50
56
  self.im_size = self.src2ctd_points_map.shape[:2]
51
57
 
52
58
  # Compile transformation expressions for ctd -> gnd
@@ -294,6 +300,81 @@ class CameraProjection:
294
300
  ctd_points = self.src_to_ctd(points)
295
301
  return self.ctd_to_ray(ctd_points)
296
302
 
303
+ def get_ctd_points_context(self, ctd_points):
304
+ """
305
+ Get scale context values for corrected (CTD) image points.
306
+
307
+ Args:
308
+ ctd_points: (N, 2) array of corrected points [[x1, y1], [x2, y2], ...]
309
+
310
+ Returns:
311
+ Dictionary with keys:
312
+ - wscale: (N,) array of width scale values
313
+ - hscale: (N,) array of height scale values
314
+ - vangle: (N,) array of vertical angle values
315
+ Out-of-bounds points will have NaN values.
316
+ """
317
+ ctd_points = np.asarray(ctd_points, dtype=float)
318
+ if ctd_points.ndim != 2 or ctd_points.shape[1] != 2:
319
+ raise ValueError(f"Expected (N, 2) array, got shape {ctd_points.shape}")
320
+
321
+ N = len(ctd_points)
322
+ wscale = np.full(N, np.nan, dtype=float)
323
+ hscale = np.full(N, np.nan, dtype=float)
324
+ vangle = np.full(N, np.nan, dtype=float)
325
+
326
+ # Check for NaN input points
327
+ valid_input = ~np.isnan(ctd_points).any(axis=1)
328
+
329
+ if not valid_input.any():
330
+ return {"wscale": wscale, "hscale": hscale, "vangle": vangle}
331
+
332
+ # Round to integer coordinates
333
+ p_int = np.round(ctd_points[valid_input]).astype(int)
334
+
335
+ # Vectorized bounds checking
336
+ in_bounds = (
337
+ (p_int[:, 0] >= 0)
338
+ & (p_int[:, 0] < self.map_scale_w.shape[1])
339
+ & (p_int[:, 1] >= 0)
340
+ & (p_int[:, 1] < self.map_scale_w.shape[0])
341
+ )
342
+
343
+ # Create mask for points that are both valid input and in bounds
344
+ valid_indices = np.where(valid_input)[0]
345
+ final_valid_indices = valid_indices[in_bounds]
346
+ valid_p_int = p_int[in_bounds]
347
+
348
+ # Vectorized lookup using advanced indexing (y, x indexing)
349
+ wscale[final_valid_indices] = self.map_scale_w[
350
+ valid_p_int[:, 1], valid_p_int[:, 0]
351
+ ]
352
+ hscale[final_valid_indices] = self.map_scale_h[
353
+ valid_p_int[:, 1], valid_p_int[:, 0]
354
+ ]
355
+ vangle[final_valid_indices] = self.map_scale_vang[
356
+ valid_p_int[:, 1], valid_p_int[:, 0]
357
+ ]
358
+
359
+ return {"wscale": wscale, "hscale": hscale, "vangle": vangle}
360
+
361
+ def get_src_points_context(self, src_points):
362
+ """
363
+ Get scale context values for source (distorted) image points.
364
+
365
+ Args:
366
+ src_points: (N, 2) array of source points [[x1, y1], [x2, y2], ...]
367
+
368
+ Returns:
369
+ Dictionary with keys:
370
+ - wscale: (N,) array of width scale values
371
+ - hscale: (N,) array of height scale values
372
+ - vangle: (N,) array of vertical angle values
373
+ Out-of-bounds points will have NaN values.
374
+ """
375
+ ctd_points = self.src_to_ctd(src_points)
376
+ return self.get_ctd_points_context(ctd_points)
377
+
297
378
  @classmethod
298
379
  def load(cls, archive_path):
299
380
  """
@@ -34,7 +34,7 @@ def read_npz_file(filename):
34
34
  - exp_key_point (sp.Expr): Sympy expression for keypoint coordinates
35
35
  - exp_im2ray (sp.Expr): Sympy expression for image to ray direction transformation
36
36
  - ctd_geometry (dict): JSON object containing geometry data in CTD coordinate system:
37
- - efov_polygons: Polygons defining effective field of view in CTD coordinates
37
+ - efov_polygon: Polygon defining effective field of view in CTD coordinates
38
38
  - counting_lines: Polylines for counting forward/backward track intersections
39
39
  """
40
40
  data = np.load(filename)
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.4
1
+ Metadata-Version: 2.1
2
2
  Name: camera-client
3
- Version: 0.2.3
3
+ Version: 0.2.5
4
4
  Summary: Python SDK for camera calibration and projection transformations - handle lens distortion, coordinate transformations, and 3D ray casting with symbolic expressions.
5
5
  Author-email: Alexander Abramov <extremal.ru@gmail.com>
6
6
  License: MIT
@@ -26,7 +26,6 @@ Description-Content-Type: text/markdown
26
26
  License-File: LICENSE
27
27
  Requires-Dist: numpy>=1.20.0
28
28
  Requires-Dist: sympy>=1.10.0
29
- Dynamic: license-file
30
29
 
31
30
  # camera-client
32
31
 
@@ -316,6 +315,58 @@ Get the camera position (key-point) in world space.
316
315
  **Returns:**
317
316
  - `np.ndarray`: Shape (3,) array with [x, y, z] camera position
318
317
 
318
+ ---
319
+
320
+ ### `get_ctd_points_context(ctd_points)`
321
+
322
+ Get scale context values for corrected (CTD) image points.
323
+
324
+ **Parameters:**
325
+ - `ctd_points` (np.ndarray): Shape (N, 2) array of [x, y] corrected coordinates
326
+
327
+ **Returns:**
328
+ - `dict`: Dictionary with keys:
329
+ - `wscale` (np.ndarray): Shape (N,) width scale values
330
+ - `hscale` (np.ndarray): Shape (N,) height scale values
331
+ - `vangle` (np.ndarray): Shape (N,) vertical angle values (radians)
332
+
333
+ **Note:** Out-of-bounds points will have NaN values
334
+
335
+ **Example:**
336
+ ```python
337
+ ctd_points = np.array([[640, 480], [800, 600]])
338
+ context = camera.get_ctd_points_context(ctd_points)
339
+ print(context['wscale']) # Width scale at each point
340
+ print(context['hscale']) # Height scale at each point
341
+ print(context['vangle']) # Vertical angle at each point
342
+ ```
343
+
344
+ ---
345
+
346
+ ### `get_src_points_context(src_points)`
347
+
348
+ Get scale context values for source (distorted) image points.
349
+
350
+ **Parameters:**
351
+ - `src_points` (np.ndarray): Shape (N, 2) array of [x, y] source coordinates
352
+
353
+ **Returns:**
354
+ - `dict`: Dictionary with keys:
355
+ - `wscale` (np.ndarray): Shape (N,) width scale values
356
+ - `hscale` (np.ndarray): Shape (N,) height scale values
357
+ - `vangle` (np.ndarray): Shape (N,) vertical angle values (radians)
358
+
359
+ **Note:** Internally converts source points to CTD coordinates first, then retrieves context
360
+
361
+ **Example:**
362
+ ```python
363
+ src_points = np.array([[640, 480], [800, 600]])
364
+ context = camera.get_src_points_context(src_points)
365
+ print(context['wscale']) # Width scale at each point
366
+ ```
367
+
368
+ ---
369
+
319
370
  ## Calibration File Format
320
371
 
321
372
  The calibration file is a NumPy `.npz` archive containing:
@@ -344,7 +395,7 @@ The calibration file is a NumPy `.npz` archive containing:
344
395
  - `im_ctd_url`: URL or path to the corrected (undistorted) camera image
345
396
  - `im_width`: Width of the camera image in pixels
346
397
  - `im_height`: Height of the camera image in pixels
347
- - `ctd_geometry`: JSON object with geometry data in CTD coordinates (efov_polygons, counting_lines)
398
+ - `ctd_geometry`: JSON object with geometry data in CTD coordinates (efov_polygon, counting_lines)
348
399
 
349
400
  ## Requirements
350
401
 
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "camera-client"
7
- version = "0.2.3"
7
+ version = "0.2.5"
8
8
  description = "Python SDK for camera calibration and projection transformations - handle lens distortion, coordinate transformations, and 3D ray casting with symbolic expressions."
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.7"
File without changes
File without changes
File without changes
File without changes