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),
74 const std::string & fileName,
77 Camera(imageRate, localTransform)
81 transformationHandle_(
NULL),
83 playbackHandle_(
NULL),
103 if (playbackHandle_ !=
NULL)
105 k4a_playback_close((k4a_playback_t)playbackHandle_);
106 playbackHandle_ =
NULL;
108 else if (deviceHandle_ !=
NULL)
110 k4a_device_stop_imu(deviceHandle_);
112 k4a_device_stop_cameras(deviceHandle_);
113 k4a_device_close(deviceHandle_);
114 deviceHandle_ =
NULL;
115 config_ = K4A_DEVICE_CONFIG_INIT_DISABLE_ALL;
118 if (transformationHandle_ !=
NULL)
120 k4a_transformation_destroy((k4a_transformation_t)transformationHandle_);
121 transformationHandle_ =
NULL;
129 rgb_resolution_ = rgb_resolution;
130 framerate_ = framerate;
131 depth_resolution_ = depth_resolution;
132 UINFO(
"setPreferences(): %i %i %i", rgb_resolution, framerate, depth_resolution);
143 bool CameraK4A::init(
const std::string & calibrationFolder,
const std::string & cameraName)
147 if (!fileName_.empty())
151 if (k4a_playback_open(fileName_.c_str(), (k4a_playback_t*)&playbackHandle_) != K4A_RESULT_SUCCEEDED)
153 UERROR(
"Failed to open recording \"%s\"", fileName_.c_str());
157 uint64_t recording_length = k4a_playback_get_last_timestamp_usec((k4a_playback_t)playbackHandle_);
158 UINFO(
"Recording is %lld seconds long", recording_length / 1000000);
160 if (k4a_playback_get_calibration((k4a_playback_t)playbackHandle_, &calibration_))
162 UERROR(
"Failed to get calibration");
168 else if (deviceId_ >= 0)
170 if(deviceHandle_!=
NULL)
175 switch(rgb_resolution_)
177 case 0: config_.color_resolution = K4A_COLOR_RESOLUTION_720P;
break;
178 case 1: config_.color_resolution = K4A_COLOR_RESOLUTION_1080P;
break;
179 case 2: config_.color_resolution = K4A_COLOR_RESOLUTION_1440P;
break;
180 case 3: config_.color_resolution = K4A_COLOR_RESOLUTION_1536P;
break;
181 case 4: config_.color_resolution = K4A_COLOR_RESOLUTION_2160P;
break;
183 default: config_.color_resolution = K4A_COLOR_RESOLUTION_3072P;
break;
188 case 0: config_.camera_fps = K4A_FRAMES_PER_SECOND_5;
break;
189 case 1: config_.camera_fps = K4A_FRAMES_PER_SECOND_15;
break;
191 default: config_.camera_fps = K4A_FRAMES_PER_SECOND_30;
break;
194 switch(depth_resolution_)
196 case 0: config_.depth_mode = K4A_DEPTH_MODE_NFOV_2X2BINNED;
break;
197 case 1: config_.depth_mode = K4A_DEPTH_MODE_NFOV_UNBINNED;
break;
198 case 2: config_.depth_mode = K4A_DEPTH_MODE_WFOV_2X2BINNED;
break;
200 default: config_.depth_mode = K4A_DEPTH_MODE_WFOV_UNBINNED;
break;
204 config_.color_format = K4A_IMAGE_FORMAT_COLOR_BGRA32;
206 int device_count = k4a_device_get_installed_count();
208 if (device_count == 0)
210 UERROR(
"No k4a devices attached!");
213 else if(deviceId_ > device_count)
215 UERROR(
"Cannot select device %d, only %d devices detected.", deviceId_, device_count);
218 UINFO(
"CameraK4A found %d k4a device(s) attached", device_count);
221 if (K4A_FAILED(k4a_device_open(deviceId_, &deviceHandle_)))
223 UERROR(
"Failed to open k4a device!");
228 size_t serial_size = 0;
229 k4a_device_get_serialnum(deviceHandle_,
NULL, &serial_size);
232 char *serial = (
char*)(malloc(serial_size));
233 k4a_device_get_serialnum(deviceHandle_, serial, &serial_size);
234 serial_number_.assign(serial, serial_size);
237 UINFO(
"Opened K4A device: %s", serial_number_.c_str());
240 if (K4A_FAILED(k4a_device_start_cameras(deviceHandle_, &config_)))
242 UERROR(
"Failed to start cameras!");
247 UINFO(
"K4A camera started successfully");
249 if (K4A_FAILED(k4a_device_get_calibration(deviceHandle_, config_.depth_mode, config_.color_resolution, &calibration_)))
251 UERROR(
"k4a_device_get_calibration() failed!");
258 UERROR(
"k4a_device_get_calibration() no file and no valid device id!");
264 cv::Mat K = cv::Mat::eye(3, 3, CV_64FC1);
265 K.at<
double>(0,0) = calibration_.depth_camera_calibration.intrinsics.parameters.param.fx;
266 K.at<
double>(1,1) = calibration_.depth_camera_calibration.intrinsics.parameters.param.fy;
267 K.at<
double>(0,2) = calibration_.depth_camera_calibration.intrinsics.parameters.param.cx;
268 K.at<
double>(1,2) = calibration_.depth_camera_calibration.intrinsics.parameters.param.cy;
269 cv::Mat D = cv::Mat::eye(1, 8, CV_64FC1);
270 D.at<
double>(0,0) = calibration_.depth_camera_calibration.intrinsics.parameters.param.k1;
271 D.at<
double>(0,1) = calibration_.depth_camera_calibration.intrinsics.parameters.param.k2;
272 D.at<
double>(0,2) = calibration_.depth_camera_calibration.intrinsics.parameters.param.p1;
273 D.at<
double>(0,3) = calibration_.depth_camera_calibration.intrinsics.parameters.param.p2;
274 D.at<
double>(0,4) = calibration_.depth_camera_calibration.intrinsics.parameters.param.k3;
275 D.at<
double>(0,5) = calibration_.depth_camera_calibration.intrinsics.parameters.param.k4;
276 D.at<
double>(0,6) = calibration_.depth_camera_calibration.intrinsics.parameters.param.k5;
277 D.at<
double>(0,7) = calibration_.depth_camera_calibration.intrinsics.parameters.param.k6;
278 cv::Mat R = cv::Mat::eye(3, 3, CV_64FC1);
279 cv::Mat P = cv::Mat::eye(3, 4, CV_64FC1);
280 P.at<
double>(0,0) = K.at<
double>(0,0);
281 P.at<
double>(1,1) = K.at<
double>(1,1);
282 P.at<
double>(0,2) = K.at<
double>(0,2);
283 P.at<
double>(1,2) = K.at<
double>(1,2);
286 cv::Size(calibration_.depth_camera_calibration.resolution_width, calibration_.depth_camera_calibration.resolution_height),
288 this->getLocalTransform());
289 UASSERT(model_.isValidForRectification());
290 model_.initRectificationMap();
294 cv::Mat K = cv::Mat::eye(3, 3, CV_64FC1);
295 K.at<
double>(0,0) = calibration_.color_camera_calibration.intrinsics.parameters.param.fx;
296 K.at<
double>(1,1) = calibration_.color_camera_calibration.intrinsics.parameters.param.fy;
297 K.at<
double>(0,2) = calibration_.color_camera_calibration.intrinsics.parameters.param.cx;
298 K.at<
double>(1,2) = calibration_.color_camera_calibration.intrinsics.parameters.param.cy;
299 cv::Mat D = cv::Mat::eye(1, 8, CV_64FC1);
300 D.at<
double>(0,0) = calibration_.color_camera_calibration.intrinsics.parameters.param.k1;
301 D.at<
double>(0,1) = calibration_.color_camera_calibration.intrinsics.parameters.param.k2;
302 D.at<
double>(0,2) = calibration_.color_camera_calibration.intrinsics.parameters.param.p1;
303 D.at<
double>(0,3) = calibration_.color_camera_calibration.intrinsics.parameters.param.p2;
304 D.at<
double>(0,4) = calibration_.color_camera_calibration.intrinsics.parameters.param.k3;
305 D.at<
double>(0,5) = calibration_.color_camera_calibration.intrinsics.parameters.param.k4;
306 D.at<
double>(0,6) = calibration_.color_camera_calibration.intrinsics.parameters.param.k5;
307 D.at<
double>(0,7) = calibration_.color_camera_calibration.intrinsics.parameters.param.k6;
308 cv::Mat R = cv::Mat::eye(3, 3, CV_64FC1);
309 cv::Mat P = cv::Mat::eye(3, 4, CV_64FC1);
310 P.at<
double>(0,0) = K.at<
double>(0,0);
311 P.at<
double>(1,1) = K.at<
double>(1,1);
312 P.at<
double>(0,2) = K.at<
double>(0,2);
313 P.at<
double>(1,2) = K.at<
double>(1,2);
316 cv::Size(calibration_.color_camera_calibration.resolution_width, calibration_.color_camera_calibration.resolution_height),
318 this->getLocalTransform());
323 UINFO(
"K4A calibration:");
324 std::cout << model_ << std::endl;
327 transformationHandle_ = k4a_transformation_create(&calibration_);
330 k4a_calibration_extrinsics_t* imu_extrinsics;
333 imu_extrinsics = &calibration_.extrinsics[K4A_CALIBRATION_TYPE_ACCEL][K4A_CALIBRATION_TYPE_DEPTH];
337 imu_extrinsics = &calibration_.extrinsics[K4A_CALIBRATION_TYPE_ACCEL][K4A_CALIBRATION_TYPE_COLOR];
340 imu_extrinsics->rotation[0], imu_extrinsics->rotation[1], imu_extrinsics->rotation[2], imu_extrinsics->translation[0] / 1000.0f,
341 imu_extrinsics->rotation[3], imu_extrinsics->rotation[4], imu_extrinsics->rotation[5], imu_extrinsics->translation[1] / 1000.0f,
342 imu_extrinsics->rotation[6], imu_extrinsics->rotation[7], imu_extrinsics->rotation[8], imu_extrinsics->translation[2] / 1000.0f);
344 UINFO(
"camera to imu=%s", imuLocalTransform_.prettyPrint().c_str());
347 UINFO(
"base to imu=%s", imuLocalTransform_.prettyPrint().c_str());
351 if (!fileName_.empty())
353 k4a_record_configuration_t
config;
354 if (k4a_playback_get_record_configuration((k4a_playback_t)playbackHandle_, &config))
356 UERROR(
"Failed to getting recording configuration");
363 if (K4A_FAILED(k4a_device_start_imu(deviceHandle_)))
365 UERROR(
"Failed to start K4A IMU");
370 UINFO(
"K4a IMU started successfully");
373 if (K4A_WAIT_RESULT_SUCCEEDED == k4a_device_get_capture(deviceHandle_, &captureHandle_, K4A_WAIT_INFINITE))
375 k4a_capture_release(captureHandle_);
384 UERROR(
"CameraK4A: RTAB-Map is not built with Kinect for Azure SDK support!");
397 if(!fileName_.empty())
401 return(serial_number_);
413 k4a_image_t ir_image_ =
NULL;
414 k4a_image_t rgb_image_ =
NULL;
415 k4a_imu_sample_t imu_sample_;
419 bool captured =
false;
422 k4a_stream_result_t result = K4A_STREAM_RESULT_FAILED;
424 (K4A_STREAM_RESULT_SUCCEEDED != (result=k4a_playback_get_next_capture(playbackHandle_, &captureHandle_)) ||
425 ((ir_ && (ir_image_=k4a_capture_get_ir_image(captureHandle_)) ==
NULL) || (!ir_ && (rgb_image_=k4a_capture_get_color_image(captureHandle_)) ==
NULL))))
427 k4a_capture_release(captureHandle_);
430 if (result == K4A_STREAM_RESULT_EOF)
433 UINFO(
"End of file reached");
435 else if (result == K4A_STREAM_RESULT_FAILED)
437 UERROR(
"Failed to read entire recording");
439 captured = result == K4A_STREAM_RESULT_SUCCEEDED;
443 k4a_wait_result_t result = K4A_WAIT_RESULT_FAILED;
445 (K4A_WAIT_RESULT_SUCCEEDED != (result=k4a_device_get_capture(deviceHandle_, &captureHandle_, K4A_WAIT_INFINITE)) ||
446 ((ir_ && (ir_image_=k4a_capture_get_ir_image(captureHandle_)) ==
NULL) || (!ir_ && (rgb_image_=k4a_capture_get_color_image(captureHandle_)) ==
NULL))))
448 k4a_capture_release(captureHandle_);
451 captured = result == K4A_WAIT_RESULT_SUCCEEDED;
454 if (captured && (rgb_image_!=
NULL || ir_image_!=
NULL))
460 if (ir_image_ !=
NULL)
463 cv::Mat bgrCV16(k4a_image_get_height_pixels(ir_image_),
464 k4a_image_get_width_pixels(ir_image_),
466 (
void*)k4a_image_get_buffer(ir_image_));
468 bgrCV16.convertTo(bgrCV, CV_8U);
470 bgrCV = model_.rectifyImage(bgrCV);
473 k4a_image_release(ir_image_);
478 if (k4a_image_get_format(rgb_image_) == K4A_IMAGE_FORMAT_COLOR_MJPG)
480 bgrCV =
uncompressImage(cv::Mat(1, (
int)k4a_image_get_size(rgb_image_),
482 (
void*)k4a_image_get_buffer(rgb_image_)));
486 cv::Mat bgra(k4a_image_get_height_pixels(rgb_image_),
487 k4a_image_get_width_pixels(rgb_image_),
489 (
void*)k4a_image_get_buffer(rgb_image_));
491 cv::cvtColor(bgra, bgrCV, CV_BGRA2BGR);
495 k4a_image_release(rgb_image_);
502 k4a_image_t depth_image_ = k4a_capture_get_depth_image(captureHandle_);
504 if (depth_image_ !=
NULL)
506 stamp = ((double)k4a_image_get_timestamp_usec(depth_image_)) / 1000000;
510 depthCV = cv::Mat(k4a_image_get_height_pixels(depth_image_),
511 k4a_image_get_width_pixels(depth_image_),
513 (
void*)k4a_image_get_buffer(depth_image_));
515 depthCV = model_.rectifyDepth(depthCV);
519 k4a_image_t transformedDepth =
NULL;
520 if (k4a_image_create(k4a_image_get_format(depth_image_),
521 bgrCV.cols, bgrCV.rows, bgrCV.cols * 2, &transformedDepth) == K4A_RESULT_SUCCEEDED)
523 if(k4a_transformation_depth_image_to_color_camera(transformationHandle_, depth_image_, transformedDepth) == K4A_RESULT_SUCCEEDED)
525 depthCV = cv::Mat(k4a_image_get_height_pixels(transformedDepth),
526 k4a_image_get_width_pixels(transformedDepth),
528 (
void*)k4a_image_get_buffer(transformedDepth)).clone();
532 UERROR(
"K4A failed to register depth image");
535 k4a_image_release(transformedDepth);
539 UERROR(
"K4A failed to allocate registered depth image");
542 k4a_image_release(depth_image_);
546 k4a_capture_release(captureHandle_);
552 k4a_playback_seek_timestamp(playbackHandle_, stamp* 1000000+1, K4A_PLAYBACK_SEEK_BEGIN);
553 if(K4A_STREAM_RESULT_SUCCEEDED == k4a_playback_get_previous_imu_sample(playbackHandle_, &imu_sample_))
555 double stmp = ((double)imu_sample_.acc_timestamp_usec) / 1000000;
556 imu =
IMU(cv::Vec3d(imu_sample_.gyro_sample.xyz.x, imu_sample_.gyro_sample.xyz.y, imu_sample_.gyro_sample.xyz.z),
557 cv::Mat::eye(3, 3, CV_64FC1),
558 cv::Vec3d(imu_sample_.acc_sample.xyz.x, imu_sample_.acc_sample.xyz.y, imu_sample_.acc_sample.xyz.z),
559 cv::Mat::eye(3, 3, CV_64FC1),
564 UWARN(
"IMU data NULL");
570 if(K4A_WAIT_RESULT_SUCCEEDED == k4a_device_get_imu_sample(deviceHandle_, &imu_sample_, 60))
572 imu =
IMU(cv::Vec3d(imu_sample_.gyro_sample.xyz.x, imu_sample_.gyro_sample.xyz.y, imu_sample_.gyro_sample.xyz.z),
573 cv::Mat::eye(3, 3, CV_64FC1),
574 cv::Vec3d(imu_sample_.acc_sample.xyz.x, imu_sample_.acc_sample.xyz.y, imu_sample_.acc_sample.xyz.z),
575 cv::Mat::eye(3, 3, CV_64FC1),
585 if (!bgrCV.empty() && !depthCV.empty())
598 UWARN(
"The option to use mkv stamps is set (framerate<0), but there are no stamps saved in the file! Aborting...");
600 else if (previousStamp_ > 0)
603 int sleepTime = 1000.0*(stamp - previousStamp_) / ratio - 1000.0*timer_.getElapsedTime();
604 if (sleepTime > 10000)
606 UWARN(
"Detected long delay (%d sec, stamps = %f vs %f). Waiting a maximum of 10 seconds.",
607 sleepTime / 1000, previousStamp_, stamp);
616 while (timer_.getElapsedTime() < (stamp - previousStamp_) / ratio - 0.000001)
621 double slept = timer_.getElapsedTime();
623 UDEBUG(
"slept=%fs vs target=%fs (ratio=%f)", slept, (stamp - previousStamp_) / ratio, ratio);
625 previousStamp_ = stamp;
630 UERROR(
"CameraK4A: RTAB-Map is not built with Kinect for Azure SDK support!");
virtual SensorData captureImage(CameraInfo *info=0)
const Transform & getLocalTransform() const
virtual bool isCalibrated() const
#define UASSERT(condition)
void setIRDepthFormat(bool enabled)
void setPreferences(int rgb_resolution, int framerate, int depth_resolution)
static ULogger::Level level()
CameraK4A(int deviceId=0, float imageRate=0.0f, const Transform &localTransform=CameraModel::opticalRotation())
void uSleep(unsigned int ms)
float getImageRate() const
virtual std::string getSerial() const
void setIMU(const IMU &imu)
virtual bool init(const std::string &calibrationFolder=".", const std::string &cameraName="")
cv::Mat RTABMAP_EXP uncompressImage(const cv::Mat &bytes)