From 027a12b6d7dcb9357c6078c88569172bc0b6e59f Mon Sep 17 00:00:00 2001 From: Jonathan Santos Date: Tue, 13 Apr 2021 18:22:17 -0700 Subject: [PATCH 1/4] Fixing point cloud transformation bug with using uint16 when int16 should be used because the X and Y images are centered around 0 and can take on negative values. Adding point_cloud_capture.py example to capture depth data, transform to point cloud, and write to text file which can then be opened with a 3D modeling application like MeshLab. --- src/python/k4a/docs/examples.md | 18 ++++++++-- .../k4a/examples/point_cloud_capture.py | 36 +++++++++++++++++++ src/python/k4a/setup.py | 2 +- .../k4a/src/k4a/_bindings/transformation.py | 8 ++--- 4 files changed, 56 insertions(+), 8 deletions(-) create mode 100644 src/python/k4a/examples/point_cloud_capture.py diff --git a/src/python/k4a/docs/examples.md b/src/python/k4a/docs/examples.md index f5eded8a8..d79f255e5 100644 --- a/src/python/k4a/docs/examples.md +++ b/src/python/k4a/docs/examples.md @@ -39,10 +39,8 @@ A simple program to showcase the image transformation functions in the Azure Kin Additional Prerequisites: - Matplotlib installed via pip: `pip install matplotlib` -- Numpy installed via pip: `pip install numpy==1.18.5` +- Numpy installed via pip: `pip install numpy` - tkinter installed via pip: `pip install tk` - ->**Note:** numpy version 1.19.5 currently has a bug for Windows, so do not use it as of 2020/12/28. In Linux, another way to install tkinter is: `sudo apt install python3-tk` @@ -61,6 +59,20 @@ Close the figure to proceed. The program then transforms a depth image and an IR image into the color camera space and displays them in a figure. Close the figure to proceed and the program exits. +### point_cloud_capture.py + +A simple program to capture a single frame, transform to point cloud, and write to text file. +The text file can then be opened in a 3D renderer application like MeshLab. + +Additional Prerequisites: +- Numpy installed via pip: `pip install numpy` + + +To run, open a command terminal and type: +`python point_cloud_capture.py` + +An output text file data.txt is written in the same directory in which the example program is run. + ### simple_viewer.py A simple program to continuously capture images from an Azure Kinect device and display the images. diff --git a/src/python/k4a/examples/point_cloud_capture.py b/src/python/k4a/examples/point_cloud_capture.py new file mode 100644 index 000000000..c81d24524 --- /dev/null +++ b/src/python/k4a/examples/point_cloud_capture.py @@ -0,0 +1,36 @@ +import numpy as np +import k4a + +if __name__ == '__main__': + # Open Device + device = k4a.Device.open() + + # Start Cameras + device_config = k4a.DEVICE_CONFIG_BGRA32_1080P_NFOV_UNBINNED_FPS15 + device.start_cameras(device_config) + + # Get Calibration + calibration = device.get_calibration( + depth_mode=device_config.depth_mode, + color_resolution=device_config.color_resolution) + + # Create Transformation + transformation = k4a.Transformation(calibration) + + # Capture One Frame + capture = device.get_capture(-1) + + # Get Point Cloud + xyz_image = transformation.depth_image_to_point_cloud(capture.depth, k4a.ECalibrationType.DEPTH) + + # Save Point Cloud To Ascii Format File. Interleave the [X, Y, Z] channels into [x0, y0, z0, x1, y1, z1, ...] + width, height, channels = xyz_image.data.shape + xyz_data = np.empty((width * height, channels,), dtype=xyz_image.data.dtype) + xyz_data[:,0] = xyz_image.data[:,:,0].reshape(width*height) + xyz_data[:,1] = xyz_image.data[:,:,1].reshape(width*height) + xyz_data[:,2] = xyz_image.data[:,:,2].reshape(width*height) + + np.savetxt('data.txt', xyz_data, delimiter=' ', fmt='%u') # save ascii format (x y z\n x y z\n x y z\n ...) + + # Stop Cameras + device.stop_cameras() \ No newline at end of file diff --git a/src/python/k4a/setup.py b/src/python/k4a/setup.py index 599d118b0..bd3343f9b 100644 --- a/src/python/k4a/setup.py +++ b/src/python/k4a/setup.py @@ -2,7 +2,7 @@ setup( name='k4a', - version='0.0.1', + version='0.0.2', author='Jonathan Santos', author_email='jonsanto@microsoft.com', description='Python interface to Azure Kinect API.', diff --git a/src/python/k4a/src/k4a/_bindings/transformation.py b/src/python/k4a/src/k4a/_bindings/transformation.py index b9ba92a79..6be4bd872 100644 --- a/src/python/k4a/src/k4a/_bindings/transformation.py +++ b/src/python/k4a/src/k4a/_bindings/transformation.py @@ -583,9 +583,9 @@ def depth_image_to_point_cloud(self, times its width in pixels. @remarks - - Each pixel of the output image consists of three int16_t values, - totaling 6 bytes. The three int values are the X, Y, and Z values - of the point. + - Each plane of the output image consists of the X, Y, and Z planar images of int16 samples. + If out is the output image, then out[:,:,1] corresponds to the X coordinates, + out[:,:,2] corresponds to the Y coordinates, and out[:,:,3] is the Z depth image. ''' # Create a custom image. @@ -607,7 +607,7 @@ def depth_image_to_point_cloud(self, # The ndarray for a CUSTOM image format is a flat buffer. # Rewrite the ndarray to have 3 dimensions for X, Y, and Z points. buffer_ptr = k4a_image_get_buffer(point_cloud_image._image_handle) - array_type = ((_ctypes.c_uint16 * 3) * depth.width_pixels) * depth.height_pixels + array_type = ((_ctypes.c_int16 * 3) * depth.width_pixels) * depth.height_pixels point_cloud_image._data = _np.ctypeslib.as_array(array_type.from_address( _ctypes.c_void_p.from_buffer(buffer_ptr).value)) From 8e39a7d5996cbe8287ff41ac12e8e061c86e9a31 Mon Sep 17 00:00:00 2001 From: Jonathan Santos Date: Tue, 13 Apr 2021 19:16:57 -0700 Subject: [PATCH 2/4] Adding a newline to avoid a warning or no new line at the end of the file. --- src/python/k4a/examples/point_cloud_capture.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/python/k4a/examples/point_cloud_capture.py b/src/python/k4a/examples/point_cloud_capture.py index c81d24524..824b6cb3e 100644 --- a/src/python/k4a/examples/point_cloud_capture.py +++ b/src/python/k4a/examples/point_cloud_capture.py @@ -33,4 +33,4 @@ np.savetxt('data.txt', xyz_data, delimiter=' ', fmt='%u') # save ascii format (x y z\n x y z\n x y z\n ...) # Stop Cameras - device.stop_cameras() \ No newline at end of file + device.stop_cameras() From 5f33e6116f8ddde5c1925a9878008444b3f3024b Mon Sep 17 00:00:00 2001 From: Jonathan Santos Date: Mon, 19 Apr 2021 16:20:35 -0700 Subject: [PATCH 3/4] Replacing point cloud example to use numpy reshape. --- src/python/k4a/examples/point_cloud_capture.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/python/k4a/examples/point_cloud_capture.py b/src/python/k4a/examples/point_cloud_capture.py index 824b6cb3e..8573a7f5c 100644 --- a/src/python/k4a/examples/point_cloud_capture.py +++ b/src/python/k4a/examples/point_cloud_capture.py @@ -26,9 +26,7 @@ # Save Point Cloud To Ascii Format File. Interleave the [X, Y, Z] channels into [x0, y0, z0, x1, y1, z1, ...] width, height, channels = xyz_image.data.shape xyz_data = np.empty((width * height, channels,), dtype=xyz_image.data.dtype) - xyz_data[:,0] = xyz_image.data[:,:,0].reshape(width*height) - xyz_data[:,1] = xyz_image.data[:,:,1].reshape(width*height) - xyz_data[:,2] = xyz_image.data[:,:,2].reshape(width*height) + xyz_data = xyz_image.data.reshape(height * width, channels) np.savetxt('data.txt', xyz_data, delimiter=' ', fmt='%u') # save ascii format (x y z\n x y z\n x y z\n ...) From 25c87485fe0612aa9393c4840311b272a9d9e41c Mon Sep 17 00:00:00 2001 From: Jonathan Santos Date: Mon, 26 Apr 2021 15:34:34 -0700 Subject: [PATCH 4/4] Fixing example point_cloud_capture.py with getting the numpy array shape and having the correct order of the width vs height. --- src/python/k4a/examples/point_cloud_capture.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/python/k4a/examples/point_cloud_capture.py b/src/python/k4a/examples/point_cloud_capture.py index 8573a7f5c..86d56ac26 100644 --- a/src/python/k4a/examples/point_cloud_capture.py +++ b/src/python/k4a/examples/point_cloud_capture.py @@ -24,8 +24,7 @@ xyz_image = transformation.depth_image_to_point_cloud(capture.depth, k4a.ECalibrationType.DEPTH) # Save Point Cloud To Ascii Format File. Interleave the [X, Y, Z] channels into [x0, y0, z0, x1, y1, z1, ...] - width, height, channels = xyz_image.data.shape - xyz_data = np.empty((width * height, channels,), dtype=xyz_image.data.dtype) + height, width, channels = xyz_image.data.shape xyz_data = xyz_image.data.reshape(height * width, channels) np.savetxt('data.txt', xyz_data, delimiter=' ', fmt='%u') # save ascii format (x y z\n x y z\n x y z\n ...)