Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

You do this by setting up the config:

k4a_device_configuration_t config = K4A_DEVICE_CONFIG_INIT_DISABLE_ALL;
config.camera_fps = K4A_FRAMES_PER_SECOND_30;
config.color_format = K4A_IMAGE_FORMAT_COLOR_BGRA32; // <==== For Color image
config.color_resolution = K4A_COLOR_RESOLUTION_2160P;
config.depth_mode = K4A_DEPTH_MODE_NFOV_UNBINNED; // <==== For Depth image 

Then, once configured, you can capture a color image the following way, and then using the raw buffer create an opencv matrix from the color image:

k4a_image_t colorImage = k4a_capture_get_color_image(capture); // get image metadata
if (colorImage != NULL)
    // you can check the format with this function
    k4a_image_format_t format = k4a_image_get_format(colorImage); // K4A_IMAGE_FORMAT_COLOR_BGRA32 
    // get raw buffer
    uint8_t* buffer = k4a_image_get_buffer(colorImage);
    // convert the raw buffer to cv::Mat
    int rows = k4a_image_get_height_pixels(colorImage);
    int cols = k4a_image_get_width_pixels(colorImage);
    cv::Mat colorMat(rows , cols, CV_8UC4, (void*)buffer, cv::Mat::AUTO_STEP);
    // ...
    k4a_image_release(colorImage);

Similarly, for the depth image, you can convert the raw depth data to opencv like this (note, the matrix type has changed!):

k4a_image_t depthImage = k4a_capture_get_depth_image(capture); // get image metadata
if (depthImage != NULL)
    // you can check the format with this function
    k4a_image_format_t format = k4a_image_get_format(depthImage); // K4A_IMAGE_FORMAT_DEPTH16 
    // get raw buffer
    uint8_t* buffer = k4a_image_get_buffer(depthImage);
    // convert the raw buffer to cv::Mat
    int rows = k4a_image_get_height_pixels(depthImage);
    int cols = k4a_image_get_width_pixels(depthImage);
    cv::Mat depthMat(rows, cols, CV_16U, (void*)buffer, cv::Mat::AUTO_STEP);
    // ...
    k4a_image_release(depthImage);
  

NOTE: Opencv matrix constructor will not copy or allocate new memory for the pointer, instead it initializes the matrix head to point to the specified data!

Fantastic answer, thank you. I was searching for something similar and while I was extremely close, I had my camera configured improperly, which was leading to errors. Thanks again! – Archetype90 Aug 1, 2019 at 16:34 And maybe you can help further... I actually implemented exactly your code with an imwrite("C:\\test.jpg", colorMat) to write the image out. It worked great (which caused me to leave the above comment). I come back to it a few hours later and I am now getting an exception: (opencv_highgui2413d.dll) Acess Violation reading location. I am seeing this error all over the place from a Google search, but nothing too helpful or specific to my situation. Have you seen this before? Aware of what may be causing it? – Archetype90 Aug 1, 2019 at 20:39 OK, going to leave the above comment in case anyone else has the issue. I was slightly wrong in what I said above - I had changed the code to attempt to write an image from a recording. But the recording was not in the proper format and that error was getting thrown. It is not a very explicit error, but as soon as I swapped over to the stream and had it configured as you stated above things worked great. Thanks again! – Archetype90 Aug 1, 2019 at 20:48 Thanks for the answer. Can you explain how you initialize the capture variable? I tried to do this with k4a_capture_t capture; but this didn't work. If you have a full script, that would be great! – user2835098 Jan 31, 2020 at 17:55 // Open the first plugged in Kinect device k4a_device_t device = NULL; if (K4A_FAILED(k4a_device_open(K4A_DEVICE_DEFAULT, &device))) printf("Failed to open k4a device!\n"); return 1; // Get the size of the serial number size_t serial_size = 0; k4a_device_get_serialnum(device, NULL, &serial_size); // Allocate memory for the serial, then acquire it char *serial = (char*)(malloc(serial_size)); k4a_device_get_serialnum(device, serial, &serial_size); printf("Opened device: %s\n", serial); free(serial); // Configure a stream of 4096x3072 BRGA color data at 15 frames per second k4a_device_configuration_t config = K4A_DEVICE_CONFIG_INIT_DISABLE_ALL; config.camera_fps = K4A_FRAMES_PER_SECOND_30; config.color_format = K4A_IMAGE_FORMAT_COLOR_BGRA32; config.color_resolution = K4A_COLOR_RESOLUTION_1080P; config.depth_mode = K4A_DEPTH_MODE_NFOV_UNBINNED; config.synchronized_images_only = true; // Start the camera with the given configuration k4a_device_start_cameras(device, &config); int frame_count = 0; k4a_device_get_capture(device, &capture, TIMEOUT_IN_MS); k4a_image_t color_image = k4a_capture_get_color_image(capture); uint8_t* color_buffer = k4a_image_get_buffer(color_image); int rows = k4a_image_get_height_pixels(color_image); int cols = k4a_image_get_width_pixels(color_image); cv::Mat color(rows, cols, CV_8UC4, (void*)color_buffer, cv::Mat::AUTO_STEP); //cv::imshow("random", color); k4a_image_t depth_image = k4a_capture_get_depth_image(capture); uint8_t* depth_buffer = k4a_image_get_buffer(depth_image); int depth_rows = k4a_image_get_height_pixels(depth_image); int depth_cols = k4a_image_get_width_pixels(depth_image); cv::Mat depth(depth_rows, depth_cols, CV_8UC4, (void*)depth_buffer, cv::Mat::AUTO_STEP); //cv::imshow("depth image",depth); //cv::waitKey(0); cv::imwrite("depth.jpg",depth); cv::imwrite("color.jpg",color); k4a_device_stop_cameras(device); k4a_device_close(device); return 0;

For complete build with cmake: https://github.com/ShitalAdhikari/Azure_kinect

Thanks for contributing an answer to Stack Overflow!

  • Please be sure to answer the question. Provide details and share your research!

But avoid

  • Asking for help, clarification, or responding to other answers.
  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.