diff --git a/orbbec_camera/include/orbbec_camera/ob_camera_node.h b/orbbec_camera/include/orbbec_camera/ob_camera_node.h index 0ed30bf0..2ab33a35 100644 --- a/orbbec_camera/include/orbbec_camera/ob_camera_node.h +++ b/orbbec_camera/include/orbbec_camera/ob_camera_node.h @@ -46,6 +46,7 @@ #include #include #include "libobsensor/ObSensor.hpp" +#include "libobsensor/hpp/Utils.hpp" #include "orbbec_camera_msgs/msg/device_info.hpp" #include "orbbec_camera_msgs/srv/get_device_info.hpp" @@ -396,6 +397,7 @@ class OBCameraNode { std::string color_info_url_; std::string ir_info_url_; std::optional camera_param_; + std::optional calibration_param_; bool enable_d2c_viewer_ = false; std::unique_ptr d2c_viewer_ = nullptr; std::map save_images_; diff --git a/orbbec_camera/src/ob_camera_node.cpp b/orbbec_camera/src/ob_camera_node.cpp index 6f0b8582..833d6f4e 100644 --- a/orbbec_camera/src/ob_camera_node.cpp +++ b/orbbec_camera/src/ob_camera_node.cpp @@ -743,6 +743,13 @@ void OBCameraNode::publishDepthPointCloud(const std::shared_ptr &f RCLCPP_ERROR_STREAM(logger_, "camera_param_ is null"); return; } + if (!calibration_param_) { + calibration_param_ = pipeline_->getCalibrationParam(pipeline_config_); + } + if (!calibration_param_) { + RCLCPP_ERROR_STREAM(logger_, "calibration_param_ is null"); + return; + } auto depth_frame = frame_set->depthFrame(); if (!depth_frame) { return; @@ -753,16 +760,27 @@ void OBCameraNode::publishDepthPointCloud(const std::shared_ptr &f if (depth_data == nullptr) { return; } - float fdx = - camera_param_->depthIntrinsic.fx * ((float)(width) / camera_param_->depthIntrinsic.width); - float fdy = - camera_param_->depthIntrinsic.fy * ((float)(height) / camera_param_->depthIntrinsic.height); - fdx = 1 / fdx; - fdy = 1 / fdy; - float u0 = - camera_param_->depthIntrinsic.cx * ((float)(width) / camera_param_->depthIntrinsic.width); - float v0 = - camera_param_->depthIntrinsic.cy * ((float)(height) / camera_param_->depthIntrinsic.height); + + uint32_t tableSize = width * height * 2; // one for x-coordinate and one for y-coordinate LUT + float * data = new float[tableSize]; + + OBXYTables xyTables; + if (!ob::CoordinateTransformHelper::transformationInitXYTables( + *calibration_param_, OB_SENSOR_DEPTH, data, + &tableSize, &xyTables)) { + return; + } + + uint32_t pointcloudSize = width * height * sizeof(OBPoint3f); + uint8_t * pointcloudData = new uint8_t[pointcloudSize]; + memset(pointcloudData, 0, pointcloudSize); + OBPoint * pointPixel = (OBPoint *)pointcloudData; + + ob::CoordinateTransformHelper::transformationDepthToPointCloud( + &xyTables, + depth_data, + pointPixel); + sensor_msgs::PointCloud2Modifier modifier(point_cloud_msg_); modifier.setPointCloud2FieldsByString(1, "xyz"); modifier.resize(width * height); @@ -777,25 +795,17 @@ void OBCameraNode::publishDepthPointCloud(const std::shared_ptr &f size_t valid_count = 0; const static float MIN_DISTANCE = 20.0; const static float MAX_DISTANCE = 10000.0; - double depth_scale = depth_frame->getValueScale(); - const static float min_depth = MIN_DISTANCE / depth_scale; - const static float max_depth = MAX_DISTANCE / depth_scale; - for (uint32_t y = 0; y < height; y++) { - for (uint32_t x = 0; x < width; x++) { - bool vaild_point = true; - if (depth_data[y * width + x] < min_depth || depth_data[y * width + x] > max_depth) { - vaild_point = false; - } - if (vaild_point || ordered_pc_) { - float xf = (x - u0) * fdx; - float yf = (y - v0) * fdy; - float zf = depth_data[y * width + x] * depth_scale; - *iter_x = zf * xf / 1000.0; - *iter_y = zf * yf / 1000.0; - *iter_z = zf / 1000.0; - ++iter_x, ++iter_y, ++iter_z; - valid_count++; - } + for (uint32_t i = 0; i < width * height; i++) { + bool valid_point = true; + if (pointPixel[i].z MAX_DISTANCE) { + valid_point = false; + } + if (valid_point || ordered_pc_) { + *iter_x = pointPixel[i].x / 1000.0; + *iter_y = pointPixel[i].y / 1000.0; + *iter_z = pointPixel[i].z / 1000.0; + ++iter_x, ++iter_y, ++iter_z; + valid_count++; } } auto timestamp = use_hardware_time_ ? fromUsToROSTime(depth_frame->timeStampUs())