15
15
*******************************************************************************/
16
16
17
17
#include " orbbec_camera/ob_camera_node.h"
18
+ #include " libobsensor/hpp/Utils.hpp"
18
19
#if defined(USE_RK_HW_DECODER)
19
20
#include " orbbec_camera/rk_mpp_decoder.h"
20
21
#elif defined(USE_NV_HW_DECODER)
@@ -64,6 +65,13 @@ void OBCameraNode::init() {
64
65
CHECK (width_[COLOR] > 0 && height_[COLOR] > 0 );
65
66
rgb_buffer_ = new uint8_t [width_[COLOR] * height_[COLOR] * 3 ];
66
67
}
68
+ if (enable_colored_point_cloud_ && enable_stream_[COLOR] && enable_stream_[DEPTH]) {
69
+ CHECK (width_[COLOR] > 0 && height_[COLOR] > 0 );
70
+ rgb_point_cloud_buffer_size_ = width_[COLOR] * height_[COLOR] * sizeof (OBColorPoint);
71
+ rgb_point_cloud_buffer_ = new uint8_t [rgb_point_cloud_buffer_size_];
72
+ xy_table_data_size_ = width_[COLOR] * height_[COLOR] * 2 ;
73
+ xy_table_data_ = new float [xy_table_data_size_];
74
+ }
67
75
rgb_is_decoded_ = false ;
68
76
if (diagnostics_frequency_ > 0.0 ) {
69
77
diagnostics_thread_ = std::make_shared<std::thread>([this ]() { setupDiagnosticUpdater (); });
@@ -73,7 +81,7 @@ void OBCameraNode::init() {
73
81
74
82
bool OBCameraNode::isInitialized () const { return is_initialized_; }
75
83
76
- OBCameraNode::~OBCameraNode () {
84
+ OBCameraNode::~OBCameraNode () noexcept {
77
85
ROS_INFO_STREAM (" OBCameraNode::~OBCameraNode() start" );
78
86
std::lock_guard<decltype (device_lock_)> lock (device_lock_);
79
87
is_running_ = false ;
@@ -94,6 +102,8 @@ OBCameraNode::~OBCameraNode() {
94
102
stopStreams ();
95
103
ROS_INFO_STREAM (" OBCameraNode::~OBCameraNode() delete rgb_buffer" );
96
104
delete[] rgb_buffer_;
105
+ delete[] rgb_point_cloud_buffer_;
106
+ delete[] xy_table_data_;
97
107
ROS_INFO_STREAM (" OBCameraNode::~OBCameraNode() end" );
98
108
}
99
109
@@ -532,25 +542,33 @@ void OBCameraNode::publishDepthPointCloud(const std::shared_ptr<ob::FrameSet>& f
532
542
if (!enable_point_cloud_ || depth_cloud_pub_.getNumSubscribers () == 0 ) {
533
543
return ;
534
544
}
535
- auto depth_frame = frame_set->depthFrame ();
545
+ if (!depth_frame_) {
546
+ return ;
547
+ }
548
+ std::lock_guard<decltype (cloud_mutex_)> cloud_lock (cloud_mutex_);
549
+ auto depth_frame = depth_frame_->as <ob::DepthFrame>();
536
550
if (!depth_frame) {
537
551
ROS_ERROR_STREAM (" depth frame is null" );
538
552
return ;
539
553
}
540
- std::lock_guard<decltype (cloud_mutex_)> cloud_lock (cloud_mutex_);
554
+ CHECK_NOTNULL (pipeline_);
555
+ auto camera_params = pipeline_->getCameraParam ();
556
+ if (depth_registration_) {
557
+ camera_params.depthIntrinsic = camera_params.rgbIntrinsic ;
558
+ }
559
+ depth_point_cloud_filter_.setCameraParam (camera_params);
560
+ float depth_scale = depth_frame->getValueScale ();
561
+ depth_point_cloud_filter_.setPositionDataScaled (depth_scale);
562
+ depth_point_cloud_filter_.setCreatePointFormat (OB_FORMAT_POINT);
563
+ auto result_frame = depth_point_cloud_filter_.process (depth_frame);
564
+ if (!result_frame) {
565
+ ROS_DEBUG (" Failed to create point cloud" );
566
+ return ;
567
+ }
568
+ auto point_size = result_frame->dataSize () / sizeof (OBPoint);
569
+ auto * points = static_cast <OBPoint*>(result_frame->data ());
541
570
auto width = depth_frame->width ();
542
571
auto height = depth_frame->height ();
543
- auto depth_profile = stream_profile_[DEPTH]->as <ob::VideoStreamProfile>();
544
- CHECK_NOTNULL (depth_profile.get ());
545
- auto depth_intrinsics = depth_profile->getIntrinsic ();
546
- float fdx = depth_intrinsics.fx * ((float )(width) / static_cast <float >(depth_intrinsics.width ));
547
- float fdy = depth_intrinsics.fy * ((float )(height) / static_cast <float >(depth_intrinsics.height ));
548
- fdx = 1 / fdx;
549
- fdy = 1 / fdy;
550
- float u0 = depth_intrinsics.cx * ((float )(width) / static_cast <float >(depth_intrinsics.width ));
551
- float v0 = depth_intrinsics.cy * ((float )(height) / static_cast <float >(depth_intrinsics.height ));
552
-
553
- const auto * depth_data = (uint16_t *)depth_frame->data ();
554
572
sensor_msgs::PointCloud2Modifier modifier (cloud_msg_);
555
573
modifier.setPointCloud2FieldsByString (1 , " xyz" );
556
574
modifier.resize (width * height);
@@ -561,28 +579,19 @@ void OBCameraNode::publishDepthPointCloud(const std::shared_ptr<ob::FrameSet>& f
561
579
sensor_msgs::PointCloud2Iterator<float > iter_x (cloud_msg_, " x" );
562
580
sensor_msgs::PointCloud2Iterator<float > iter_y (cloud_msg_, " y" );
563
581
sensor_msgs::PointCloud2Iterator<float > iter_z (cloud_msg_, " z" );
564
- size_t valid_count = 0 ;
565
582
const static double MIN_DISTANCE = 20.0 ;
566
583
const static double MAX_DISTANCE = 10000.0 ;
567
- double depth_scale = depth_frame->getValueScale ();
568
584
const static double min_depth = MIN_DISTANCE / depth_scale;
569
585
const static double max_depth = MAX_DISTANCE / depth_scale;
570
- for (int y = 0 ; y < height; y++) {
571
- for (int x = 0 ; x < width; x++) {
572
- bool valid_point = true ;
573
- if (depth_data[y * width + x] < min_depth || depth_data[y * width + x] > max_depth) {
574
- valid_point = false ;
575
- }
576
- if (valid_point || ordered_pc_) {
577
- float xf = (x - u0) * fdx;
578
- float yf = (y - v0) * fdy;
579
- float zf = depth_data[y * width + x] * depth_scale;
580
- *iter_x = zf * xf / 1000.0 ;
581
- *iter_y = zf * yf / 1000.0 ;
582
- *iter_z = zf / 1000.0 ;
583
- ++iter_x, ++iter_y, ++iter_z;
584
- valid_count++;
585
- }
586
+ size_t valid_count = 0 ;
587
+ for (size_t i = 0 ; i < point_size; i++) {
588
+ bool valid_point = points[i].z >= min_depth && points[i].z <= max_depth;
589
+ if (valid_point || ordered_pc_) {
590
+ *iter_x = static_cast <float >(points[i].x / 1000.0 );
591
+ *iter_y = static_cast <float >(points[i].y / 1000.0 );
592
+ *iter_z = static_cast <float >(points[i].z / 1000.0 );
593
+ ++iter_x, ++iter_y, ++iter_z;
594
+ valid_count++;
586
595
}
587
596
}
588
597
if (!ordered_pc_) {
@@ -641,26 +650,41 @@ void OBCameraNode::publishColoredPointCloud(const std::shared_ptr<ob::FrameSet>&
641
650
color_width, color_height);
642
651
return ;
643
652
}
653
+ if (!xy_tables_.has_value ()) {
654
+ calibration_param_ = pipeline_->getCalibrationParam (pipeline_config_);
644
655
645
- OBCameraIntrinsic intrinsics;
646
- CHECK_NOTNULL (device_info_.get ());
647
- if (isGemini335PID (device_info_->pid ())) {
648
- auto color_profile = stream_profile_[COLOR]->as <ob::VideoStreamProfile>();
649
- CHECK_NOTNULL (color_profile.get ());
650
- intrinsics = color_profile->getIntrinsic ();
651
- } else {
652
- CHECK_NOTNULL (pipeline_.get ());
653
- auto camera_params = pipeline_->getCameraParam ();
654
- intrinsics = camera_params.rgbIntrinsic ;
655
- }
656
- float fdx = intrinsics.fx * ((float )(color_width) / intrinsics.width );
657
- float fdy = intrinsics.fy * ((float )(color_height) / intrinsics.height );
658
- fdx = 1 / fdx;
659
- fdy = 1 / fdy;
660
- float u0 = intrinsics.cx * ((float )(color_width) / intrinsics.width );
661
- float v0 = intrinsics.cy * ((float )(color_height) / intrinsics.height );
662
- const auto * depth_data = (uint16_t *)depth_frame->data ();
656
+ uint32_t table_size =
657
+ color_width * color_height * 2 ; // one for x-coordinate and one for y-coordinate LUT
658
+ if (xy_table_data_size_ != table_size) {
659
+ ROS_INFO_STREAM (" Init xy tables with size " << table_size);
660
+ xy_table_data_size_ = table_size;
661
+ delete[] xy_table_data_;
662
+ xy_table_data_ = new float [table_size];
663
+ }
664
+
665
+ xy_tables_ = OBXYTables ();
666
+ CHECK_NOTNULL (xy_table_data_);
667
+ if (!ob::CoordinateTransformHelper::transformationInitXYTables (
668
+ *calibration_param_, OB_SENSOR_COLOR, xy_table_data_, &table_size, &(*xy_tables_))) {
669
+ ROS_ERROR (" Failed to init xy tables" );
670
+ return ;
671
+ }
672
+ }
673
+
674
+ const auto * depth_data = (uint8_t *)depth_frame->data ();
663
675
const auto * color_data = (uint8_t *)(rgb_buffer_);
676
+ CHECK_NOTNULL (rgb_point_cloud_buffer_);
677
+ uint32_t point_cloud_buffer_size = color_width * color_height * sizeof (OBColorPoint);
678
+ if (point_cloud_buffer_size > rgb_point_cloud_buffer_size_) {
679
+ delete[] rgb_point_cloud_buffer_;
680
+ rgb_point_cloud_buffer_ = new uint8_t [point_cloud_buffer_size];
681
+ rgb_point_cloud_buffer_size_ = point_cloud_buffer_size;
682
+ }
683
+ memset (rgb_point_cloud_buffer_, 0 , rgb_point_cloud_buffer_size_);
684
+ auto * point_cloud = (OBColorPoint*)rgb_point_cloud_buffer_;
685
+ ob::CoordinateTransformHelper::transformationDepthToRGBDPointCloud (&(*xy_tables_), depth_data,
686
+ color_data, point_cloud);
687
+
664
688
sensor_msgs::PointCloud2Modifier modifier (cloud_msg_);
665
689
modifier.setPointCloud2FieldsByString (1 , " xyz" );
666
690
cloud_msg_.width = color_frame->width ();
@@ -682,31 +706,17 @@ void OBCameraNode::publishColoredPointCloud(const std::shared_ptr<ob::FrameSet>&
682
706
double depth_scale = depth_frame->getValueScale ();
683
707
static float min_depth = MIN_DISTANCE / depth_scale;
684
708
static float max_depth = MAX_DISTANCE / depth_scale;
685
- for (int y = 0 ; y < color_height; y++) {
686
- for (int x = 0 ; x < color_width; x++) {
687
- bool valid_point = true ;
688
- float depth = depth_data[y * depth_width + x];
689
- if (depth < min_depth || depth > max_depth) {
690
- valid_point = false ;
691
- }
692
- if (valid_point || ordered_pc_) {
693
- float xf = (x - u0) * fdx;
694
- float yf = (y - v0) * fdy;
695
- float zf = depth * depth_scale;
696
- *iter_x = zf * xf / 1000.0 ;
697
- *iter_y = zf * yf / 1000.0 ;
698
- *iter_z = zf / 1000.0 ;
699
- *iter_r = color_data[(y * color_width + x) * 3 ];
700
- *iter_g = color_data[(y * color_width + x) * 3 + 1 ];
701
- *iter_b = color_data[(y * color_width + x) * 3 + 2 ];
702
- ++iter_x;
703
- ++iter_y;
704
- ++iter_z;
705
- ++iter_r;
706
- ++iter_g;
707
- ++iter_b;
708
- ++valid_count;
709
- }
709
+ for (size_t i = 0 ; i < color_width * color_height; i++) {
710
+ bool valid_point = point_cloud[i].z >= min_depth && point_cloud[i].z <= max_depth;
711
+ if (valid_point || ordered_pc_) {
712
+ *iter_x = static_cast <float >(point_cloud[i].x / 1000.0 );
713
+ *iter_y = static_cast <float >(point_cloud[i].y / 1000.0 );
714
+ *iter_z = static_cast <float >(point_cloud[i].z / 1000.0 );
715
+ *iter_r = static_cast <uint8_t >(point_cloud[i].r );
716
+ *iter_g = static_cast <uint8_t >(point_cloud[i].g );
717
+ *iter_b = static_cast <uint8_t >(point_cloud[i].b );
718
+ ++iter_x, ++iter_y, ++iter_z, ++iter_r, ++iter_g, ++iter_b;
719
+ ++valid_count;
710
720
}
711
721
}
712
722
if (!ordered_pc_) {
0 commit comments