46 ConnectionBasedNodelet::onInit();
65 pnh_->param(
"fill_value",
fill_value, std::numeric_limits<float>::quiet_NaN());
80 std::vector<double> trans_pos(3, 0);
81 std::vector<double> trans_quat(4, 0); trans_quat[3] = 1.0;
82 if (
pnh_->hasParam(
"translation")) {
85 ROS_INFO(
"translation : %f %f %f", trans_pos[0], trans_pos[1], trans_pos[2]);
86 if (
pnh_->hasParam(
"rotation")) {
89 ROS_INFO(
"rotation : %f %f %f %f", trans_quat[0], trans_quat[1], trans_quat[2], trans_quat[3]);
90 tf::Quaternion btq(trans_quat[0], trans_quat[1], trans_quat[2], trans_quat[3]);
91 tf::Vector3 btp(trans_pos[0], trans_pos[1], trans_pos[2]);
103 service_ = pnh_->advertiseService(
"set_point_cloud",
121 sync_inputs_a_ = boost::make_shared <message_filters::Synchronizer<message_filters::sync_policies::ApproximateTime<sensor_msgs::CameraInfo, sensor_msgs::PointCloud2> > > (
max_queue_size_);
125 sync_inputs_e_ = boost::make_shared <message_filters::Synchronizer<message_filters::sync_policies::ExactTime<sensor_msgs::CameraInfo, sensor_msgs::PointCloud2> > > (
max_queue_size_);
155 std_srvs::Empty::Response &
res) {
160 const sensor_msgs::PointCloud2ConstPtr& pcloud2) {
161 ROS_DEBUG(
"DepthImageCreator::callback_sync");
166 ROS_DEBUG(
"DepthImageCreator::callback_cloud");
172 ROS_DEBUG(
"DepthImageCreator::callback_info");
185 const sensor_msgs::PointCloud2ConstPtr& pcloud2) {
186 sensor_msgs::PointCloud2Ptr pcloud2_ptr(
new sensor_msgs::PointCloud2(*pcloud2));
190 "y", 1, sensor_msgs::PointField::FLOAT32,
191 "z", 1, sensor_msgs::PointField::FLOAT32,
192 "rgb", 1, sensor_msgs::PointField::FLOAT32);
195 ROS_DEBUG(
"DepthImageCreator::publish_points");
196 if (!pcloud2_ptr)
return;
197 bool proc_cloud =
true, proc_depth =
true, proc_image =
true, proc_disp =
true;
210 if( !proc_cloud && !proc_depth && !proc_image && !proc_disp)
return;
212 int width = info->width;
213 int height = info->height;
214 float fx = info->P[0];
215 float cx = info->P[2];
216 float tx = info->P[3];
217 float fy = info->P[5];
218 float cy = info->P[6];
220 Eigen::Affine3f sensorPose;
228 info->header.frame_id,
232 info->header.frame_id,
233 info->header.stamp, transform);
235 catch ( std::runtime_error e ) {
242 sensorPose = (Eigen::Affine3f)Eigen::Translation3f(p.
getX(), p.
getY(), p.
getZ());
243 Eigen::Quaternion<float>
rot(q.
getW(), q.getX(), q.getY(), q.getZ());
244 sensorPose = sensorPose *
rot;
247 Eigen::Affine3f trans = (Eigen::Affine3f)Eigen::Translation3f(-tx/fx , 0, 0);
248 sensorPose = sensorPose * trans;
251 ROS_INFO(
"%f %f %f %f %f %f %f %f %f, %f %f %f",
252 sensorPose(0,0), sensorPose(0,1), sensorPose(0,2),
253 sensorPose(1,0), sensorPose(1,1), sensorPose(1,2),
254 sensorPose(2,0), sensorPose(2,1), sensorPose(2,2),
255 sensorPose(0,3), sensorPose(1,3), sensorPose(2,3));
260 pcl::RangeImagePlanar rangeImageP;
267 #if ( PCL_MAJOR_VERSION >= 1 && PCL_MINOR_VERSION >= 5 ) 268 inv = sensorPose.inverse();
269 pcl::transformPointCloud< Point > (tpc, pointCloud, inv);
271 pcl::getInverse(sensorPose, inv);
272 pcl::getTransformedPointCloud<PointCloud> (tpc, inv, pointCloud);
275 Eigen::Affine3f dummytrans;
276 dummytrans.setIdentity();
277 rangeImageP.createFromPointCloudWithFixedSize (pointCloud,
285 cv::Mat color_mat = cv::Mat::zeros(rangeImageP.height, rangeImageP.width, CV_8UC3);
286 cv::Mat depth_mat(rangeImageP.height, rangeImageP.width, CV_32FC1);
288 for (
size_t i=0; i<pointCloud.size(); i++) {
289 Point pt = pointCloud[i];
293 rangeImageP.getImagePoint(pt.x, pt.y, pt.z, image_x, image_y);
295 if (!rangeImageP.isInImage(image_x, image_y)) {
299 pcl::PointWithRange pt_with_range = rangeImageP.getPoint(image_x, image_y);
300 depth_mat.at<
float>(image_y, image_x) = pt_with_range.z;
302 if (!std::isnan(pt.x) && !std::isnan(pt.y) && !std::isnan(pt.z)) {
303 color_mat.at<cv::Vec3b>(image_y, image_x) = cv::Vec3b(pt.r, pt.g, pt.b);
309 cv::resize(color_mat, color_mat, cv::Size(info->width, info->height));
310 cv::resize(depth_mat, depth_mat, cv::Size(info->width, info->height));
324 if(proc_cloud || proc_disp) {
326 pcl::RangeImagePlanar rangeImagePP;
327 rangeImagePP.setDepthImage ((
float *)depth_mat.ptr(),
330 #if PCL_MAJOR_VERSION == 1 && PCL_MINOR_VERSION >= 7 333 rangeImagePP.header = info->header;
337 cloud_out.header = rangeImagePP.header;
339 cloud_out.width = rangeImagePP.width;
340 cloud_out.height = rangeImagePP.height;
342 cloud_out.width = rangeImagePP.width * rangeImagePP.height;
343 cloud_out.height = 1;
345 cloud_out.resize(cloud_out.width * cloud_out.height);
346 cloud_out.is_dense =
true;
347 for (
int y = 0;
y < (int)rangeImagePP.height;
y++ ) {
348 for (
int x = 0;
x < (int)rangeImagePP.width;
x++ ) {
349 pcl::PointWithRange pt_from = rangeImagePP.points[rangeImagePP.width *
y +
x];
350 cv::Vec3b
rgb = color_mat.at<cv::Vec3b>(
y,
x);
358 cloud_out.points[rangeImagePP.width * y +
x] = pt_to;
359 if (std::isnan(pt_to.x) || std::isnan(pt_to.y) || std::isnan(pt_to.z)) {
360 cloud_out.is_dense =
false;
368 stereo_msgs::DisparityImage disp;
369 #if PCL_MAJOR_VERSION == 1 && PCL_MINOR_VERSION >= 7 372 disp.header = rangeImagePP.header;
375 disp.image.height = rangeImagePP.height;
376 disp.image.width = rangeImagePP.width;
377 disp.image.step = disp.image.width *
sizeof(
float);
378 disp.f = fx; disp.T = 0.075;
379 disp.min_disparity = 0;
380 disp.max_disparity = disp.T * disp.f / 0.3;
381 disp.delta_d = 0.125;
383 disp.image.data.resize (disp.image.height * disp.image.step);
384 float *
data =
reinterpret_cast<float*
> (&disp.image.data[0]);
386 float normalization_factor = disp.f * disp.T;
387 for (
int y = 0;
y < (int)rangeImagePP.height;
y++ ) {
388 for (
int x = 0;
x < (int)rangeImagePP.width;
x++ ) {
389 pcl::PointWithRange
p = rangeImagePP.getPoint(
x,
y);
390 data[
y*disp.image.width+
x] = normalization_factor / p.z;
ros::Publisher pub_cloud_
ros::Publisher pub_depth_
void publish(const boost::shared_ptr< M > &message) const
boost::mutex mutex_points
message_filters::Subscriber< sensor_msgs::CameraInfo > sub_info_
const std::string & getName() const
void fromROSMsg(const sensor_msgs::PointCloud2 &cloud, pcl::PointCloud< T > &pcl_cloud)
TFSIMD_FORCE_INLINE const tfScalar & getY() const
void setPointCloud2Fields(int n_fields,...)
ros::Publisher pub_disp_image_
bool service_cb(std_srvs::Empty::Request &req, std_srvs::Empty::Response &res)
TFSIMD_FORCE_INLINE const tfScalar & getW() const
bool hasField(const std::string &field_name, const sensor_msgs::PointCloud2 &msg)
TFSIMD_FORCE_INLINE const tfScalar & getZ() const
void toPCL(const pcl_msgs::PointIndices &pi, pcl::PointIndices &pcl_pi)
ros::Subscriber sub_as_info_
PLUGINLIB_EXPORT_CLASS(jsk_pcl_ros::DepthImageCreator, nodelet::Nodelet)
ros::Publisher pub_image_
void callback_info(const sensor_msgs::CameraInfoConstPtr &info)
void callback_cloud(const sensor_msgs::PointCloud2ConstPtr &pcloud2)
const std::string TYPE_32FC1
ros::Subscriber sub_as_cloud_
boost::shared_ptr< message_filters::Synchronizer< message_filters::sync_policies::ApproximateTime< sensor_msgs::CameraInfo, sensor_msgs::PointCloud2 > > > sync_inputs_a_
sensor_msgs::PointCloud2ConstPtr points_ptr_
boost::shared_ptr< message_filters::Synchronizer< message_filters::sync_policies::ExactTime< sensor_msgs::CameraInfo, sensor_msgs::PointCloud2 > > > sync_inputs_e_
void publish_points(const sensor_msgs::CameraInfoConstPtr &info, const sensor_msgs::PointCloud2ConstPtr &pcloud2)
void callback_sync(const sensor_msgs::CameraInfoConstPtr &info, const sensor_msgs::PointCloud2ConstPtr &pcloud2)
#define NODELET_INFO(...)
uint32_t getNumSubscribers() const
void subscribe(ros::NodeHandle &nh, const std::string &topic, uint32_t queue_size, const ros::TransportHints &transport_hints=ros::TransportHints(), ros::CallbackQueueInterface *callback_queue=0)
message_filters::Subscriber< sensor_msgs::PointCloud2 > sub_cloud_
TFSIMD_FORCE_INLINE const tfScalar & getX() const
static tf::TransformListener * getInstance()
tf::TransformListener * tf_listener_
pcl::PointCloud< Point > PointCloud
ros::ServiceServer service_
sensor_msgs::ImagePtr toImageMsg() const
std_msgs::Header fromPCL(const pcl::PCLHeader &pcl_header)
tf::StampedTransform fixed_transform