stitch_frames.cpp
Go to the documentation of this file.
1 /******************************************************************************
2 Copyright (c), 2023 - Analog Devices Inc. All Rights Reserved.
3 This software is PROPRIETARY & CONFIDENTIAL to Analog Devices, Inc.
4 and its licensors.
5 ******************************************************************************/
7 #include <ros/ros.h>
8 
9 #include "module_profile.h"
10 
11 #include <geometry_msgs/TransformStamped.h>
12 #include <opencv2/core.hpp>
13 #include <opencv2/highgui.hpp>
14 #include <opencv2/imgcodecs.hpp>
15 #include <tf2_eigen/tf2_eigen.h>
16 #include <boost/chrono.hpp>
17 
18 #ifdef ENABLE_OPENMP_OPTIMIZATION
19 #include <omp.h>
20 #endif
21 
23 
31 {
32  // Make sure we have received frames from all the sensors
33  bool all_callbacks_recvd = true;
35 
36  if (num_sensors_ <= 1)
37  all_callbacks_recvd = false;
38  for (int i = 0; i < num_sensors_; i++)
39  {
41  {
42  if (!depth_image_recvd_[i] || !ir_image_recvd_[i])
43  {
44  all_callbacks_recvd = false;
45  }
46  }
47  }
48 
49  if (all_callbacks_recvd)
50  {
51  // Reset flags
52  for (int i = 0; i < num_sensors_; i++)
53  {
54  ir_image_recvd_[i] = false;
55  depth_image_recvd_[i] = false;
56  }
57 
58  // Read the available node from the queue
59  ADI3DToFImageStitchingInputInfo* image_stitch_input_info = getInputNode();
60 
61  // Get a output node
63  if (new_output_node == nullptr)
64  {
65  return false;
66  }
67  ROS_INFO("adi_3dtof_image_stitching::Running loop");
68  PROFILE_FUNCTION_START(ImageStitch_RUN);
69 
70  float* out_xyz_frame = new_output_node->xyz_frame_;
71  unsigned short* out_depth_frame = new_output_node->depth_frame_;
72  unsigned short* out_ir_frame = new_output_node->ir_frame_;
73  int* out_lut_3d_to_2d_mapping = new_output_node->lut_3d_to_2d_mapping_;
74 
75  // Core processing function
76 #ifdef ENABLE_GPU_OPTIMIZATION
77  stitch_frames_core_GPU_->stitchFrames(image_stitch_input_info, num_sensors_, out_xyz_frame, out_depth_frame,
78  out_ir_frame, out_lut_3d_to_2d_mapping);
79 #else
80  stitch_frames_core_CPU_->stitchFrames(image_stitch_input_info, num_sensors_, out_xyz_frame, out_depth_frame,
81  out_ir_frame, out_lut_3d_to_2d_mapping );
82 #endif
83 
84  // Publish the output
85  if (new_output_node != nullptr)
86  {
87  new_output_node->frame_counter_ = frame_counter_;
88  // Push
89  pushOutputNode(new_output_node);
90  }
91 
92  // Update frame count
94 
95  delete image_stitch_input_info;
96 
97  PROFILE_FUNCTION_END(ImageStitch_RUN);
98  }
99 
100  return true;
101 }
108 void ADI3DToFImageStitching::generatePointCloud(float* xyz_frame,int* lut_3d_to_2d_mapping, const pcl::PointCloud<pcl::PointXYZ>::Ptr& out_pointcloud)
109 {
110  int i;
111 #ifdef ENABLE_OPENMP_OPTIMIZATION
112 #pragma omp parallel for
113 #endif
114  for (i = 0; i < int(out_image_width_ * out_image_height_); i++)
115  {
116  pcl::PointXYZ point = { 0, 0, 0 };
117  if (lut_3d_to_2d_mapping[i] != -1)
118  {
119  // compensate for the additional transformation
120  point.x = xyz_frame[3 * lut_3d_to_2d_mapping[i]];
121  point.y = xyz_frame[3 * lut_3d_to_2d_mapping[i] + 1];
122  point.z = xyz_frame[3 * lut_3d_to_2d_mapping[i] + 2];
123  }
124  out_pointcloud->points[i] = point;
125  }
126 
127  out_pointcloud->width = out_image_width_;
128  out_pointcloud->height = out_image_height_;
129 }
130 
137 {
138  ADI3DToFImageStitchingInputInfo* innode = nullptr;
139  input_thread_mtx_.lock();
140  int queue_size = input_node_queue_.size();
141  input_thread_mtx_.unlock();
142 
143  // We will try till read the buffer, this is just to allow the read thread to fill the queue
144  while ((innode == nullptr) && ((!input_read_abort_) || queue_size > 0))
145  {
146  input_thread_mtx_.lock();
147  queue_size = input_node_queue_.size();
148  input_thread_mtx_.unlock();
149  if (queue_size > 0)
150  {
151  input_thread_mtx_.lock();
153  input_node_queue_.pop();
154  input_thread_mtx_.unlock();
155  }
156  if (innode == nullptr)
157  {
158  // Wait for the buffers to be filled
159  try {
160  boost::this_thread::sleep_for(boost::chrono::milliseconds(2));
161  }
162  catch (...) {
163  printf("\n ERROR: Exception running Boost sleep \n");
164  }
165 
166  }
167  }
168  return innode;
169 }
170 
ADI3DToFImageStitching::input_node_queue_
std::queue< ADI3DToFImageStitchingInputInfo * > input_node_queue_
Definition: adi_3dtof_image_stitching.h:488
sensor_msgs::image_encodings
ADI3DToFImageStitchingOutputInfo
ENABLE_GPU_OPTIMIZATION.
Definition: adi_3dtof_image_stitching_output_info.h:19
ADI3DToFImageStitching::enable_pointcloud_generation_
int enable_pointcloud_generation_
Definition: adi_3dtof_image_stitching.h:436
ADI3DToFImageStitching::out_image_height_
int out_image_height_
Definition: adi_3dtof_image_stitching.h:108
tf2_eigen.h
ADI3DToFImageStitchingOutputInfo::depth_frame_
unsigned short * depth_frame_
Definition: adi_3dtof_image_stitching_output_info.h:118
module_profile.h
ros.h
ADI3DToFImageStitching::input_read_abort_
bool input_read_abort_
Definition: adi_3dtof_image_stitching.h:486
ADI3DToFImageStitching::generatePointCloud
void generatePointCloud(float *xyz_frame, int *lut_3d_to_2d_mapping, const pcl::PointCloud< pcl::PointXYZ >::Ptr &out_pointcloud)
Function to convert 3D XYZ frame to PCL point cloud format.
Definition: stitch_frames.cpp:108
PROFILE_FUNCTION_END
#define PROFILE_FUNCTION_END(ID)
Definition: module_profile.h:25
ADI3DToFImageStitchingOutputInfo::frame_counter_
int frame_counter_
Definition: adi_3dtof_image_stitching_output_info.h:117
ADI3DToFImageStitchingOutputInfo::ir_frame_
unsigned short * ir_frame_
Definition: adi_3dtof_image_stitching_output_info.h:120
ADI3DToFImageStitching::depth_image_recvd_
bool depth_image_recvd_[MAX_NUM_DEVICES]
Definition: adi_3dtof_image_stitching.h:449
StitchFramesCoreCPU::stitchFrames
void stitchFrames(ADI3DToFImageStitchingInputInfo *image_stitch_input_info, int num_sensors, float *out_xyz_frame, unsigned short *out_depth_frame, unsigned short *out_ir_frame, int *out_lut_3d_to_2d_mapping)
Core function to initiate image stitching.
Definition: stitch_frames_core_cpu.cpp:410
ADI3DToFImageStitching::out_image_width_
int out_image_width_
Definition: adi_3dtof_image_stitching.h:109
ADI3DToFImageStitchingInputInfo
ENABLE_GPU_OPTIMIZATION.
Definition: adi_3dtof_image_stitching_input_info.h:20
PROFILE_FUNCTION_START
#define PROFILE_FUNCTION_START(ID)
Definition: module_profile.h:24
ADI3DToFImageStitching::stitch_frames_core_CPU_
StitchFramesCoreCPU * stitch_frames_core_CPU_
Definition: adi_3dtof_image_stitching.h:493
ADI3DToFImageStitching::stitchFrames
bool stitchFrames()
Stitch function.
Definition: stitch_frames.cpp:30
ADI3DToFImageStitching::frame_counter_
int frame_counter_
Definition: adi_3dtof_image_stitching.h:431
ADI3DToFImageStitching::input_thread_mtx_
boost::mutex input_thread_mtx_
Definition: adi_3dtof_image_stitching.h:484
ADI3DToFImageStitching::ir_image_recvd_
bool ir_image_recvd_[MAX_NUM_DEVICES]
Definition: adi_3dtof_image_stitching.h:448
ADI3DToFImageStitching::curr_frame_timestamp_
ros::Time curr_frame_timestamp_
Definition: adi_3dtof_image_stitching.h:474
ADI3DToFImageStitching::pushOutputNode
void pushOutputNode(ADI3DToFImageStitchingOutputInfo *new_output_node)
This function pushes the debug node to the output queue. If the queue is full, then the last item in ...
Definition: adi_3dtof_image_stitching_output_thread.cpp:30
ADI3DToFImageStitchingOutputInfo::lut_3d_to_2d_mapping_
int * lut_3d_to_2d_mapping_
Definition: adi_3dtof_image_stitching_output_info.h:123
ADI3DToFImageStitching::num_sensors_
int num_sensors_
Definition: adi_3dtof_image_stitching.h:476
ROS_INFO
#define ROS_INFO(...)
ADI3DToFImageStitchingOutputInfo::xyz_frame_
float * xyz_frame_
Definition: adi_3dtof_image_stitching_output_info.h:122
adi_3dtof_image_stitching.h
ADI3DToFImageStitching::getInputNode
ADI3DToFImageStitchingInputInfo * getInputNode()
Function to read the next node from the input Queue.
Definition: stitch_frames.cpp:136
ros::Time::now
static Time now()


adi_3dtof_image_stitching
Author(s):
autogenerated on Fri Mar 21 2025 02:27:20