mirror of
https://github.com/orbbec/OrbbecSDK_ROS2.git
synced 2026-10-08 13:57:46 +08:00
Add depth to point cloud conversion using util functions
This commit is contained in:
@@ -46,6 +46,7 @@
|
||||
#include <image_transport/publisher.hpp>
|
||||
#include <sensor_msgs/msg/imu.hpp>
|
||||
#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<OBCameraParam> camera_param_;
|
||||
std::optional<OBCalibrationParam> calibration_param_;
|
||||
bool enable_d2c_viewer_ = false;
|
||||
std::unique_ptr<D2CViewer> d2c_viewer_ = nullptr;
|
||||
std::map<stream_index_pair, std::atomic_bool> save_images_;
|
||||
|
||||
@@ -743,6 +743,13 @@ void OBCameraNode::publishDepthPointCloud(const std::shared_ptr<ob::FrameSet> &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<ob::FrameSet> &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<ob::FrameSet> &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<MIN_DISTANCE || 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())
|
||||
|
||||
Reference in New Issue
Block a user