Azure Kinect Sensor SDK  refs/pull/766/merge
Documentation for https://github.com/Microsoft/Azure-Kinect-Sensor-SDK
k4a.hpp
1 
7 #ifndef K4A_HPP
8 #define K4A_HPP
9 
10 #include "k4a.h"
11 
12 #include <algorithm>
13 #include <chrono>
14 #include <cstdint>
15 #include <limits>
16 #include <stdexcept>
17 #include <string>
18 #include <vector>
19 
20 namespace k4a
21 {
22 
33 class error : public std::runtime_error
34 {
35 public:
36  using runtime_error::runtime_error;
37 };
38 
39 // Helper functions not intended for use by client code
40 //
41 namespace internal
42 {
44 
51 template<typename output_type, typename input_type> output_type clamp_cast(input_type input)
52 {
53  static_assert(std::is_arithmetic<input_type>::value, "clamp_cast only supports arithmetic types");
54  static_assert(std::is_arithmetic<output_type>::value, "clamp_cast only supports arithmetic types");
55  const input_type min_value = std::is_signed<input_type>() ?
56  static_cast<input_type>(std::numeric_limits<output_type>::min()) :
57  0;
58 
59  input_type max_value = static_cast<input_type>(std::numeric_limits<output_type>::max());
60  if (max_value < 0)
61  {
62  // Output type is of greater or equal size to input type and we've overflowed.
63  //
64  max_value = std::numeric_limits<input_type>::max();
65  }
66  input = std::min(input, max_value);
67  input = std::max(input, min_value);
68  return static_cast<output_type>(input);
69 }
71 } // namespace internal
72 
80 class image
81 {
82 public:
88  image(k4a_image_t handle = nullptr) noexcept : m_handle(handle) {}
89 
92  image(const image &other) noexcept : m_handle(other.m_handle)
93  {
94  if (m_handle != nullptr)
95  {
96  k4a_image_reference(m_handle);
97  }
98  }
99 
102  image(image &&other) noexcept : m_handle(other.m_handle)
103  {
104  other.m_handle = nullptr;
105  }
106 
107  ~image()
108  {
109  reset();
110  }
111 
114  image &operator=(const image &other) noexcept
115  {
116  if (this != &other)
117  {
118  reset();
119  m_handle = other.m_handle;
120  if (m_handle != nullptr)
121  {
122  k4a_image_reference(m_handle);
123  }
124  }
125  return *this;
126  }
127 
130  image &operator=(image &&other) noexcept
131  {
132  if (this != &other)
133  {
134  reset();
135  m_handle = other.m_handle;
136  other.m_handle = nullptr;
137  }
138  return *this;
139  }
140 
143  image &operator=(std::nullptr_t) noexcept
144  {
145  reset();
146  return *this;
147  }
148 
151  bool operator==(const image &other) const noexcept
152  {
153  return m_handle == other.m_handle;
154  }
155 
158  bool operator==(std::nullptr_t) const noexcept
159  {
160  return m_handle == nullptr;
161  }
162 
165  bool operator!=(const image &other) const noexcept
166  {
167  return m_handle != other.m_handle;
168  }
169 
172  bool operator!=(std::nullptr_t) const noexcept
173  {
174  return m_handle != nullptr;
175  }
176 
179  operator bool() const noexcept
180  {
181  return m_handle != nullptr;
182  }
183 
191  k4a_image_t handle() const noexcept
192  {
193  return m_handle;
194  }
195 
198  void reset() noexcept
199  {
200  if (m_handle != nullptr)
201  {
202  k4a_image_release(m_handle);
203  m_handle = nullptr;
204  }
205  }
206 
212  static image create(k4a_image_format_t format, int width_pixels, int height_pixels, int stride_bytes)
213  {
214  k4a_image_t handle = nullptr;
215  k4a_result_t result = k4a_image_create(format, width_pixels, height_pixels, stride_bytes, &handle);
216  if (K4A_RESULT_SUCCEEDED != result)
217  {
218  throw error("Failed to create image!");
219  }
220  return image(handle);
221  }
222 
229  int width_pixels,
230  int height_pixels,
231  int stride_bytes,
232  uint8_t *buffer,
233  size_t buffer_size,
234  k4a_memory_destroy_cb_t *buffer_release_cb,
235  void *buffer_release_cb_context)
236  {
237  k4a_image_t handle = nullptr;
238  k4a_result_t result = k4a_image_create_from_buffer(format,
239  width_pixels,
240  height_pixels,
241  stride_bytes,
242  buffer,
243  buffer_size,
244  buffer_release_cb,
245  buffer_release_cb_context,
246  &handle);
247  if (K4A_RESULT_SUCCEEDED != result)
248  {
249  throw error("Failed to create image from buffer");
250  }
251  return image(handle);
252  }
253 
258  uint8_t *get_buffer() noexcept
259  {
260  return k4a_image_get_buffer(m_handle);
261  }
262 
267  const uint8_t *get_buffer() const noexcept
268  {
269  return k4a_image_get_buffer(m_handle);
270  }
271 
276  size_t get_size() const noexcept
277  {
278  return k4a_image_get_size(m_handle);
279  }
280 
286  {
287  return k4a_image_get_format(m_handle);
288  }
289 
294  int get_width_pixels() const noexcept
295  {
296  return k4a_image_get_width_pixels(m_handle);
297  }
298 
303  int get_height_pixels() const noexcept
304  {
305  return k4a_image_get_height_pixels(m_handle);
306  }
307 
312  int get_stride_bytes() const noexcept
313  {
314  return k4a_image_get_stride_bytes(m_handle);
315  }
316 
321  std::chrono::microseconds get_device_timestamp() const noexcept
322  {
323  return std::chrono::microseconds(k4a_image_get_device_timestamp_usec(m_handle));
324  }
325 
330  std::chrono::nanoseconds get_system_timestamp() const noexcept
331  {
332  return std::chrono::nanoseconds(k4a_image_get_system_timestamp_nsec(m_handle));
333  }
334 
339  std::chrono::microseconds get_exposure() const noexcept
340  {
341  return std::chrono::microseconds(k4a_image_get_exposure_usec(m_handle));
342  }
343 
348  uint32_t get_white_balance() const noexcept
349  {
350  return k4a_image_get_white_balance(m_handle);
351  }
352 
357  uint32_t get_iso_speed() const noexcept
358  {
359  return k4a_image_get_iso_speed(m_handle);
360  }
361 
366  void set_timestamp(std::chrono::microseconds timestamp) noexcept
367  {
368  k4a_image_set_device_timestamp_usec(m_handle, internal::clamp_cast<uint64_t>(timestamp.count()));
369  }
370 
375  void set_exposure_time(std::chrono::microseconds exposure) noexcept
376  {
377  k4a_image_set_exposure_usec(m_handle, internal::clamp_cast<uint64_t>(exposure.count()));
378  }
379 
384  void set_white_balance(uint32_t white_balance) noexcept
385  {
386  k4a_image_set_white_balance(m_handle, white_balance);
387  }
388 
393  void set_iso_speed(uint32_t iso_speed) noexcept
394  {
395  k4a_image_set_iso_speed(m_handle, iso_speed);
396  }
397 
398 private:
399  k4a_image_t m_handle;
400 };
401 
407 class capture
408 {
409 public:
415  capture(k4a_capture_t handle = nullptr) noexcept : m_handle(handle) {}
416 
419  capture(const capture &other) noexcept : m_handle(other.m_handle)
420  {
421  if (m_handle != nullptr)
422  {
423  k4a_capture_reference(m_handle);
424  }
425  }
426 
429  capture(capture &&other) noexcept : m_handle(other.m_handle)
430  {
431  other.m_handle = nullptr;
432  }
433 
434  ~capture()
435  {
436  reset();
437  }
438 
441  capture &operator=(const capture &other) noexcept
442  {
443  if (this != &other)
444  {
445  reset();
446  m_handle = other.m_handle;
447  if (m_handle != nullptr)
448  {
449  k4a_capture_reference(m_handle);
450  }
451  }
452  return *this;
453  }
454 
457  capture &operator=(capture &&other) noexcept
458  {
459  if (this != &other)
460  {
461  reset();
462  m_handle = other.m_handle;
463  other.m_handle = nullptr;
464  }
465  return *this;
466  }
467 
470  capture &operator=(std::nullptr_t) noexcept
471  {
472  reset();
473  return *this;
474  }
475 
478  bool operator==(const capture &other) const noexcept
479  {
480  return m_handle == other.m_handle;
481  }
482 
485  bool operator==(std::nullptr_t) const noexcept
486  {
487  return m_handle == nullptr;
488  }
489 
492  bool operator!=(const capture &other) const noexcept
493  {
494  return m_handle != other.m_handle;
495  }
496 
499  bool operator!=(std::nullptr_t) const noexcept
500  {
501  return m_handle != nullptr;
502  }
503 
506  operator bool() const noexcept
507  {
508  return m_handle != nullptr;
509  }
510 
518  k4a_capture_t handle() const noexcept
519  {
520  return m_handle;
521  }
522 
525  void reset() noexcept
526  {
527  if (m_handle != nullptr)
528  {
529  k4a_capture_release(m_handle);
530  m_handle = nullptr;
531  }
532  }
533 
538  image get_color_image() const noexcept
539  {
540  return image(k4a_capture_get_color_image(m_handle));
541  }
542 
547  image get_depth_image() const noexcept
548  {
549  return image(k4a_capture_get_depth_image(m_handle));
550  }
551 
556  image get_ir_image() const noexcept
557  {
558  return image(k4a_capture_get_ir_image(m_handle));
559  }
560 
565  void set_color_image(const image &color_image) noexcept
566  {
567  k4a_capture_set_color_image(m_handle, color_image.handle());
568  }
569 
574  void set_depth_image(const image &depth_image) noexcept
575  {
576  k4a_capture_set_depth_image(m_handle, depth_image.handle());
577  }
578 
583  void set_ir_image(const image &ir_image) noexcept
584  {
585  k4a_capture_set_ir_image(m_handle, ir_image.handle());
586  }
587 
592  void set_temperature_c(float temperature_c) noexcept
593  {
594  k4a_capture_set_temperature_c(m_handle, temperature_c);
595  }
596 
601  float get_temperature_c() const noexcept
602  {
603  return k4a_capture_get_temperature_c(m_handle);
604  }
605 
611  static capture create()
612  {
613  k4a_capture_t handle = nullptr;
614  k4a_result_t result = k4a_capture_create(&handle);
615  if (K4A_RESULT_SUCCEEDED != result)
616  {
617  throw error("Failed to create capture!");
618  }
619  return capture(handle);
620  }
621 
622 private:
623  k4a_capture_t m_handle;
624 };
625 
632 {
639  k4a_calibration_type_t source_camera,
640  k4a_calibration_type_t target_camera) const
641  {
642  k4a_float3_t target_point3d;
643  k4a_result_t result =
644  k4a_calibration_3d_to_3d(this, &source_point3d, source_camera, target_camera, &target_point3d);
645 
646  if (K4A_RESULT_SUCCEEDED != result)
647  {
648  throw error("Calibration contained invalid transformation parameters!");
649  }
650  return target_point3d;
651  }
652 
661  bool convert_2d_to_3d(const k4a_float2_t &source_point2d,
662  float source_depth,
663  k4a_calibration_type_t source_camera,
664  k4a_calibration_type_t target_camera,
665  k4a_float3_t *target_point3d) const
666  {
667  int valid = 0;
669  this, &source_point2d, source_depth, source_camera, target_camera, target_point3d, &valid);
670 
671  if (K4A_RESULT_SUCCEEDED != result)
672  {
673  throw error("Calibration contained invalid transformation parameters!");
674  }
675  return static_cast<bool>(valid);
676  }
677 
685  bool convert_3d_to_2d(const k4a_float3_t &source_point3d,
686  k4a_calibration_type_t source_camera,
687  k4a_calibration_type_t target_camera,
688  k4a_float2_t *target_point2d) const
689  {
690  int valid = 0;
691  k4a_result_t result =
692  k4a_calibration_3d_to_2d(this, &source_point3d, source_camera, target_camera, target_point2d, &valid);
693 
694  if (K4A_RESULT_SUCCEEDED != result)
695  {
696  throw error("Calibration contained invalid transformation parameters!");
697  }
698  return static_cast<bool>(valid);
699  }
700 
709  bool convert_2d_to_2d(const k4a_float2_t &source_point2d,
710  float source_depth,
711  k4a_calibration_type_t source_camera,
712  k4a_calibration_type_t target_camera,
713  k4a_float2_t *target_point2d) const
714  {
715  int valid = 0;
717  this, &source_point2d, source_depth, source_camera, target_camera, target_point2d, &valid);
718 
719  if (K4A_RESULT_SUCCEEDED != result)
720  {
721  throw error("Calibration contained invalid transformation parameters!");
722  }
723  return static_cast<bool>(valid);
724  }
725 
733  bool convert_color_2d_to_depth_2d(const k4a_float2_t &source_point2d,
734  const image &depth_image,
735  k4a_float2_t *target_point2d) const
736  {
737  int valid = 0;
738  k4a_result_t result =
739  k4a_calibration_color_2d_to_depth_2d(this, &source_point2d, depth_image.handle(), target_point2d, &valid);
740 
741  if (K4A_RESULT_SUCCEEDED != result)
742  {
743  throw error("Calibration contained invalid transformation parameters!");
744  }
745  return static_cast<bool>(valid);
746  }
747 
753  static calibration get_from_raw(char *raw_calibration,
754  size_t raw_calibration_size,
755  k4a_depth_mode_t target_depth_mode,
756  k4a_color_resolution_t target_color_resolution)
757  {
758  calibration calib;
759  k4a_result_t result = k4a_calibration_get_from_raw(raw_calibration,
760  raw_calibration_size,
761  target_depth_mode,
762  target_color_resolution,
763  &calib);
764 
765  if (K4A_RESULT_SUCCEEDED != result)
766  {
767  throw error("Failed to load calibration from raw calibration blob!");
768  }
769  return calib;
770  }
771 
777  static calibration get_from_raw(uint8_t *raw_calibration,
778  size_t raw_calibration_size,
779  k4a_depth_mode_t target_depth_mode,
780  k4a_color_resolution_t target_color_resolution)
781  {
782  return get_from_raw(reinterpret_cast<char *>(raw_calibration),
783  raw_calibration_size,
784  target_depth_mode,
785  target_color_resolution);
786  }
787 
793  static calibration get_from_raw(std::vector<uint8_t> &raw_calibration,
794  k4a_depth_mode_t target_depth_mode,
795  k4a_color_resolution_t target_color_resolution)
796  {
797  return get_from_raw(reinterpret_cast<char *>(raw_calibration.data()),
798  raw_calibration.size(),
799  target_depth_mode,
800  target_color_resolution);
801  }
802 };
803 
810 {
811 public:
817  m_handle(k4a_transformation_create(&calibration)),
822  {
823  }
824 
830  transformation(k4a_transformation_t handle = nullptr) noexcept : m_handle(handle) {}
831 
834  transformation(transformation &&other) noexcept :
835  m_handle(other.m_handle),
836  m_color_resolution(other.m_color_resolution),
837  m_depth_resolution(other.m_depth_resolution)
838  {
839  other.m_handle = nullptr;
840  }
841 
842  transformation(const transformation &) = delete;
843 
844  ~transformation()
845  {
846  destroy();
847  }
848 
852  {
853  if (this != &other)
854  {
855  destroy();
856  m_handle = other.m_handle;
857  m_color_resolution = other.m_color_resolution;
858  m_depth_resolution = other.m_depth_resolution;
859  other.m_handle = nullptr;
860  }
861 
862  return *this;
863  }
864 
867  transformation &operator=(std::nullptr_t) noexcept
868  {
869  destroy();
870  return *this;
871  }
872 
873  transformation &operator=(const transformation &) = delete;
874 
877  void destroy() noexcept
878  {
879  if (m_handle != nullptr)
880  {
881  k4a_transformation_destroy(m_handle);
882  m_handle = nullptr;
883  }
884  }
885 
892  void depth_image_to_color_camera(const image &depth_image, image *transformed_depth_image) const
893  {
894  k4a_result_t result = k4a_transformation_depth_image_to_color_camera(m_handle,
895  depth_image.handle(),
896  transformed_depth_image->handle());
897  if (K4A_RESULT_SUCCEEDED != result)
898  {
899  throw error("Failed to convert depth map to color camera geometry!");
900  }
901  }
902 
909  image depth_image_to_color_camera(const image &depth_image) const
910  {
911  image transformed_depth_image = image::create(K4A_IMAGE_FORMAT_DEPTH16,
912  m_color_resolution.width,
913  m_color_resolution.height,
914  m_color_resolution.width *
915  static_cast<int32_t>(sizeof(uint16_t)));
916  depth_image_to_color_camera(depth_image, &transformed_depth_image);
917  return transformed_depth_image;
918  }
919 
926  void depth_image_to_color_camera_custom(const image &depth_image,
927  const image &custom_image,
928  image *transformed_depth_image,
929  image *transformed_custom_image,
930  k4a_transformation_interpolation_type_t interpolation_type,
931  uint32_t invalid_custom_value) const
932  {
933  k4a_result_t result = k4a_transformation_depth_image_to_color_camera_custom(m_handle,
934  depth_image.handle(),
935  custom_image.handle(),
936  transformed_depth_image->handle(),
937  transformed_custom_image->handle(),
938  interpolation_type,
939  invalid_custom_value);
940  if (K4A_RESULT_SUCCEEDED != result)
941  {
942  throw error("Failed to convert depth map and custom image to color camera geometry!");
943  }
944  }
945 
952  std::pair<image, image>
954  const image &custom_image,
955  k4a_transformation_interpolation_type_t interpolation_type,
956  uint32_t invalid_custom_value) const
957  {
958  image transformed_depth_image = image::create(K4A_IMAGE_FORMAT_DEPTH16,
959  m_color_resolution.width,
960  m_color_resolution.height,
961  m_color_resolution.width *
962  static_cast<int32_t>(sizeof(uint16_t)));
963  int32_t bytes_per_pixel;
964  switch (custom_image.get_format())
965  {
967  bytes_per_pixel = static_cast<int32_t>(sizeof(int8_t));
968  break;
970  bytes_per_pixel = static_cast<int32_t>(sizeof(int16_t));
971  break;
972  default:
973  throw error("Failed to support this format of custom image!");
974  }
975  image transformed_custom_image = image::create(custom_image.get_format(),
976  m_color_resolution.width,
977  m_color_resolution.height,
978  m_color_resolution.width * bytes_per_pixel);
980  custom_image,
981  &transformed_depth_image,
982  &transformed_custom_image,
983  interpolation_type,
984  invalid_custom_value);
985  return { std::move(transformed_depth_image), std::move(transformed_custom_image) };
986  }
987 
994  void color_image_to_depth_camera(const image &depth_image,
995  const image &color_image,
996  image *transformed_color_image) const
997  {
998  k4a_result_t result = k4a_transformation_color_image_to_depth_camera(m_handle,
999  depth_image.handle(),
1000  color_image.handle(),
1001  transformed_color_image->handle());
1002  if (K4A_RESULT_SUCCEEDED != result)
1003  {
1004  throw error("Failed to convert color image to depth camera geometry!");
1005  }
1006  }
1007 
1014  image color_image_to_depth_camera(const image &depth_image, const image &color_image) const
1015  {
1016  image transformed_color_image = image::create(K4A_IMAGE_FORMAT_COLOR_BGRA32,
1017  m_depth_resolution.width,
1018  m_depth_resolution.height,
1019  m_depth_resolution.width * 4 *
1020  static_cast<int32_t>(sizeof(uint8_t)));
1021  color_image_to_depth_camera(depth_image, color_image, &transformed_color_image);
1022  return transformed_color_image;
1023  }
1024 
1031  void depth_image_to_point_cloud(const image &depth_image, k4a_calibration_type_t camera, image *xyz_image) const
1032  {
1033  k4a_result_t result =
1034  k4a_transformation_depth_image_to_point_cloud(m_handle, depth_image.handle(), camera, xyz_image->handle());
1035  if (K4A_RESULT_SUCCEEDED != result)
1036  {
1037  throw error("Failed to transform depth image to point cloud!");
1038  }
1039  }
1040 
1048  {
1050  depth_image.get_width_pixels(),
1051  depth_image.get_height_pixels(),
1052  depth_image.get_width_pixels() * 3 * static_cast<int32_t>(sizeof(int16_t)));
1053  depth_image_to_point_cloud(depth_image, camera, &xyz_image);
1054  return xyz_image;
1055  }
1056 
1057 private:
1058  k4a_transformation_t m_handle;
1059  struct resolution
1060  {
1061  int32_t width;
1062  int32_t height;
1063  };
1064  resolution m_color_resolution;
1065  resolution m_depth_resolution;
1066 };
1067 
1073 class device
1074 {
1075 public:
1081  device(k4a_device_t handle = nullptr) noexcept : m_handle(handle) {}
1082 
1085  device(device &&dev) noexcept : m_handle(dev.m_handle)
1086  {
1087  dev.m_handle = nullptr;
1088  }
1089 
1090  device(const device &) = delete;
1091 
1092  ~device()
1093  {
1094  close();
1095  }
1096 
1097  device &operator=(const device &) = delete;
1098 
1101  device &operator=(device &&dev) noexcept
1102  {
1103  if (this != &dev)
1104  {
1105  close();
1106  m_handle = dev.m_handle;
1107  dev.m_handle = nullptr;
1108  }
1109  return *this;
1110  }
1111 
1114  operator bool() const noexcept
1115  {
1116  return m_handle != nullptr;
1117  }
1118 
1124  k4a_device_t handle() const noexcept
1125  {
1126  return m_handle;
1127  }
1128 
1133  void close() noexcept
1134  {
1135  if (m_handle != nullptr)
1136  {
1137  k4a_device_close(m_handle);
1138  m_handle = nullptr;
1139  }
1140  }
1141 
1147  bool get_capture(capture *cap, std::chrono::milliseconds timeout)
1148  {
1149  k4a_capture_t capture_handle = nullptr;
1150  int32_t timeout_ms = internal::clamp_cast<int32_t>(timeout.count());
1151  k4a_wait_result_t result = k4a_device_get_capture(m_handle, &capture_handle, timeout_ms);
1152  if (result == K4A_WAIT_RESULT_FAILED)
1153  {
1154  throw error("Failed to get capture from device!");
1155  }
1156  else if (result == K4A_WAIT_RESULT_TIMEOUT)
1157  {
1158  return false;
1159  }
1160 
1161  *cap = capture(capture_handle);
1162  return true;
1163  }
1164 
1171  {
1172  return get_capture(cap, std::chrono::milliseconds(K4A_WAIT_INFINITE));
1173  }
1174 
1180  bool get_imu_sample(k4a_imu_sample_t *imu_sample, std::chrono::milliseconds timeout)
1181  {
1182  int32_t timeout_ms = internal::clamp_cast<int32_t>(timeout.count());
1183  k4a_wait_result_t result = k4a_device_get_imu_sample(m_handle, imu_sample, timeout_ms);
1184  if (result == K4A_WAIT_RESULT_FAILED)
1185  {
1186  throw error("Failed to get IMU sample from device!");
1187  }
1188  else if (result == K4A_WAIT_RESULT_TIMEOUT)
1189  {
1190  return false;
1191  }
1192 
1193  return true;
1194  }
1195 
1202  {
1203  return get_imu_sample(imu_sample, std::chrono::milliseconds(K4A_WAIT_INFINITE));
1204  }
1205 
1211  void start_cameras(const k4a_device_configuration_t *configuration)
1212  {
1213  k4a_result_t result = k4a_device_start_cameras(m_handle, configuration);
1214  if (K4A_RESULT_SUCCEEDED != result)
1215  {
1216  throw error("Failed to start cameras!");
1217  }
1218  }
1219 
1224  void stop_cameras() noexcept
1225  {
1226  k4a_device_stop_cameras(m_handle);
1227  }
1228 
1234  void start_imu()
1235  {
1236  k4a_result_t result = k4a_device_start_imu(m_handle);
1237  if (K4A_RESULT_SUCCEEDED != result)
1238  {
1239  throw error("Failed to start IMU!");
1240  }
1241  }
1242 
1247  void stop_imu() noexcept
1248  {
1249  k4a_device_stop_imu(m_handle);
1250  }
1251 
1257  std::string get_serialnum() const
1258  {
1259  std::string serialnum;
1260  size_t buffer = 0;
1261  k4a_buffer_result_t result = k4a_device_get_serialnum(m_handle, &serialnum[0], &buffer);
1262 
1263  if (result == K4A_BUFFER_RESULT_TOO_SMALL && buffer > 1)
1264  {
1265  serialnum.resize(buffer);
1266  result = k4a_device_get_serialnum(m_handle, &serialnum[0], &buffer);
1267  if (result == K4A_BUFFER_RESULT_SUCCEEDED && serialnum[buffer - 1] == 0)
1268  {
1269  // std::string expects there to not be as null terminator at the end of its data but
1270  // k4a_device_get_serialnum adds a null terminator, so we drop the last character of the string after we
1271  // get the result back.
1272  serialnum.resize(buffer - 1);
1273  }
1274  }
1275 
1276  if (result != K4A_BUFFER_RESULT_SUCCEEDED)
1277  {
1278  throw error("Failed to read device serial number!");
1279  }
1280 
1281  return serialnum;
1282  }
1283 
1290  {
1291  k4a_result_t result = k4a_device_get_color_control(m_handle, command, mode, value);
1292  if (K4A_RESULT_SUCCEEDED != result)
1293  {
1294  throw error("Failed to read color control!");
1295  }
1296  }
1297 
1304  {
1305  k4a_result_t result = k4a_device_set_color_control(m_handle, command, mode, value);
1306  if (K4A_RESULT_SUCCEEDED != result)
1307  {
1308  throw error("Failed to set color control!");
1309  }
1310  }
1311 
1317  std::vector<uint8_t> get_raw_calibration() const
1318  {
1319  std::vector<uint8_t> calibration;
1320  size_t buffer = 0;
1321  k4a_buffer_result_t result = k4a_device_get_raw_calibration(m_handle, &calibration[0], &buffer);
1322 
1323  if (result == K4A_BUFFER_RESULT_TOO_SMALL && buffer > 1)
1324  {
1325  calibration.resize(buffer);
1326  result = k4a_device_get_raw_calibration(m_handle, &calibration[0], &buffer);
1327  }
1328 
1329  if (result != K4A_BUFFER_RESULT_SUCCEEDED)
1330  {
1331  throw error("Failed to read raw device calibration!");
1332  }
1333 
1334  return calibration;
1335  }
1336 
1343  {
1344  calibration calib;
1345  k4a_result_t result = k4a_device_get_calibration(m_handle, depth_mode, color_resolution, &calib);
1346 
1347  if (K4A_RESULT_SUCCEEDED != result)
1348  {
1349  throw error("Failed to read device calibration!");
1350  }
1351  return calib;
1352  }
1353 
1360  {
1361  bool sync_in_jack_connected, sync_out_jack_connected;
1362  k4a_result_t result = k4a_device_get_sync_jack(m_handle, &sync_in_jack_connected, &sync_out_jack_connected);
1363 
1364  if (K4A_RESULT_SUCCEEDED != result)
1365  {
1366  throw error("Failed to read sync jack status!");
1367  }
1368  return sync_in_jack_connected;
1369  }
1370 
1377  {
1378  bool sync_in_jack_connected, sync_out_jack_connected;
1379  k4a_result_t result = k4a_device_get_sync_jack(m_handle, &sync_in_jack_connected, &sync_out_jack_connected);
1380 
1381  if (K4A_RESULT_SUCCEEDED != result)
1382  {
1383  throw error("Failed to read sync jack status!");
1384  }
1385  return sync_out_jack_connected;
1386  }
1387 
1394  {
1395  k4a_hardware_version_t version;
1396  k4a_result_t result = k4a_device_get_version(m_handle, &version);
1397 
1398  if (K4A_RESULT_SUCCEEDED != result)
1399  {
1400  throw error("Failed to read device firmware information!");
1401  }
1402  return version;
1403  }
1404 
1410  static device open(uint32_t index)
1411  {
1412  k4a_device_t handle = nullptr;
1413  k4a_result_t result = k4a_device_open(index, &handle);
1414 
1415  if (K4A_RESULT_SUCCEEDED != result)
1416  {
1417  throw error("Failed to open device!");
1418  }
1419  return device(handle);
1420  }
1421 
1426  static uint32_t get_installed_count() noexcept
1427  {
1428  return k4a_device_get_installed_count();
1429  }
1430 
1431 private:
1432  k4a_device_t m_handle;
1433 };
1434 
1439 } // namespace k4a
1440 
1441 #endif
bool is_sync_out_connected() const
Get the device jack status for the synchronization out connector Throws error on failure.
Definition: k4a.hpp:1376
Calibration type representing device calibration.
Definition: k4atypes.h:1099
The result was successful.
Definition: k4atypes.h:233
transformation(const k4a_calibration_t &calibration) noexcept
Creates a transformation associated with calibration.
Definition: k4a.hpp:816
void reset() noexcept
Releases the underlying k4a_image_t; the image is set to invalid.
Definition: k4a.hpp:198
k4a_float3_t convert_3d_to_3d(const k4a_float3_t &source_point3d, k4a_calibration_type_t source_camera, k4a_calibration_type_t target_camera) const
Transform a 3d point of a source coordinate system into a 3d point of the target coordinate system...
Definition: k4a.hpp:638
capture & operator=(capture &&other) noexcept
Moves another capture into this capture; other is set to invalid.
Definition: k4a.hpp:457
transformation(transformation &&other) noexcept
Moves another tranformation into a new transformation.
Definition: k4a.hpp:834
void set_exposure_time(std::chrono::microseconds exposure) noexcept
Set the image&#39;s exposure time in microseconds (color images only)
Definition: k4a.hpp:375
int resolution_height
Resolution height of the calibration sensor.
Definition: k4atypes.h:1087
Color image type BGRA32.
Definition: k4atypes.h:386
k4a_result_t k4a_calibration_color_2d_to_depth_2d(const k4a_calibration_t *calibration, const k4a_float2_t *source_point2d, const k4a_image_t depth_image, k4a_float2_t *target_point2d, int *valid)
Transform a 2D pixel coordinate from color camera into a 2D pixel coordinate of the depth camera...
const uint8_t * get_buffer() const noexcept
Get the image buffer.
Definition: k4a.hpp:267
Structure to define hardware version.
Definition: k4atypes.h:1141
image depth_image_to_color_camera(const image &depth_image) const
Transforms the depth map into the geometry of the color camera.
Definition: k4a.hpp:909
int get_stride_bytes() const noexcept
Get the image stride in bytes.
Definition: k4a.hpp:312
k4a_result_t
Result code returned by Azure Kinect APIs.
Definition: k4atypes.h:217
static calibration get_from_raw(char *raw_calibration, size_t raw_calibration_size, k4a_depth_mode_t target_depth_mode, k4a_color_resolution_t target_color_resolution)
Get the camera calibration for a device from a raw calibration blob.
Definition: k4a.hpp:753
Exception type thrown when a K4A API call fails.
Definition: k4a.hpp:33
void set_color_image(const image &color_image) noexcept
Set / add a color image to the capture.
Definition: k4a.hpp:565
void set_depth_image(const image &depth_image) noexcept
Set / add a depth image to the capture.
Definition: k4a.hpp:574
size_t get_size() const noexcept
Get the image buffer size in bytes.
Definition: k4a.hpp:276
k4a_depth_mode_t
Depth sensor capture modes.
Definition: k4atypes.h:290
Handle to an Azure Kinect capture.
Definition: k4atypes.h:122
bool operator==(std::nullptr_t) const noexcept
Returns false if the capture is valid, true otherwise.
Definition: k4a.hpp:485
static calibration get_from_raw(uint8_t *raw_calibration, size_t raw_calibration_size, k4a_depth_mode_t target_depth_mode, k4a_color_resolution_t target_color_resolution)
Get the camera calibration for a device from a raw calibration blob.
Definition: k4a.hpp:777
uint32_t get_white_balance() const noexcept
Get the image white balance in Kelvin (color images only)
Definition: k4a.hpp:348
k4a_buffer_result_t
Result code returned by Azure Kinect APIs.
Definition: k4atypes.h:231
static device open(uint32_t index)
Open a k4a device.
Definition: k4a.hpp:1410
capture & operator=(const capture &other) noexcept
Sets capture to a shallow copy of other.
Definition: k4a.hpp:441
bool get_imu_sample(k4a_imu_sample_t *imu_sample)
Reads an IMU sample.
Definition: k4a.hpp:1201
void depth_image_to_color_camera(const image &depth_image, image *transformed_depth_image) const
Transforms the depth map into the geometry of the color camera.
Definition: k4a.hpp:892
Wrapper for k4a_transformation_t.
Definition: k4a.hpp:809
The operation timed out.
Definition: k4atypes.h:250
bool get_capture(capture *cap)
Reads a sensor capture into cap.
Definition: k4a.hpp:1170
image(k4a_image_t handle=nullptr) noexcept
Creates an image from a k4a_image_t.
Definition: k4a.hpp:88
device & operator=(device &&dev) noexcept
Moves another device into this device; other is set to invalid.
Definition: k4a.hpp:1101
std::vector< uint8_t > get_raw_calibration() const
Get the raw calibration blob for the entire K4A device.
Definition: k4a.hpp:1317
int get_width_pixels() const noexcept
Get the image width in pixels.
Definition: k4a.hpp:294
IMU sample.
Definition: k4atypes.h:1199
std::chrono::microseconds get_exposure() const noexcept
Get the image exposure time in microseconds.
Definition: k4a.hpp:339
void start_cameras(const k4a_device_configuration_t *configuration)
Starts the K4A device&#39;s cameras Throws error on failure.
Definition: k4a.hpp:1211
bool operator!=(const capture &other) const noexcept
Returns true if two captures wrap different k4a_capture_t instances, false otherwise.
Definition: k4a.hpp:492
bool convert_2d_to_2d(const k4a_float2_t &source_point2d, float source_depth, k4a_calibration_type_t source_camera, k4a_calibration_type_t target_camera, k4a_float2_t *target_point2d) const
Transform a 2d pixel coordinate with an associated depth value of the source camera into a 2d pixel c...
Definition: k4a.hpp:709
k4a_transformation_interpolation_type_t
Transformation interpolation type.
Definition: k4atypes.h:459
transformation & operator=(std::nullptr_t) noexcept
Invalidates this transformation.
Definition: k4a.hpp:867
Definition: k4a.hpp:20
std::chrono::microseconds get_device_timestamp() const noexcept
Get the image&#39;s device timestamp in microseconds.
Definition: k4a.hpp:321
k4a_result_t k4a_calibration_3d_to_2d(const k4a_calibration_t *calibration, const k4a_float3_t *source_point3d_mm, const k4a_calibration_type_t source_camera, const k4a_calibration_type_t target_camera, k4a_float2_t *target_point2d, int *valid)
Transform a 3D point of a source coordinate system into a 2D pixel coordinate of the target camera...
calibration get_calibration(k4a_depth_mode_t depth_mode, k4a_color_resolution_t color_resolution) const
Get the camera calibration for the entire K4A device, which is used for all transformation functions...
Definition: k4a.hpp:1342
void set_iso_speed(uint32_t iso_speed) noexcept
Set the ISO speed of the image (color images only)
Definition: k4a.hpp:393
void set_ir_image(const image &ir_image) noexcept
Set / add an IR image to the capture.
Definition: k4a.hpp:583
image & operator=(const image &other) noexcept
Sets image to a shallow copy of other.
Definition: k4a.hpp:114
bool get_imu_sample(k4a_imu_sample_t *imu_sample, std::chrono::milliseconds timeout)
Reads an IMU sample.
Definition: k4a.hpp:1180
capture(capture &&other) noexcept
Moves another capture into a new capture.
Definition: k4a.hpp:429
std::chrono::nanoseconds get_system_timestamp() const noexcept
Get the image&#39;s system timestamp in nanoseconds.
Definition: k4a.hpp:330
bool is_sync_in_connected() const
Get the device jack status for the synchronization in connector Throws error on failure.
Definition: k4a.hpp:1359
Single channel image type CUSTOM16.
Definition: k4atypes.h:435
k4a_calibration_type_t
Calibration types.
Definition: k4atypes.h:658
image get_color_image() const noexcept
Get the color image associated with the capture.
Definition: k4a.hpp:538
static uint32_t get_installed_count() noexcept
Gets the number of connected devices.
Definition: k4a.hpp:1426
bool operator!=(std::nullptr_t) const noexcept
Returns true if the capture is valid, false otherwise.
Definition: k4a.hpp:499
void get_color_control(k4a_color_control_command_t command, k4a_color_control_mode_t *mode, int32_t *value) const
Get the K4A color sensor control value Throws error on failure.
Definition: k4a.hpp:1289
static image create_from_buffer(k4a_image_format_t format, int width_pixels, int height_pixels, int stride_bytes, uint8_t *buffer, size_t buffer_size, k4a_memory_destroy_cb_t *buffer_release_cb, void *buffer_release_cb_context)
Create an image from a pre-allocated buffer Throws error on failure.
Definition: k4a.hpp:228
k4a_result_t k4a_calibration_2d_to_2d(const k4a_calibration_t *calibration, const k4a_float2_t *source_point2d, const float source_depth_mm, const k4a_calibration_type_t source_camera, const k4a_calibration_type_t target_camera, k4a_float2_t *target_point2d, int *valid)
Transform a 2D pixel coordinate with an associated depth value of the source camera into a 2D pixel c...
void set_timestamp(std::chrono::microseconds timestamp) noexcept
Set the image&#39;s timestamp in microseconds.
Definition: k4a.hpp:366
bool convert_3d_to_2d(const k4a_float3_t &source_point3d, k4a_calibration_type_t source_camera, k4a_calibration_type_t target_camera, k4a_float2_t *target_point2d) const
Transform a 3d point of a source coordinate system into a 2d pixel coordinate of the target camera...
Definition: k4a.hpp:685
Wrapper for k4a_capture_t.
Definition: k4a.hpp:407
void depth_image_to_color_camera_custom(const image &depth_image, const image &custom_image, image *transformed_depth_image, image *transformed_custom_image, k4a_transformation_interpolation_type_t interpolation_type, uint32_t invalid_custom_value) const
Transforms depth map and a custom image into the geometry of the color camera.
Definition: k4a.hpp:926
k4a_result_t k4a_calibration_3d_to_3d(const k4a_calibration_t *calibration, const k4a_float3_t *source_point3d_mm, const k4a_calibration_type_t source_camera, const k4a_calibration_type_t target_camera, k4a_float3_t *target_point3d_mm)
Transform a 3D point of a source coordinate system into a 3D point of the target coordinate system...
Three dimensional floating point vector.
Definition: k4atypes.h:1179
bool operator!=(std::nullptr_t) const noexcept
Returns true if the image is valid, false otherwise.
Definition: k4a.hpp:172
capture(k4a_capture_t handle=nullptr) noexcept
Creates a capture from a k4a_capture_t Takes ownership of the handle, i.e.
Definition: k4a.hpp:415
k4a_device_t handle() const noexcept
Returns the underlying k4a_device_t handle.
Definition: k4a.hpp:1124
static capture create()
Create an empty capture object.
Definition: k4a.hpp:611
transformation(k4a_transformation_t handle=nullptr) noexcept
Creates a transformation from a k4a_transformation_t Takes ownership of the handle, i.e.
Definition: k4a.hpp:830
k4a_color_control_mode_t
Color sensor control mode.
Definition: k4atypes.h:622
Single channel image type CUSTOM8.
Definition: k4atypes.h:424
std::string get_serialnum() const
Get the K4A device serial number Throws error on failure.
Definition: k4a.hpp:1257
bool operator!=(const image &other) const noexcept
Returns true if two images wrap different k4a_image_t instances, false otherwise. ...
Definition: k4a.hpp:165
capture(const capture &other) noexcept
Creates a shallow copy of another capture.
Definition: k4a.hpp:419
k4a_image_t handle() const noexcept
Returns the underlying k4a_image_t handle.
Definition: k4a.hpp:191
k4a_image_format_t get_format() const noexcept
Get the image format of the image.
Definition: k4a.hpp:285
std::pair< image, image > depth_image_to_color_camera_custom(const image &depth_image, const image &custom_image, k4a_transformation_interpolation_type_t interpolation_type, uint32_t invalid_custom_value) const
Transforms depth map and a custom image into the geometry of the color camera.
Definition: k4a.hpp:953
int get_height_pixels() const noexcept
Get the image height in pixels.
Definition: k4a.hpp:303
Handle to an Azure Kinect transformation context.
Definition: k4atypes.h:195
image color_image_to_depth_camera(const image &depth_image, const image &color_image) const
Transforms the color image into the geometry of the depth camera.
Definition: k4a.hpp:1014
Depth image type DEPTH16.
Definition: k4atypes.h:398
k4a_color_resolution_t
Color sensor resolutions.
Definition: k4atypes.h:309
float get_temperature_c() const noexcept
Get temperature (in Celsius) associated with the capture.
Definition: k4a.hpp:601
void() k4a_memory_destroy_cb_t(void *buffer, void *context)
Callback function for a memory object being destroyed.
Definition: k4atypes.h:868
void set_white_balance(uint32_t white_balance) noexcept
Set the white balance of the image (color images only)
Definition: k4a.hpp:384
k4a_result_t k4a_calibration_2d_to_3d(const k4a_calibration_t *calibration, const k4a_float2_t *source_point2d, const float source_depth_mm, const k4a_calibration_type_t source_camera, const k4a_calibration_type_t target_camera, k4a_float3_t *target_point3d_mm, int *valid)
Transform a 2D pixel coordinate with an associated depth value of the source camera into a 3D point o...
#define K4A_WAIT_INFINITE
An infinite wait time for functions that take a timeout parameter.
Definition: k4atypes.h:1240
The result was successful.
Definition: k4atypes.h:219
device(k4a_device_t handle=nullptr) noexcept
Creates a device from a k4a_device_t Takes ownership of the handle, i.e.
Definition: k4a.hpp:1081
void destroy() noexcept
Invalidates this transformation.
Definition: k4a.hpp:877
void stop_imu() noexcept
Stops the K4A IMU.
Definition: k4a.hpp:1247
uint32_t get_iso_speed() const noexcept
Get the image&#39;s ISO speed (color images only)
Definition: k4a.hpp:357
k4a_calibration_camera_t color_camera_calibration
Color camera calibration.
Definition: k4atypes.h:1103
image & operator=(image &&other) noexcept
Moves another image into this image; other is set to invalid.
Definition: k4a.hpp:130
Wrapper for k4a_image_t.
Definition: k4a.hpp:80
void set_temperature_c(float temperature_c) noexcept
Set the temperature associated with the capture in Celsius.
Definition: k4a.hpp:592
image get_ir_image() const noexcept
Get the IR image associated with the capture.
Definition: k4a.hpp:556
bool convert_2d_to_3d(const k4a_float2_t &source_point2d, float source_depth, k4a_calibration_type_t source_camera, k4a_calibration_type_t target_camera, k4a_float3_t *target_point3d) const
Transform a 2d pixel coordinate with an associated depth value of the source camera into a 3d point o...
Definition: k4a.hpp:661
k4a_capture_t handle() const noexcept
Returns the underlying k4a_capture_t handle.
Definition: k4a.hpp:518
device(device &&dev) noexcept
Moves another device into a new device.
Definition: k4a.hpp:1085
int resolution_width
Resolution width of the calibration sensor.
Definition: k4atypes.h:1086
image & operator=(std::nullptr_t) noexcept
Invalidates this image.
Definition: k4a.hpp:143
k4a_calibration_camera_t depth_camera_calibration
Depth camera calibration.
Definition: k4atypes.h:1101
Handle to an Azure Kinect device.
Definition: k4atypes.h:66
uint8_t * get_buffer() noexcept
Get the image buffer.
Definition: k4a.hpp:258
void color_image_to_depth_camera(const image &depth_image, const image &color_image, image *transformed_color_image) const
Transforms the color image into the geometry of the depth camera.
Definition: k4a.hpp:994
Two dimensional floating point vector.
Definition: k4atypes.h:1160
bool operator==(std::nullptr_t) const noexcept
Returns false if the image is valid, true otherwise.
Definition: k4a.hpp:158
Handle to an Azure Kinect image.
Definition: k4atypes.h:173
image(image &&other) noexcept
Moves another image into a new image.
Definition: k4a.hpp:102
image(const image &other) noexcept
Creates a shallow copy of another image.
Definition: k4a.hpp:92
bool get_capture(capture *cap, std::chrono::milliseconds timeout)
Reads a sensor capture into cap.
Definition: k4a.hpp:1147
Wrapper for k4a_device_t.
Definition: k4a.hpp:1073
void depth_image_to_point_cloud(const image &depth_image, k4a_calibration_type_t camera, image *xyz_image) const
Transforms the depth image into 3 planar images representing X, Y and Z-coordinates of corresponding ...
Definition: k4a.hpp:1031
Configuration parameters for an Azure Kinect device.
Definition: k4atypes.h:917
The result was a failure.
Definition: k4atypes.h:249
void stop_cameras() noexcept
Stops the K4A device&#39;s cameras.
Definition: k4a.hpp:1224
The input buffer was too small.
Definition: k4atypes.h:235
capture & operator=(std::nullptr_t) noexcept
Invalidates this capture.
Definition: k4a.hpp:470
bool operator==(const capture &other) const noexcept
Returns true if two captures refer to the same k4a_capture_t, false otherwise.
Definition: k4a.hpp:478
void set_color_control(k4a_color_control_command_t command, k4a_color_control_mode_t mode, int32_t value)
Set the K4A color sensor control value Throws error on failure.
Definition: k4a.hpp:1303
bool operator==(const image &other) const noexcept
Returns true if two images refer to the same k4a_image_t, false otherwise.
Definition: k4a.hpp:151
k4a_color_control_command_t
Color sensor control commands.
Definition: k4atypes.h:503
Custom image format.
Definition: k4atypes.h:445
k4a_hardware_version_t get_version() const
Get the version numbers of the K4A subsystems&#39; firmware Throws error on failure.
Definition: k4a.hpp:1393
static image create(k4a_image_format_t format, int width_pixels, int height_pixels, int stride_bytes)
Create a blank image Throws error on failure.
Definition: k4a.hpp:212
bool convert_color_2d_to_depth_2d(const k4a_float2_t &source_point2d, const image &depth_image, k4a_float2_t *target_point2d) const
Transform a 2D pixel coordinate from color camera into a 2D pixel coordinate of the depth camera...
Definition: k4a.hpp:733
Wrapper for k4a_calibration_t.
Definition: k4a.hpp:631
void start_imu()
Starts the K4A IMU Throws error on failure.
Definition: k4a.hpp:1234
k4a_wait_result_t
Result code returned by Azure Kinect APIs.
Definition: k4atypes.h:246
transformation & operator=(transformation &&other) noexcept
Moves another image into this image; other is set to invalid.
Definition: k4a.hpp:851
k4a_image_format_t
Image format type.
Definition: k4atypes.h:332
void close() noexcept
Closes a k4a device.
Definition: k4a.hpp:1133
image depth_image_to_point_cloud(const image &depth_image, k4a_calibration_type_t camera) const
Transforms the depth image into 3 planar images representing X, Y and Z-coordinates of corresponding ...
Definition: k4a.hpp:1047
image get_depth_image() const noexcept
Get the depth image associated with the capture.
Definition: k4a.hpp:547
static calibration get_from_raw(std::vector< uint8_t > &raw_calibration, k4a_depth_mode_t target_depth_mode, k4a_color_resolution_t target_color_resolution)
Get the camera calibration for a device from a raw calibration blob.
Definition: k4a.hpp:793
void reset() noexcept
Releases the underlying k4a_capture_t; the capture is set to invalid.
Definition: k4a.hpp:525