Skip to content

Commit e94b0fa

Browse files
lpasselinshagrenSBoulangerjohan12345
authored
Version 1.2.0 (#115)
- Use clang-format as CPP code formatter/linter (#105) - Available devices count (#107) - Recording support (#106) - Capture color exposure and white balance properties (#110) - Calibration: Add functions to access intrinsics (#113) - Add 3d => 2d conversion function (#114) * Run test with different python versions (#65) * Add matrix to workflow * Change python versions list * Change python versions list * Add k4a versions to matrix * Typofix * Drop k4a from matrix * Add dataclasses requirement for python <3.7 * Fix python 3.6 test behavior * Fix python 3.6 test behavior * Restore fail-fast option * fix conversion seconds to ns * fix conversion seconds to ns * fix timestamp ns to us Co-authored-by: Louis-Philippe Asselin <[email protected]> * fix install using pip --editable --user (#67) * Codecov support (#64) * Codecov support * Add badge * Order badges * fix capture.transformed_depth_point_cloud (#73) * version 1.0.1 * Added transformed_ir with transform_depth_image_to_color_camera_custom functionality (#76) * Added transform_depth_image_to_color_camera_custom functionality * keeping things c * add interpolation option condition as a parameter * returned the depth image * unpack return value if not None so avoid error * Image timestamp support (#88) * Support for capture images timestamps * Support for capture images timestamps * Add more changes * version 1.1.0 * fix lint * readme fix wrong example version of SDK * Use clang-format as CPP code formatter/linter (#105) * Use clang-format as CPP code formatter/linter * Add missed .clang-format * Available devices count (#107) * Add ability to querying devices count and read serial numbers * Fix test * Rename installed_count => connected_device_count * Recording support (#106) * Recording support * Tests * Small refactoring * Add ability to querying devices count and read serial numbers * Fix test * Fix format * Capture color exposure and white balance properties (#110) * Add color_white_balance and exposure_usec properties to capture * Add color_white_balance and exposure_usec properties to capture Co-authored-by: Louis-Philippe Asselin <[email protected]> * Calibration: Add functions to access intrinsics (#113) Camera matrix and distortion coefficients in OpenCV-compatible format. These values are already specific to the selected camera resolution (in contrast to those accessed through calibration_raw). related to #35, #69 Co-authored-by: Johan von Forstner <[email protected]> * version 1.2.0 Co-authored-by: Ilya Gruzinov <[email protected]> Co-authored-by: Samuel Boulanger <[email protected]> Co-authored-by: Johan von Forstner <[email protected]> Co-authored-by: Johan von Forstner <[email protected]>
1 parent 8186ae9 commit e94b0fa

17 files changed

+656
-19
lines changed

example/devices.py

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
from pyk4a import PyK4A, connected_device_count
2+
3+
4+
cnt = connected_device_count()
5+
if not cnt:
6+
print("No devices available")
7+
exit()
8+
print(f"Available devices: {cnt}")
9+
for device_id in range(cnt):
10+
device = PyK4A(device_id=device_id)
11+
device.open()
12+
print(f"{device_id}: {device.serial}")
13+
device.close()

example/record.py

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
from argparse import ArgumentParser
2+
3+
from pyk4a import Config, ImageFormat, PyK4A, PyK4ARecord
4+
5+
6+
parser = ArgumentParser(description="pyk4a recorder")
7+
parser.add_argument("--device", type=int, help="Device ID", default=0)
8+
parser.add_argument("FILE", type=str, help="Path to MKV file")
9+
args = parser.parse_args()
10+
11+
print(f"Starting device #{args.device}")
12+
config = Config(color_format=ImageFormat.COLOR_MJPG)
13+
device = PyK4A(config=config, device_id=args.device)
14+
device.start()
15+
16+
print(f"Open record file {args.FILE}")
17+
record = PyK4ARecord(device=device, config=config, path=args.FILE)
18+
record.create()
19+
try:
20+
print("Recording... Press CTRL-C to stop recording.")
21+
while True:
22+
capture = device.get_capture()
23+
record.write_capture(capture)
24+
except KeyboardInterrupt:
25+
print("CTRL-C pressed. Exiting.")
26+
27+
record.flush()
28+
record.close()
29+
print(f"{record.captures_count} frames written.")

pyk4a/__init__.py

+9
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import k4a_module
2+
13
from .calibration import Calibration, CalibrationType
24
from .capture import PyK4ACapture
35
from .config import (
@@ -13,6 +15,7 @@
1315
from .errors import K4AException, K4ATimeoutException
1416
from .playback import PyK4APlayback, SeekOrigin
1517
from .pyk4a import ColorControlCapabilities, PyK4A
18+
from .record import PyK4ARecord
1619
from .transformation import (
1720
color_image_to_depth_camera,
1821
depth_image_to_color_camera,
@@ -21,6 +24,10 @@
2124
)
2225

2326

27+
def connected_device_count() -> int:
28+
return k4a_module.device_get_installed_count()
29+
30+
2431
__all__ = (
2532
"Calibration",
2633
"CalibrationType",
@@ -43,4 +50,6 @@
4350
"depth_image_to_point_cloud",
4451
"depth_image_to_color_camera",
4552
"depth_image_to_color_camera_custom",
53+
"PyK4ARecord",
54+
"connected_device_count",
4655
)

pyk4a/calibration.py

+27
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
from enum import IntEnum
22
from typing import Optional, Tuple
33

4+
import numpy as np
5+
46
import k4a_module
57

68
from .config import ColorResolution, DepthMode
@@ -157,3 +159,28 @@ def transformation_handle(self) -> object:
157159
raise K4AException("Cannot create transformation handle")
158160
self._transformation_handle = handle
159161
return self._transformation_handle
162+
163+
def get_camera_matrix(self, camera: CalibrationType) -> np.ndarray:
164+
"""
165+
Get the camera matrix (in OpenCV compatible format) for the color or depth camera
166+
"""
167+
if camera not in [CalibrationType.COLOR, CalibrationType.DEPTH]:
168+
raise ValueError("Camera matrix only available for color and depth cameras.")
169+
params = k4a_module.calibration_get_intrinsics(self._calibration_handle, self.thread_safe, camera)
170+
if len(params) != 14:
171+
raise ValueError("Unknown camera calibration type")
172+
173+
cx, cy, fx, fy = params[:4]
174+
return np.array([[fx, 0, cx], [0, fy, cy], [0, 0, 1]])
175+
176+
def get_distortion_coefficients(self, camera: CalibrationType) -> np.ndarray:
177+
"""
178+
Get the distortion coefficients (in OpenCV compatible format) for the color or depth camera
179+
"""
180+
if camera not in [CalibrationType.COLOR, CalibrationType.DEPTH]:
181+
raise ValueError("Distortion coefficients only available for color and depth cameras.")
182+
params = k4a_module.calibration_get_intrinsics(self._calibration_handle, self.thread_safe, camera)
183+
if len(params) != 14:
184+
raise ValueError("Unknown camera calibration type")
185+
186+
return np.array([params[4], params[5], params[13], params[12], *params[6:10]])

pyk4a/capture.py

+21
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
from .calibration import Calibration
88
from .config import ImageFormat
9+
from .errors import K4AException
910
from .transformation import (
1011
color_image_to_depth_camera,
1112
depth_image_to_color_camera,
@@ -25,6 +26,8 @@ def __init__(
2526

2627
self._color: Optional[np.ndarray] = None
2728
self._color_timestamp_usec: int = 0
29+
self._color_exposure_usec: Optional[int] = None
30+
self._color_white_balance: Optional[int] = None
2831
self._depth: Optional[np.ndarray] = None
2932
self._depth_timestamp_usec: int = 0
3033
self._ir: Optional[np.ndarray] = None
@@ -50,6 +53,24 @@ def color_timestamp_usec(self) -> int:
5053
self.color
5154
return self._color_timestamp_usec
5255

56+
@property
57+
def color_exposure_usec(self) -> int:
58+
if self._color_exposure_usec is None:
59+
value = k4a_module.color_image_get_exposure_usec(self._capture_handle)
60+
if value == 0:
61+
raise K4AException("Cannot read exposure from color image")
62+
self._color_exposure_usec = value
63+
return self._color_exposure_usec
64+
65+
@property
66+
def color_white_balance(self) -> int:
67+
if self._color_white_balance is None:
68+
value = k4a_module.color_image_get_white_balance(self._capture_handle)
69+
if value == 0:
70+
raise K4AException("Cannot read white balance from color image")
71+
self._color_white_balance = value
72+
return self._color_white_balance
73+
5374
@property
5475
def depth(self) -> Optional[np.ndarray]:
5576
if self._depth is None:

0 commit comments

Comments
 (0)