64 #include <std_msgs/Int32.h> 65 #include <sensor_msgs/PointCloud2.h> 71 #include <pcl/io/io.h> 72 #include <pcl/point_types.h> 73 #include <pcl/range_image/range_image.h> 74 #include <pcl/filters/radius_outlier_removal.h> 75 #include <pcl/filters/voxel_grid.h> 76 #include <pcl/filters/passthrough.h> 77 #include <pcl/filters/frustum_culling.h> 84 #include <opencv2/imgproc/imgproc.hpp> 89 #include <dynamic_reconfigure/server.h> 90 #include <softkinetic_camera/SoftkineticConfig.h> 92 #include <DepthSense.hxx> 176 DepthSense::DepthNode::CameraMode
depthMode(
const std::string& depth_mode_str)
178 if ( depth_mode_str ==
"long" )
179 return DepthNode::CAMERA_MODE_LONG_RANGE;
181 return DepthNode::CAMERA_MODE_CLOSE_MODE;
186 if ( depth_frame_format_str ==
"QQVGA" )
187 return FRAME_FORMAT_QQVGA;
188 else if ( depth_frame_format_str ==
"QVGA" )
189 return FRAME_FORMAT_QVGA;
191 return FRAME_FORMAT_VGA;
196 if ( color_compression_str ==
"YUY2" )
197 return COMPRESSION_TYPE_YUY2;
199 return COMPRESSION_TYPE_MJPEG;
204 if ( color_frame_format_str ==
"QQVGA" )
205 return FRAME_FORMAT_QQVGA;
206 else if ( color_frame_format_str ==
"QVGA" )
207 return FRAME_FORMAT_QVGA;
208 else if ( color_frame_format_str ==
"VGA" )
209 return FRAME_FORMAT_VGA;
210 else if ( color_frame_format_str ==
"NHD" )
211 return FRAME_FORMAT_NHD;
213 return FRAME_FORMAT_WXGA_H;
234 FrameFormat_toResolution(data.captureConfiguration.frameFormat, &w, &h);
239 img_rgb.data.resize(w * h * 3);
257 const_cast<uint8_t *
>(
static_cast<const uint8_t *
>(data.colorMap)));
264 const_cast<uint8_t *
>(
static_cast<const uint8_t *
>(data.colorMap)));
291 pcl::VoxelGrid<pcl::PointXYZRGB> sor;
292 sor.setInputCloud(cloud_to_filter);
296 int before = cloud_to_filter->size();
298 sor.filter(*cloud_to_filter);
300 int after = cloud_to_filter->size();
302 <<
"points reduced from " << before <<
" to " << after);
308 pcl::RadiusOutlierRemoval<pcl::PointXYZRGB> ror;
309 ror.setInputCloud(cloud_to_filter);
312 ror.setKeepOrganized(
true);
315 int before = cloud_to_filter->size();
317 ror.filter(*cloud_to_filter);
319 int after = cloud_to_filter->size();
321 <<
"points reduced from " << before <<
" to " << after);
327 pcl::PassThrough<pcl::PointXYZRGB> pt;
328 pt.setInputCloud(cloud_to_filter);
329 pt.setFilterFieldName(
"x");
331 pt.setKeepOrganized(
true);
334 int before = cloud_to_filter->size();
336 pt.filter(*cloud_to_filter);
338 int after = cloud_to_filter->size();
340 <<
"points reduced from " << before <<
" to " << after);
346 pcl::FrustumCulling<pcl::PointXYZRGB> fc;
347 fc.setInputCloud(cloud_to_filter);
354 Eigen::Matrix4f pose = Eigen::Matrix4f::Identity();
362 fc.setCameraPose(pose);
363 fc.setHorizontalFOV(
hfov);
364 fc.setVerticalFOV(
vfov);
367 fc.setKeepOrganized(
true);
370 int before = cloud_to_filter->size();
372 fc.filter(*cloud_to_filter);
374 int after = cloud_to_filter->size();
376 <<
"points reduced from " << before <<
" to " << after);
379 void setupCameraInfo(
const DepthSense::IntrinsicParameters& params, sensor_msgs::CameraInfo& cam_info)
381 cam_info.distortion_model =
"plumb_bob";
382 cam_info.height = params.height;
383 cam_info.width = params.width;
386 cam_info.D.resize(5);
387 cam_info.D[0] = params.k1;
388 cam_info.D[1] = params.k2;
389 cam_info.D[2] = params.p1;
390 cam_info.D[3] = params.p2;
391 cam_info.D[4] = params.k3;
397 cam_info.K[0] = params.fx;
398 cam_info.K[2] = params.cx;
399 cam_info.K[4] = params.fy;
400 cam_info.K[5] = params.cy;
416 cam_info.P[0] = params.fx;
417 cam_info.P[2] = params.cx;
418 cam_info.P[5] = params.fy;
419 cam_info.P[6] = params.cy;
420 cam_info.P[10] = 1.0;
430 FrameFormat_toResolution(data.captureConfiguration.frameFormat,
436 img_depth.data.resize(data_size *
sizeof(
float));
456 pcl::PointCloud<pcl::PointXYZRGB>::Ptr current_cloud(
new pcl::PointCloud<pcl::PointXYZRGB>());
457 current_cloud->header.frame_id =
cloud.header.frame_id;
458 current_cloud->width = w;
459 current_cloud->height = h;
460 current_cloud->is_dense =
true;
461 current_cloud->points.resize(w * h);
466 std::memcpy(
img_depth.data.data(), data.depthMapFloatingPoint,
img_depth.data.size());
468 for (
int count = 0; count < w * h; count++)
471 if (data.depthMapFloatingPoint[count] < 0.0)
473 *
reinterpret_cast<float*
>(&
img_depth.data[count*
sizeof(float)]) =
474 std::numeric_limits<float>::quiet_NaN();
487 UV uv = data.uvMap[count];
488 if (uv.u != -FLT_MAX && uv.v != -FLT_MAX)
492 int x_pos = (int)round(uv.u*
img_rgb.width);
493 int y_pos = (int)round(uv.v*
img_rgb.height);
494 current_cloud->points[count].b =
cv_img_rgb.at<cv::Vec3b>(y_pos, x_pos)[0];
495 current_cloud->points[count].g =
cv_img_rgb.at<cv::Vec3b>(y_pos, x_pos)[1];
496 current_cloud->points[count].r =
cv_img_rgb.at<cv::Vec3b>(y_pos, x_pos)[2];
503 current_cloud->points[count].x = data.verticesFloatingPoint[count].x + 0.025;
504 current_cloud->points[count].y = - data.verticesFloatingPoint[count].y;
505 current_cloud->points[count].z = data.verticesFloatingPoint[count].z;
536 ROS_WARN_THROTTLE(2.0,
"Calling radius outlier removal as the only filter would take too long!");
593 DepthNode::Configuration config =
g_dnode.getConfiguration();
598 config.saturation =
true;
603 g_dnode.setEnableVerticesFloatingPoint(
true);
604 g_dnode.setEnableDepthMapFloatingPoint(
true);
612 g_dnode.setConfiguration(config);
614 catch (ArgumentException& e)
616 printf(
"Argument Exception: %s\n", e.what());
618 catch (UnauthorizedAccessException& e)
620 printf(
"Unauthorized Access Exception: %s\n", e.what());
622 catch (IOException& e)
624 printf(
"IO Exception: %s\n", e.what());
626 catch (InvalidOperationException& e)
628 printf(
"Invalid Operation Exception: %s\n", e.what());
630 catch (ConfigurationException& e)
632 printf(
"Configuration Exception: %s\n", e.what());
634 catch (StreamingException& e)
636 printf(
"Streaming Exception: %s\n", e.what());
638 catch (TimeoutException&)
640 printf(
"TimeoutException\n");
650 ColorNode::Configuration config =
g_cnode.getConfiguration();
654 config.powerLineFrequency = POWER_LINE_FREQUENCY_50HZ;
657 g_cnode.setEnableColorMap(
true);
663 g_cnode.setConfiguration(config);
665 catch (ArgumentException& e)
667 printf(
"Argument Exception: %s\n", e.what());
669 catch (UnauthorizedAccessException& e)
671 printf(
"Unauthorized Access Exception: %s\n", e.what());
673 catch (IOException& e)
675 printf(
"IO Exception: %s\n", e.what());
677 catch (InvalidOperationException& e)
679 printf(
"Invalid Operation Exception: %s\n", e.what());
681 catch (ConfigurationException& e)
683 printf(
"Configuration Exception: %s\n", e.what());
685 catch (StreamingException& e)
687 printf(
"Streaming Exception: %s\n", e.what());
689 catch (TimeoutException&)
691 printf(
"TimeoutException\n");
700 g_dnode = node.as<DepthNode>();
707 g_cnode = node.as<ColorNode>();
731 if (data.node.is<ColorNode>() && (data.node.as<ColorNode>() ==
g_cnode))
733 if (data.node.is<DepthNode>() && (data.node.as<DepthNode>() ==
g_dnode))
735 printf(
"Node disconnected\n");
753 printf(
"Device disconnected\n");
817 "hfov = " <<
hfov <<
"\n" <<
818 "vfov = " <<
vfov <<
"\n" <<
822 "enable_depth = " << (
depth_enabled ?
"ON" :
"OFF" ) <<
"\n" <<
823 "depth_mode = " << config.depth_mode <<
"\n" <<
824 "depth_frame_format = " << config.depth_frame_format <<
"\n" <<
827 "enable_color = " << (
color_enabled ?
"ON" :
"OFF" ) <<
"\n" <<
828 "color_compression = " << config.color_compression <<
"\n" <<
829 "color_frame_format = " << config.color_frame_format <<
"\n" <<
833 "serial = " <<
serial <<
"\n");
837 int main(
int argc,
char* argv[])
840 ros::init(argc, argv,
"softkinetic_bringup_node");
855 std::string optical_frame;
856 if (nh.
getParam(
"rgb_optical_frame", optical_frame))
858 cloud.header.frame_id = optical_frame.c_str();
859 img_rgb.header.frame_id = optical_frame.c_str();
860 img_mono.header.frame_id = optical_frame.c_str();
864 img_rgb.header.frame_id =
"/softkinetic_rgb_optical_frame";
865 img_mono.header.frame_id =
"/softkinetic_rgb_optical_frame";
868 if (nh.
getParam(
"depth_optical_frame", optical_frame))
870 img_depth.header.frame_id = optical_frame.c_str();
874 img_depth.header.frame_id =
"/softkinetic_depth_optical_frame";
878 if (!nh.
hasParam(
"confidence_threshold"))
887 if (use_voxel_grid_filter)
895 if (use_radius_outlier_filter)
914 if(use_passthrough_filter)
933 if(use_frustum_culling_filter)
965 std::string depth_mode_str;
966 nh.
param<std::string>(
"depth_mode", depth_mode_str,
"close");
969 std::string depth_frame_format_str;
970 nh.
param<std::string>(
"depth_frame_format", depth_frame_format_str,
"QVGA");
976 std::string color_compression_str;
977 nh.
param<std::string>(
"color_compression", color_compression_str,
"MJPEG");
980 std::string color_frame_format_str;
981 nh.
param<std::string>(
"color_frame_format", color_frame_format_str,
"WXGA_H");
990 pub_cloud = nh.
advertise<sensor_msgs::PointCloud2>(
"depth/points", 1);
991 pub_rgb = it.advertise(
"rgb/image_color", 1);
992 pub_mono = it.advertise(
"rgb/image_mono", 1);
993 pub_depth = it.advertise(
"depth/image_raw", 1);
994 pub_depth_info = nh.
advertise<sensor_msgs::CameraInfo>(
"depth/camera_info", 1);
995 pub_rgb_info = nh.
advertise<sensor_msgs::CameraInfo>(
"rgb/camera_info", 1);
997 std::string calibration_file;
998 if (nh.
getParam(
"rgb_calibration_file", calibration_file))
1004 if (nh.
getParam(
"depth_calibration_file", calibration_file))
1010 g_context = Context::create(
"softkinetic");
1016 vector<Device> da =
g_context.getDevices();
1020 int device_index = 0;
1032 device_index = atoi(argv[1]);
1040 bool serialDeviceFound =
false;
1041 for (
int i=0; i < da.size(); i++)
1043 if (!da[i].getSerialNumber().compare(
serial))
1046 serialDeviceFound =
true;
1049 if (serialDeviceFound)
1060 ROS_INFO_STREAM(
"Serial Number: " << da[device_index].getSerialNumber());
1067 vector<Node> na = da[device_index].getNodes();
1069 for (
int n = 0; n < (int)na.size(); n++)
1078 dynamic_reconfigure::Server<softkinetic_camera::SoftkineticConfig> server(nh_cfg);
sensor_msgs::PointCloud2 cloud
void setupCameraInfo(const DepthSense::IntrinsicParameters ¶ms, sensor_msgs::CameraInfo &cam_info)
#define ROS_WARN_THROTTLE(rate,...)
sensor_msgs::CameraInfo getCameraInfo(void)
void onDeviceConnected(Context context, Context::DeviceAddedData data)
DepthSense::DepthNode::CameraMode depth_mode
void publish(const boost::shared_ptr< M > &message) const
void sigintHandler(int sig)
ros::Publisher pub_rgb_info
void filterPassThrough(pcl::PointCloud< pcl::PointXYZRGB >::Ptr cloud_to_filter)
ROSCPP_DECL void init(int &argc, char **argv, const std::string &name, uint32_t options=0)
void onNewColorSample(ColorNode node, ColorNode::NewSampleReceivedData data)
int main(int argc, char *argv[])
void reconfigure_callback(softkinetic_camera::SoftkineticConfig &config, uint32_t level)
DepthSense::FrameFormat color_frame_format
ROSCPP_DECL const std::string & getName()
void configureColorNode()
void downsampleCloud(pcl::PointCloud< pcl::PointXYZRGB >::Ptr cloud_to_filter)
DepthSense::FrameFormat depth_frame_format
DepthSense::CompressionType color_compression
ros::Publisher pub_depth_info
image_transport::Publisher pub_depth
DepthSense::FrameFormat depthFrameFormat(const std::string &depth_frame_format_str)
void onNodeConnected(Device device, Device::NodeAddedData data)
image_transport::Publisher pub_rgb
CvImagePtr cvtColor(const CvImageConstPtr &source, const std::string &encoding)
void configureNode(Node node)
void publish(const sensor_msgs::Image &message) const
bool param(const std::string ¶m_name, T ¶m_val, const T &default_val) const
void setCallbackQueue(CallbackQueueInterface *queue)
sensor_msgs::CameraInfo depth_info
const std::string TYPE_32FC1
void onDeviceDisconnected(Context context, Context::DeviceRemovedData data)
DepthSense::DepthNode::CameraMode depthMode(const std::string &depth_mode_str)
bool use_voxel_grid_filter
void filterCloudRadiusBased(pcl::PointCloud< pcl::PointXYZRGB >::Ptr cloud_to_filter)
Publisher advertise(const std::string &topic, uint32_t queue_size, bool latch=false)
sensor_msgs::CameraInfo rgb_info
#define ROS_DEBUG_STREAM(args)
void configureDepthNode()
DepthSense::FrameFormat colorFrameFormat(const std::string &color_frame_format_str)
sensor_msgs::Image img_rgb
TFSIMD_FORCE_INLINE const tfScalar & w() const
image_transport::Publisher pub_mono
#define ROS_INFO_STREAM(args)
void onNodeDisconnected(Device device, Device::NodeRemovedData data)
bool getParam(const std::string &key, std::string &s) const
void toROSMsg(const sensor_msgs::PointCloud2 &cloud, sensor_msgs::Image &image)
void onNewAudioSample(AudioNode node, AudioNode::NewSampleReceivedData data)
bool use_frustum_culling_filter
ROSCPP_DECL void shutdown()
sensor_msgs::Image img_mono
bool use_passthrough_filter
bool hasParam(const std::string &key) const
void onNewDepthSample(DepthNode node, DepthNode::NewSampleReceivedData data)
#define ROS_ERROR_STREAM(args)
DepthSense::CompressionType colorCompression(const std::string &color_compression_str)
sensor_msgs::Image img_depth
bool use_radius_outlier_filter
void filterFrustumCulling(pcl::PointCloud< pcl::PointXYZRGB >::Ptr cloud_to_filter)
void configureAudioNode()