32 #include <opencv2/imgproc/types_c.h>
36 #include <k4arecord/playback.h>
55 Camera(imageRate, localTransform)
59 config_(K4A_DEVICE_CONFIG_INIT_DISABLE_ALL),
60 transformationHandle_(
NULL),
62 playbackHandle_(
NULL),
75 const std::string & fileName,
78 Camera(imageRate, localTransform)
82 transformationHandle_(
NULL),
84 playbackHandle_(
NULL),
105 if (playbackHandle_ !=
NULL)
107 k4a_playback_close((k4a_playback_t)playbackHandle_);
108 playbackHandle_ =
NULL;
110 else if (deviceHandle_ !=
NULL)
112 k4a_device_stop_imu(deviceHandle_);
114 k4a_device_stop_cameras(deviceHandle_);
115 k4a_device_close(deviceHandle_);
116 deviceHandle_ =
NULL;
117 config_ = K4A_DEVICE_CONFIG_INIT_DISABLE_ALL;
120 if (transformationHandle_ !=
NULL)
122 k4a_transformation_destroy((k4a_transformation_t)transformationHandle_);
123 transformationHandle_ =
NULL;
125 previousStamp_ = 0.0;
126 timestampOffset_ = 0.0;
133 rgb_resolution_ = rgb_resolution;
134 framerate_ = framerate;
135 depth_resolution_ = depth_resolution;
136 UINFO(
"setPreferences(): %i %i %i", rgb_resolution, framerate, depth_resolution);
147 bool CameraK4A::init(
const std::string & calibrationFolder,
const std::string & cameraName)
151 if (!fileName_.empty())
155 if (k4a_playback_open(fileName_.c_str(), (k4a_playback_t*)&playbackHandle_) != K4A_RESULT_SUCCEEDED)
157 UERROR(
"Failed to open recording \"%s\"", fileName_.c_str());
161 uint64_t recording_length = k4a_playback_get_recording_length_usec((k4a_playback_t)playbackHandle_);
162 UINFO(
"Recording is %lld seconds long", recording_length / 1000000);
164 k4a_record_configuration_t
config;
165 if(k4a_playback_get_record_configuration((k4a_playback_t)playbackHandle_, &
config))
167 UERROR(
"Failed to get record configuration");
174 config.camera_fps == K4A_FRAMES_PER_SECOND_5?5:
175 config.camera_fps == K4A_FRAMES_PER_SECOND_15?15:30;
176 UINFO(
"Recording framerate is %d fps", rate);
180 if (k4a_playback_get_calibration((k4a_playback_t)playbackHandle_, &calibration_))
182 UERROR(
"Failed to get calibration");
188 else if (deviceId_ >= 0)
190 if(deviceHandle_!=
NULL)
195 switch(rgb_resolution_)
197 case 0: config_.color_resolution = K4A_COLOR_RESOLUTION_720P;
break;
198 case 1: config_.color_resolution = K4A_COLOR_RESOLUTION_1080P;
break;
199 case 2: config_.color_resolution = K4A_COLOR_RESOLUTION_1440P;
break;
200 case 3: config_.color_resolution = K4A_COLOR_RESOLUTION_1536P;
break;
201 case 4: config_.color_resolution = K4A_COLOR_RESOLUTION_2160P;
break;
203 default: config_.color_resolution = K4A_COLOR_RESOLUTION_3072P;
break;
208 case 0: config_.camera_fps = K4A_FRAMES_PER_SECOND_5;
break;
209 case 1: config_.camera_fps = K4A_FRAMES_PER_SECOND_15;
break;
211 default: config_.camera_fps = K4A_FRAMES_PER_SECOND_30;
break;
214 switch(depth_resolution_)
216 case 0: config_.depth_mode = K4A_DEPTH_MODE_NFOV_2X2BINNED;
break;
217 case 1: config_.depth_mode = K4A_DEPTH_MODE_NFOV_UNBINNED;
break;
218 case 2: config_.depth_mode = K4A_DEPTH_MODE_WFOV_2X2BINNED;
break;
220 default: config_.depth_mode = K4A_DEPTH_MODE_WFOV_UNBINNED;
break;
224 config_.color_format = K4A_IMAGE_FORMAT_COLOR_BGRA32;
226 int device_count = k4a_device_get_installed_count();
228 if (device_count == 0)
230 UERROR(
"No k4a devices attached!");
233 else if(deviceId_ > device_count)
235 UERROR(
"Cannot select device %d, only %d devices detected.", deviceId_, device_count);
238 UINFO(
"CameraK4A found %d k4a device(s) attached", device_count);
241 if (K4A_FAILED(k4a_device_open(deviceId_, &deviceHandle_)))
243 UERROR(
"Failed to open k4a device!");
248 size_t serial_size = 0;
249 k4a_device_get_serialnum(deviceHandle_,
NULL, &serial_size);
252 char *serial = (
char*)(malloc(serial_size));
253 k4a_device_get_serialnum(deviceHandle_, serial, &serial_size);
254 serial_number_.assign(serial, serial_size);
257 UINFO(
"Opened K4A device: %s", serial_number_.c_str());
260 if (K4A_FAILED(k4a_device_start_cameras(deviceHandle_, &config_)))
262 UERROR(
"Failed to start cameras!");
267 UINFO(
"K4A camera started successfully");
269 if (K4A_FAILED(k4a_device_get_calibration(deviceHandle_, config_.depth_mode, config_.color_resolution, &calibration_)))
271 UERROR(
"k4a_device_get_calibration() failed!");
278 UERROR(
"k4a_device_get_calibration() no file and no valid device id!");
284 cv::Mat
K = cv::Mat::eye(3, 3, CV_64FC1);
285 K.at<
double>(0,0) = calibration_.depth_camera_calibration.intrinsics.parameters.param.fx;
286 K.at<
double>(1,1) = calibration_.depth_camera_calibration.intrinsics.parameters.param.fy;
287 K.at<
double>(0,2) = calibration_.depth_camera_calibration.intrinsics.parameters.param.cx;
288 K.at<
double>(1,2) = calibration_.depth_camera_calibration.intrinsics.parameters.param.cy;
289 cv::Mat
D = cv::Mat::eye(1, 8, CV_64FC1);
290 D.at<
double>(0,0) = calibration_.depth_camera_calibration.intrinsics.parameters.param.k1;
291 D.at<
double>(0,1) = calibration_.depth_camera_calibration.intrinsics.parameters.param.k2;
292 D.at<
double>(0,2) = calibration_.depth_camera_calibration.intrinsics.parameters.param.p1;
293 D.at<
double>(0,3) = calibration_.depth_camera_calibration.intrinsics.parameters.param.p2;
294 D.at<
double>(0,4) = calibration_.depth_camera_calibration.intrinsics.parameters.param.k3;
295 D.at<
double>(0,5) = calibration_.depth_camera_calibration.intrinsics.parameters.param.k4;
296 D.at<
double>(0,6) = calibration_.depth_camera_calibration.intrinsics.parameters.param.k5;
297 D.at<
double>(0,7) = calibration_.depth_camera_calibration.intrinsics.parameters.param.k6;
298 cv::Mat
R = cv::Mat::eye(3, 3, CV_64FC1);
299 cv::Mat
P = cv::Mat::eye(3, 4, CV_64FC1);
300 P.at<
double>(0,0) =
K.at<
double>(0,0);
301 P.at<
double>(1,1) =
K.at<
double>(1,1);
302 P.at<
double>(0,2) =
K.at<
double>(0,2);
303 P.at<
double>(1,2) =
K.at<
double>(1,2);
306 cv::Size(calibration_.depth_camera_calibration.resolution_width, calibration_.depth_camera_calibration.resolution_height),
308 this->getLocalTransform());
312 cv::Mat
K = cv::Mat::eye(3, 3, CV_64FC1);
313 K.at<
double>(0,0) = calibration_.color_camera_calibration.intrinsics.parameters.param.fx;
314 K.at<
double>(1,1) = calibration_.color_camera_calibration.intrinsics.parameters.param.fy;
315 K.at<
double>(0,2) = calibration_.color_camera_calibration.intrinsics.parameters.param.cx;
316 K.at<
double>(1,2) = calibration_.color_camera_calibration.intrinsics.parameters.param.cy;
317 cv::Mat
D = cv::Mat::eye(1, 8, CV_64FC1);
318 D.at<
double>(0,0) = calibration_.color_camera_calibration.intrinsics.parameters.param.k1;
319 D.at<
double>(0,1) = calibration_.color_camera_calibration.intrinsics.parameters.param.k2;
320 D.at<
double>(0,2) = calibration_.color_camera_calibration.intrinsics.parameters.param.p1;
321 D.at<
double>(0,3) = calibration_.color_camera_calibration.intrinsics.parameters.param.p2;
322 D.at<
double>(0,4) = calibration_.color_camera_calibration.intrinsics.parameters.param.k3;
323 D.at<
double>(0,5) = calibration_.color_camera_calibration.intrinsics.parameters.param.k4;
324 D.at<
double>(0,6) = calibration_.color_camera_calibration.intrinsics.parameters.param.k5;
325 D.at<
double>(0,7) = calibration_.color_camera_calibration.intrinsics.parameters.param.k6;
326 cv::Mat
R = cv::Mat::eye(3, 3, CV_64FC1);
327 cv::Mat
P = cv::Mat::eye(3, 4, CV_64FC1);
328 P.at<
double>(0,0) =
K.at<
double>(0,0);
329 P.at<
double>(1,1) =
K.at<
double>(1,1);
330 P.at<
double>(0,2) =
K.at<
double>(0,2);
331 P.at<
double>(1,2) =
K.at<
double>(1,2);
334 cv::Size(calibration_.color_camera_calibration.resolution_width, calibration_.color_camera_calibration.resolution_height),
336 this->getLocalTransform());
338 UASSERT(model_.isValidForRectification());
339 model_.initRectificationMap();
343 UINFO(
"K4A calibration:");
344 std::cout << model_ << std::endl;
347 transformationHandle_ = k4a_transformation_create(&calibration_);
350 k4a_calibration_extrinsics_t* imu_extrinsics;
353 imu_extrinsics = &calibration_.extrinsics[K4A_CALIBRATION_TYPE_ACCEL][K4A_CALIBRATION_TYPE_DEPTH];
357 imu_extrinsics = &calibration_.extrinsics[K4A_CALIBRATION_TYPE_ACCEL][K4A_CALIBRATION_TYPE_COLOR];
360 imu_extrinsics->rotation[0], imu_extrinsics->rotation[1], imu_extrinsics->rotation[2], imu_extrinsics->translation[0] / 1000.0f,
361 imu_extrinsics->rotation[3], imu_extrinsics->rotation[4], imu_extrinsics->rotation[5], imu_extrinsics->translation[1] / 1000.0f,
362 imu_extrinsics->rotation[6], imu_extrinsics->rotation[7], imu_extrinsics->rotation[8], imu_extrinsics->translation[2] / 1000.0f);
364 UINFO(
"camera to imu=%s", imuLocalTransform_.prettyPrint().c_str());
367 UINFO(
"base to imu=%s", imuLocalTransform_.prettyPrint().c_str());
371 if (!fileName_.empty())
373 k4a_record_configuration_t
config;
374 if (k4a_playback_get_record_configuration((k4a_playback_t)playbackHandle_, &
config))
376 UERROR(
"Failed to getting recording configuration");
383 if (K4A_FAILED(k4a_device_start_imu(deviceHandle_)))
385 UERROR(
"Failed to start K4A IMU");
390 UINFO(
"K4a IMU started successfully");
393 if (K4A_WAIT_RESULT_SUCCEEDED == k4a_device_get_capture(deviceHandle_, &captureHandle_, K4A_WAIT_INFINITE))
395 k4a_capture_release(captureHandle_);
404 UERROR(
"CameraK4A: RTAB-Map is not built with Kinect for Azure SDK support!");
417 if(!fileName_.empty())
421 return(serial_number_);
433 k4a_image_t ir_image_ =
NULL;
434 k4a_image_t rgb_image_ =
NULL;
435 k4a_imu_sample_t imu_sample_;
439 bool captured =
false;
442 k4a_stream_result_t
result = K4A_STREAM_RESULT_FAILED;
444 (K4A_STREAM_RESULT_SUCCEEDED != (
result=k4a_playback_get_next_capture(playbackHandle_, &captureHandle_)) ||
445 ((ir_ && (ir_image_=k4a_capture_get_ir_image(captureHandle_)) ==
NULL) || (!ir_ && (rgb_image_=k4a_capture_get_color_image(captureHandle_)) ==
NULL))))
447 k4a_capture_release(captureHandle_);
450 if (
result == K4A_STREAM_RESULT_EOF)
453 UINFO(
"End of file reached");
455 else if (
result == K4A_STREAM_RESULT_FAILED)
457 UERROR(
"Failed to read entire recording");
459 captured =
result == K4A_STREAM_RESULT_SUCCEEDED;
463 k4a_wait_result_t
result = K4A_WAIT_RESULT_FAILED;
465 (K4A_WAIT_RESULT_SUCCEEDED != (
result=k4a_device_get_capture(deviceHandle_, &captureHandle_, K4A_WAIT_INFINITE)) ||
466 ((ir_ && (ir_image_=k4a_capture_get_ir_image(captureHandle_)) ==
NULL) || (!ir_ && (rgb_image_=k4a_capture_get_color_image(captureHandle_)) ==
NULL))))
468 k4a_capture_release(captureHandle_);
471 captured =
result == K4A_WAIT_RESULT_SUCCEEDED;
474 if (captured && (rgb_image_!=
NULL || ir_image_!=
NULL))
480 if (ir_image_ !=
NULL)
483 cv::Mat bgrCV16(k4a_image_get_height_pixels(ir_image_),
484 k4a_image_get_width_pixels(ir_image_),
486 (
void*)k4a_image_get_buffer(ir_image_));
488 bgrCV16.convertTo(bgrCV, CV_8U);
490 bgrCV = model_.rectifyImage(bgrCV);
493 k4a_image_release(ir_image_);
498 if (k4a_image_get_format(rgb_image_) == K4A_IMAGE_FORMAT_COLOR_MJPG)
500 bgrCV =
uncompressImage(cv::Mat(1, (
int)k4a_image_get_size(rgb_image_),
502 (
void*)k4a_image_get_buffer(rgb_image_)));
506 cv::Mat bgra(k4a_image_get_height_pixels(rgb_image_),
507 k4a_image_get_width_pixels(rgb_image_),
509 (
void*)k4a_image_get_buffer(rgb_image_));
511 cv::cvtColor(bgra, bgrCV, CV_BGRA2BGR);
513 bgrCV = model_.rectifyImage(bgrCV);
516 k4a_image_release(rgb_image_);
524 k4a_image_t depth_image_ = k4a_capture_get_depth_image(captureHandle_);
526 if (depth_image_ !=
NULL)
528 imageStamp = k4a_image_get_device_timestamp_usec(depth_image_);
529 double stampDevice = ((double)imageStamp) / 1000000.0;
531 if(timestampOffset_ == 0.0)
533 timestampOffset_ = stamp - stampDevice;
536 stamp = stampDevice + timestampOffset_;
540 depthCV = cv::Mat(k4a_image_get_height_pixels(depth_image_),
541 k4a_image_get_width_pixels(depth_image_),
543 (
void*)k4a_image_get_buffer(depth_image_));
545 depthCV = model_.rectifyDepth(depthCV);
549 k4a_image_t transformedDepth =
NULL;
550 if (k4a_image_create(k4a_image_get_format(depth_image_),
551 bgrCV.cols, bgrCV.rows, bgrCV.cols * 2, &transformedDepth) == K4A_RESULT_SUCCEEDED)
553 if(k4a_transformation_depth_image_to_color_camera(transformationHandle_, depth_image_, transformedDepth) == K4A_RESULT_SUCCEEDED)
555 depthCV = cv::Mat(k4a_image_get_height_pixels(transformedDepth),
556 k4a_image_get_width_pixels(transformedDepth),
558 (
void*)k4a_image_get_buffer(transformedDepth)).clone();
562 UERROR(
"K4A failed to register depth image");
565 k4a_image_release(transformedDepth);
569 UERROR(
"K4A failed to allocate registered depth image");
572 k4a_image_release(depth_image_);
576 k4a_capture_release(captureHandle_);
581 k4a_stream_result_t imu_res = K4A_STREAM_RESULT_FAILED;
582 k4a_imu_sample_t next_imu_sample;
584 while((K4A_STREAM_RESULT_SUCCEEDED == (imu_res=k4a_playback_get_next_imu_sample(playbackHandle_, &next_imu_sample))) &&
585 (next_imu_sample.gyro_timestamp_usec < imageStamp))
587 imu_sample_ = next_imu_sample;
590 if(imu_res == K4A_STREAM_RESULT_SUCCEEDED)
592 imu =
IMU(cv::Vec3d(imu_sample_.gyro_sample.xyz.x, imu_sample_.gyro_sample.xyz.y, imu_sample_.gyro_sample.xyz.z),
593 cv::Mat::eye(3, 3, CV_64FC1),
594 cv::Vec3d(imu_sample_.acc_sample.xyz.x, imu_sample_.acc_sample.xyz.y, imu_sample_.acc_sample.xyz.z),
595 cv::Mat::eye(3, 3, CV_64FC1),
600 UWARN(
"IMU data NULL");
605 if(K4A_WAIT_RESULT_SUCCEEDED == k4a_device_get_imu_sample(deviceHandle_, &imu_sample_, 60))
607 imu =
IMU(cv::Vec3d(imu_sample_.gyro_sample.xyz.x, imu_sample_.gyro_sample.xyz.y, imu_sample_.gyro_sample.xyz.z),
608 cv::Mat::eye(3, 3, CV_64FC1),
609 cv::Vec3d(imu_sample_.acc_sample.xyz.x, imu_sample_.acc_sample.xyz.y, imu_sample_.acc_sample.xyz.z),
610 cv::Mat::eye(3, 3, CV_64FC1),
620 if (!bgrCV.empty() && !depthCV.empty())
633 UWARN(
"The option to use mkv stamps is set (framerate<0), but there are no stamps saved in the file! Aborting...");
635 else if (previousStamp_ > 0)
638 int sleepTime = 1000.0*(rateSec - timer_.getElapsedTime());
639 if (sleepTime > 10000)
641 UWARN(
"Detected long delay (%d sec, stamps = %f vs %f). Waiting a maximum of 10 seconds.",
642 sleepTime / 1000, previousStamp_, stamp);
651 while (timer_.getElapsedTime() < rateSec - 0.000001)
656 double slept = timer_.getElapsedTime();
658 UDEBUG(
"slept=%fs vs target=%fs", slept, rateSec);
660 previousStamp_ = stamp;
665 UERROR(
"CameraK4A: RTAB-Map is not built with Kinect for Azure SDK support!");