Skip to content

Commit

Permalink
Version 1.2.4 (#126)
Browse files Browse the repository at this point in the history
* fix install fail on recent python with python_version requirement

* Add functions to access system timestamps for each image (#122)

* fix memory usage problem for calls to capture.transformed_ir (#125)

* version 1.2.4

Co-authored-by: Johan von Forstner <[email protected]>
  • Loading branch information
lpasselin and johan12345 authored May 19, 2021
1 parent 0554de5 commit 8a2fb92
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 22 deletions.
44 changes: 37 additions & 7 deletions pyk4a/capture.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,15 @@ def __init__(

self._color: Optional[np.ndarray] = None
self._color_timestamp_usec: int = 0
self._color_system_timestamp_nsec: int = 0
self._color_exposure_usec: Optional[int] = None
self._color_white_balance: Optional[int] = None
self._depth: Optional[np.ndarray] = None
self._depth_timestamp_usec: int = 0
self._depth_system_timestamp_nsec: int = 0
self._ir: Optional[np.ndarray] = None
self._ir_timestamp_usec: int = 0
self._ir_system_timestamp_nsec: int = 0
self._depth_point_cloud: Optional[np.ndarray] = None
self._transformed_depth: Optional[np.ndarray] = None
self._transformed_depth_point_cloud: Optional[np.ndarray] = None
Expand All @@ -41,9 +44,11 @@ def __init__(
@property
def color(self) -> Optional[np.ndarray]:
if self._color is None:
self._color, self._color_timestamp_usec = k4a_module.capture_get_color_image(
self._capture_handle, self.thread_safe
)
(
self._color,
self._color_timestamp_usec,
self._color_system_timestamp_nsec,
) = k4a_module.capture_get_color_image(self._capture_handle, self.thread_safe)
return self._color

@property
Expand All @@ -53,6 +58,13 @@ def color_timestamp_usec(self) -> int:
self.color
return self._color_timestamp_usec

@property
def color_system_timestamp_nsec(self) -> int:
"""System timestamp for color image in nanoseconds. Corresponds to Python's time.perf_counter_ns()."""
if self._color is None:
self.color
return self._color_system_timestamp_nsec

@property
def color_exposure_usec(self) -> int:
if self._color_exposure_usec is None:
Expand All @@ -74,9 +86,11 @@ def color_white_balance(self) -> int:
@property
def depth(self) -> Optional[np.ndarray]:
if self._depth is None:
self._depth, self._depth_timestamp_usec = k4a_module.capture_get_depth_image(
self._capture_handle, self.thread_safe
)
(
self._depth,
self._depth_timestamp_usec,
self._depth_system_timestamp_nsec,
) = k4a_module.capture_get_depth_image(self._capture_handle, self.thread_safe)
return self._depth

@property
Expand All @@ -86,11 +100,20 @@ def depth_timestamp_usec(self) -> int:
self.depth
return self._depth_timestamp_usec

@property
def depth_system_timestamp_nsec(self) -> int:
"""System timestamp for depth image in nanoseconds. Corresponds to Python's time.perf_counter_ns()."""
if self._depth is None:
self.depth
return self._depth_system_timestamp_nsec

@property
def ir(self) -> Optional[np.ndarray]:
"""Device timestamp for IR image. Not equal host machine timestamp!. Like as equal depth image timestamp"""
if self._ir is None:
self._ir, self._ir_timestamp_usec = k4a_module.capture_get_ir_image(self._capture_handle, self.thread_safe)
self._ir, self._ir_timestamp_usec, self._ir_system_timestamp_nsec = k4a_module.capture_get_ir_image(
self._capture_handle, self.thread_safe
)
return self._ir

@property
Expand All @@ -99,6 +122,13 @@ def ir_timestamp_usec(self) -> int:
self.ir
return self._ir_timestamp_usec

@property
def ir_system_timestamp_nsec(self) -> int:
"""System timestamp for IR image in nanoseconds. Corresponds to Python's time.perf_counter_ns()."""
if self._ir is None:
self.ir
return self._ir_system_timestamp_nsec

@property
def transformed_depth(self) -> Optional[np.ndarray]:
if self._transformed_depth is None and self.depth is not None:
Expand Down
40 changes: 26 additions & 14 deletions pyk4a/pyk4a.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -517,6 +517,11 @@ k4a_result_t k4a_image_to_numpy(k4a_image_t *img_src, PyArrayObject **img_dst) {
dims[1] = k4a_image_get_width_pixels(*img_src);
*img_dst = (PyArrayObject *)PyArray_SimpleNewFromData(2, dims, NPY_UINT16, buffer);
break;
case K4A_IMAGE_FORMAT_CUSTOM8:
dims[0] = k4a_image_get_height_pixels(*img_src);
dims[1] = k4a_image_get_width_pixels(*img_src);
*img_dst = (PyArrayObject *)PyArray_SimpleNewFromData(2, dims, NPY_UINT8, buffer);
break;
case K4A_IMAGE_FORMAT_CUSTOM:
// xyz in uint16 format
dims[0] = k4a_image_get_height_pixels(*img_src);
Expand Down Expand Up @@ -544,13 +549,15 @@ k4a_result_t numpy_to_k4a_image(PyArrayObject *img_src, k4a_image_t *img_dst, k4

switch (format) {
case K4A_IMAGE_FORMAT_DEPTH16:
case K4A_IMAGE_FORMAT_CUSTOM16:
case K4A_IMAGE_FORMAT_IR16:
pixel_size = (int)sizeof(uint16_t);
break;
case K4A_IMAGE_FORMAT_COLOR_BGRA32:
pixel_size = (int)sizeof(uint32_t);
break;
case K4A_IMAGE_FORMAT_CUSTOM16:
pixel_size = (unsigned int)sizeof(int16_t);
case K4A_IMAGE_FORMAT_CUSTOM8:
pixel_size = (int)sizeof(uint8_t);
break;
default:
// Not supported
Expand Down Expand Up @@ -707,8 +714,7 @@ static PyObject *transformation_depth_image_to_color_camera_custom(PyObject *sel
if (K4A_RESULT_SUCCEEDED == res) {
res = k4a_image_create(k4a_image_get_format(custom_image), RESOLUTION_TO_DIMS[color_resolution][0],
RESOLUTION_TO_DIMS[color_resolution][1],
RESOLUTION_TO_DIMS[color_resolution][0] * static_cast<int32_t>(sizeof(int16_t)),
custom_image_transformed);
RESOLUTION_TO_DIMS[color_resolution][0] * (int)sizeof(uint16_t), custom_image_transformed);
}

if (K4A_RESULT_SUCCEEDED == res) {
Expand All @@ -729,7 +735,7 @@ static PyObject *transformation_depth_image_to_color_camera_custom(PyObject *sel
}

if (K4A_RESULT_SUCCEEDED == res) {
return Py_BuildValue("OO", np_custom_image, np_depth_image);
return Py_BuildValue("NN", np_custom_image, np_depth_image);
} else {
free(depth_image_transformed);
free(custom_image_transformed);
Expand Down Expand Up @@ -838,6 +844,7 @@ static PyObject *capture_get_color_image(PyObject *self, PyObject *args) {
PyObject *capsule;
int thread_safe;
uint64_t device_timestamp_usec = 0;
uint64_t system_timestamp_nsec = 0;
PyThreadState *thread_state;
k4a_result_t res = K4A_RESULT_FAILED;

Expand All @@ -847,7 +854,7 @@ static PyObject *capture_get_color_image(PyObject *self, PyObject *args) {
k4a_image_t *image = (k4a_image_t *)malloc(sizeof(k4a_image_t));
if (image == NULL) {
fprintf(stderr, "Cannot allocate memory");
return Py_BuildValue("NK", Py_None, device_timestamp_usec);
return Py_BuildValue("NKK", Py_None, device_timestamp_usec, system_timestamp_nsec);
}

thread_state = _gil_release(thread_safe);
Expand All @@ -861,10 +868,11 @@ static PyObject *capture_get_color_image(PyObject *self, PyObject *args) {

if (K4A_RESULT_SUCCEEDED == res) {
device_timestamp_usec = k4a_image_get_device_timestamp_usec(*image);
return Py_BuildValue("NK", np_image, device_timestamp_usec);
system_timestamp_nsec = k4a_image_get_system_timestamp_nsec(*image);
return Py_BuildValue("NKK", np_image, device_timestamp_usec, system_timestamp_nsec);
} else {
free(image);
return Py_BuildValue("NK", Py_None, device_timestamp_usec);
return Py_BuildValue("NKK", Py_None, device_timestamp_usec, system_timestamp_nsec);
}
}

Expand All @@ -873,6 +881,7 @@ static PyObject *capture_get_depth_image(PyObject *self, PyObject *args) {
PyObject *capsule;
int thread_safe;
uint64_t device_timestamp_usec = 0;
uint64_t system_timestamp_nsec = 0;
PyThreadState *thread_state;
k4a_result_t res = K4A_RESULT_FAILED;

Expand All @@ -882,7 +891,7 @@ static PyObject *capture_get_depth_image(PyObject *self, PyObject *args) {
k4a_image_t *image = (k4a_image_t *)malloc(sizeof(k4a_image_t));
if (image == NULL) {
fprintf(stderr, "Cannot allocate memory");
return Py_BuildValue("NK", Py_None, device_timestamp_usec);
return Py_BuildValue("NKK", Py_None, device_timestamp_usec, system_timestamp_nsec);
}

thread_state = _gil_release(thread_safe);
Expand All @@ -896,10 +905,11 @@ static PyObject *capture_get_depth_image(PyObject *self, PyObject *args) {

if (K4A_RESULT_SUCCEEDED == res) {
device_timestamp_usec = k4a_image_get_device_timestamp_usec(*image);
return Py_BuildValue("NK", np_image, device_timestamp_usec);
system_timestamp_nsec = k4a_image_get_system_timestamp_nsec(*image);
return Py_BuildValue("NKK", np_image, device_timestamp_usec, system_timestamp_nsec);
} else {
free(image);
return Py_BuildValue("NK", Py_None, device_timestamp_usec);
return Py_BuildValue("NKK", Py_None, device_timestamp_usec, system_timestamp_nsec);
}
}

Expand All @@ -908,6 +918,7 @@ static PyObject *capture_get_ir_image(PyObject *self, PyObject *args) {
PyObject *capsule;
int thread_safe;
uint64_t device_timestamp_usec = 0;
uint64_t system_timestamp_nsec = 0;
PyThreadState *thread_state;
k4a_result_t res = K4A_RESULT_FAILED;

Expand All @@ -917,7 +928,7 @@ static PyObject *capture_get_ir_image(PyObject *self, PyObject *args) {
k4a_image_t *image = (k4a_image_t *)malloc(sizeof(k4a_image_t));
if (image == NULL) {
fprintf(stderr, "Cannot allocate memory");
return Py_BuildValue("NK", Py_None, device_timestamp_usec);
return Py_BuildValue("NKK", Py_None, device_timestamp_usec, system_timestamp_nsec);
}

thread_state = _gil_release(thread_safe);
Expand All @@ -931,10 +942,11 @@ static PyObject *capture_get_ir_image(PyObject *self, PyObject *args) {

if (K4A_RESULT_SUCCEEDED == res) {
device_timestamp_usec = k4a_image_get_device_timestamp_usec(*image);
return Py_BuildValue("NK", np_image, device_timestamp_usec);
system_timestamp_nsec = k4a_image_get_system_timestamp_nsec(*image);
return Py_BuildValue("NKK", np_image, device_timestamp_usec, system_timestamp_nsec);
} else {
free(image);
return Py_BuildValue("NK", Py_None, device_timestamp_usec);
return Py_BuildValue("NKK", Py_None, device_timestamp_usec, system_timestamp_nsec);
}
}

Expand Down
2 changes: 1 addition & 1 deletion setup.cfg
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[metadata]
name = pyk4a
version = 1.2.3
version = 1.2.4
description-file = README.md
description = Python wrapper over Azure Kinect SDK
long_description = file: README.md
Expand Down

0 comments on commit 8a2fb92

Please sign in to comment.