attention_clipper_nodelet.cpp
Go to the documentation of this file.
00001 // -*- mode: c++ -*-
00002 /*********************************************************************
00003  * Software License Agreement (BSD License)
00004  *
00005  *  Copyright (c) 2014, JSK Lab
00006  *  All rights reserved.
00007  *
00008  *  Redistribution and use in source and binary forms, with or without
00009  *  modification, are permitted provided that the following conditions
00010  *  are met:
00011  *
00012  *   * Redistributions of source code must retain the above copyright
00013  *     notice, this list of conditions and the following disclaimer.
00014  *   * Redistributions in binary form must reproduce the above
00015  *     copyright notice, this list of conditions and the following
00016  *     disclaimer in the documentation and/o2r other materials provided
00017  *     with the distribution.
00018  *   * Neither the name of the JSK Lab nor the names of its
00019  *     contributors may be used to endorse or promote products derived
00020  *     from this software without specific prior written permission.
00021  *
00022  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00023  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00024  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00025  *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00026  *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00027  *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00028  *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00029  *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00030  *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00031  *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00032  *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00033  *  POSSIBILITY OF SUCH DAMAGE.
00034  *********************************************************************/
00035 #define BOOST_PARAMETER_MAX_ARITY 7
00036 #include "jsk_pcl_ros/attention_clipper.h"
00037 #include <eigen_conversions/eigen_msg.h>
00038 #include <tf_conversions/tf_eigen.h>
00039 #include <opencv2/opencv.hpp>
00040 #include <cv_bridge/cv_bridge.h>
00041 #include <sensor_msgs/image_encodings.h>
00042 #include <pcl/filters/crop_box.h>
00043 #include <pcl_ros/transforms.h>
00044 #include "jsk_pcl_ros/pcl_conversion_util.h"
00045 #include <jsk_topic_tools/rosparam_utils.h>
00046 #include "jsk_pcl_ros/pcl_util.h"
00047 #include <algorithm>
00048 #include <set>
00049 namespace jsk_pcl_ros
00050 {
00051   void AttentionClipper::onInit()
00052   {
00053     DiagnosticNodelet::onInit();
00054     tf_listener_ = TfListenerSingleton::getInstance();
00055     pnh_->param("negative", negative_, false);
00056     pnh_->param("use_multiple_attention", use_multiple_attention_, false);
00057     if (!use_multiple_attention_) {
00058       Eigen::Affine3f pose = Eigen::Affine3f::Identity();
00059       std::vector<double> initial_pos;
00060       if (jsk_topic_tools::readVectorParameter(*pnh_,
00061                                                "initial_pos",
00062                                                initial_pos))
00063       {
00064         pose.translation() = Eigen::Vector3f(initial_pos[0],
00065                                               initial_pos[1],
00066                                               initial_pos[2]);
00067       }
00068 
00069       std::vector<double> initial_rot;
00070       if (jsk_topic_tools::readVectorParameter(*pnh_,
00071                                                "initial_rot",
00072                                                initial_rot))
00073       {
00074         pose = pose
00075           * Eigen::AngleAxisf(initial_rot[0],
00076                               Eigen::Vector3f::UnitX())
00077           * Eigen::AngleAxisf(initial_rot[1],
00078                               Eigen::Vector3f::UnitY())
00079           * Eigen::AngleAxisf(initial_rot[2],
00080                               Eigen::Vector3f::UnitZ());
00081       }
00082 
00083       // parameter
00084       // backward compatibility
00085       double dimension_x, dimension_y, dimension_z;
00086       pnh_->param("dimension_x", dimension_x, 0.1);
00087       pnh_->param("dimension_y", dimension_y, 0.1);
00088       pnh_->param("dimension_z", dimension_z, 0.1);
00089       dimensions_.push_back(Eigen::Vector3f(dimension_x,
00090                                             dimension_y,
00091                                             dimension_z));
00092       std::string frame_id;
00093       pnh_->param("frame_id", frame_id, std::string("base_link"));
00094       frame_id_list_.push_back(frame_id);
00095       pose_list_.push_back(pose);
00096     }
00097     else {                      // multiple interst
00098       // ~initial_pos_list
00099       //   -> [[0, 0, 0], ...]
00100       std::vector<std::vector<double> > initial_pos_list;
00101       std::vector<std::vector<double> > initial_rot_list;
00102       std::vector<std::vector<double> > dimensions;
00103       jsk_topic_tools::readVectorParameter(*pnh_, "initial_pos_list",
00104                                            initial_pos_list);
00105       jsk_topic_tools::readVectorParameter(*pnh_, "initial_rot_list",
00106                                            initial_rot_list);
00107       jsk_topic_tools::readVectorParameter(*pnh_, "dimensions", dimensions);
00108       jsk_topic_tools::readVectorParameter(*pnh_, "prefixes", prefixes_);
00109       if (initial_pos_list.size() != 0) {
00110         initializePoseList(initial_pos_list.size());
00111         for (size_t i = 0; i < initial_pos_list.size(); i++) {
00112           if (initial_pos_list[i].size() != 3) {
00113             JSK_NODELET_FATAL("element of ~initial_pos_list should be [x, y, z]");
00114             return;
00115           }
00116           pose_list_[i].translation() = Eigen::Vector3f(initial_pos_list[i][0],
00117                                                         initial_pos_list[i][1],
00118                                                         initial_pos_list[i][2]);
00119         }
00120       }
00121       // ~initial_rot_list
00122       //   -> [[0, 0, 0], ...]
00123       if (initial_rot_list.size() != 0) {
00124         // error check
00125         if (initial_pos_list.size() != 0 &&
00126             initial_rot_list.size() != initial_pos_list.size()) {
00127           JSK_NODELET_FATAL(
00128             "the size of ~initial_pos_list and ~initial_rot_list are different");
00129           return;
00130         }
00131         if (initial_pos_list.size() == 0) {
00132           initializePoseList(initial_rot_list.size());
00133         }
00134         for (size_t i = 0; i < initial_rot_list.size(); i++) {
00135           if (initial_rot_list[i].size() != 3) {
00136             JSK_NODELET_FATAL("element of ~initial_rot_list should be [rx, ry, rz]");
00137             return;
00138           }
00139           pose_list_[i] = pose_list_[i]
00140             * Eigen::AngleAxisf(initial_rot_list[i][0],
00141                                 Eigen::Vector3f::UnitX())
00142             * Eigen::AngleAxisf(initial_rot_list[i][1],
00143                                 Eigen::Vector3f::UnitY())
00144             * Eigen::AngleAxisf(initial_rot_list[i][2],
00145                                 Eigen::Vector3f::UnitZ());
00146         }
00147       }
00148       // ~dimensions
00149       //   -> [[x, y, z], [x, y, z] ...]
00150       if (dimensions.size() != 0) {
00151         // error check
00152         if (pose_list_.size() != 0 &&
00153             pose_list_.size() != dimensions.size()) {
00154           JSK_NODELET_FATAL(
00155             "the size of ~dimensions and ~initial_pos_list or ~initial_rot_list are different");
00156           return;
00157         }
00158         if (pose_list_.size() == 0) {
00159           initializePoseList(dimensions.size());
00160         }
00161         for (size_t i = 0; i < dimensions.size(); i++) {
00162           dimensions_.push_back(Eigen::Vector3f(dimensions[i][0],
00163                                                 dimensions[i][1],
00164                                                 dimensions[i][2]));
00165         }
00166       }
00167 
00168       // ~prefixes
00169       //   -> [left_hand, right_hand ...]
00170       if (prefixes_.size() != 0) {
00171         // error check
00172         if (prefixes_.size() != dimensions.size()) {
00173           JSK_NODELET_FATAL(
00174             "the size of ~prefixes and ~dimensions are different");
00175           return;
00176         }
00177         for(int i = 0; i < prefixes_.size(); i++){
00178           multiple_pub_indices_.push_back(advertise<PCLIndicesMsg>(*pnh_, prefixes_[i]+std::string("/point_indices"), 1));
00179         }
00180       }
00181 
00182       jsk_topic_tools::readVectorParameter(*pnh_, "frame_id_list", frame_id_list_);
00183     }
00184     pub_camera_info_ = advertise<sensor_msgs::CameraInfo>(*pnh_, "output", 1);
00185     pub_bounding_box_array_
00186       = advertise<jsk_recognition_msgs::BoundingBoxArray>(*pnh_, "output/box_array", 1);
00187     pub_mask_ = advertise<sensor_msgs::Image>(*pnh_, "output/mask", 1);
00188     pub_indices_ = advertise<PCLIndicesMsg>(*pnh_, "output/point_indices", 1);
00189     pub_cluster_indices_ = advertise<jsk_recognition_msgs::ClusterPointIndices>(*pnh_, "output/cluster_point_indices", 1);
00190   }
00191 
00192   void AttentionClipper::initializePoseList(size_t num)
00193   {
00194     pose_list_.resize(num);
00195     for (size_t i = 0; i < pose_list_.size(); i++) {
00196       pose_list_[i].setIdentity();
00197     }
00198   }
00199 
00200   void AttentionClipper::subscribe()
00201   {
00202     sub_ = pnh_->subscribe("input", 1, &AttentionClipper::clip, this);
00203     sub_points_ = pnh_->subscribe("input/points", 1,
00204                                   &AttentionClipper::clipPointcloud, this);
00205     if (!use_multiple_attention_) {
00206       sub_pose_ = pnh_->subscribe("input/pose",
00207                                   1, &AttentionClipper::poseCallback, this);
00208       sub_box_ = pnh_->subscribe("input/box",
00209                                  1, &AttentionClipper::boxCallback, this);
00210     }
00211     else {
00212       sub_pose_ = pnh_->subscribe("input/pose_array",
00213                                   1, &AttentionClipper::poseArrayCallback, this);
00214       sub_box_ = pnh_->subscribe("input/box_array",
00215                                  1, &AttentionClipper::boxArrayCallback, this);
00216     }
00217   }
00218 
00219   void AttentionClipper::unsubscribe()
00220   {
00221     sub_.shutdown();
00222     sub_points_.shutdown();
00223     sub_pose_.shutdown();
00224     sub_box_.shutdown();
00225   }
00226 
00227   Vertices AttentionClipper::cubeVertices(Eigen::Vector3f& dimension)
00228   {
00229     Vertices nonoffsetted_vertices;
00230     nonoffsetted_vertices.push_back(
00231       Eigen::Vector3f(-dimension[0]/2, -dimension[1]/2, -dimension[2]/2));
00232     nonoffsetted_vertices.push_back(
00233       Eigen::Vector3f(-dimension[0]/2, -dimension[1]/2, dimension[2]/2));
00234     nonoffsetted_vertices.push_back(
00235       Eigen::Vector3f(-dimension[0]/2, dimension[1]/2, -dimension[2]/2));
00236     nonoffsetted_vertices.push_back(
00237       Eigen::Vector3f(-dimension[0]/2, dimension[1]/2, dimension[2]/2));
00238     nonoffsetted_vertices.push_back(
00239       Eigen::Vector3f(dimension[0]/2, -dimension[1]/2, -dimension[2]/2));
00240     nonoffsetted_vertices.push_back(
00241       Eigen::Vector3f(dimension[0]/2, -dimension[1]/2, dimension[2]/2));
00242     nonoffsetted_vertices.push_back(
00243       Eigen::Vector3f(dimension[0]/2, dimension[1]/2, -dimension[2]/2));
00244     nonoffsetted_vertices.push_back(
00245       Eigen::Vector3f(dimension[0]/2, dimension[1]/2, dimension[2]/2));
00246     return nonoffsetted_vertices;
00247   }
00248 
00249   // callback only for one interaction
00250   void AttentionClipper::poseCallback(
00251     const geometry_msgs::PoseStamped::ConstPtr& pose)
00252   {
00253     boost::mutex::scoped_lock lock(mutex_);
00254     frame_id_list_[0] = pose->header.frame_id;
00255     tf::poseMsgToEigen(pose->pose, pose_list_[0]);
00256   }
00257 
00258   void AttentionClipper::boxCallback(
00259     const jsk_recognition_msgs::BoundingBox::ConstPtr& box)
00260   {
00261     boost::mutex::scoped_lock lock(mutex_);
00262     dimensions_[0][0] = box->dimensions.x;
00263     dimensions_[0][1] = box->dimensions.y;
00264     dimensions_[0][2] = box->dimensions.z;
00265     frame_id_list_[0] = box->header.frame_id;
00266     tf::poseMsgToEigen(box->pose, pose_list_[0]);
00267   }
00268 
00269   // callback for multiple interactions
00270   void AttentionClipper::poseArrayCallback(
00271     const geometry_msgs::PoseArray::ConstPtr& pose_array)
00272   {
00273     boost::mutex::scoped_lock lock(mutex_);
00274     // resize
00275     initializePoseList(pose_array->poses.size());
00276     frame_id_list_.resize(pose_array->poses.size());
00277     std::fill(frame_id_list_.begin(), frame_id_list_.end(),
00278               pose_array->header.frame_id);
00279     for (size_t i = 0; i < pose_list_.size(); i++) {
00280       tf::poseMsgToEigen(pose_array->poses[i], pose_list_[i]);
00281     }
00282   }
00283 
00284   void AttentionClipper::boxArrayCallback(
00285     const jsk_recognition_msgs::BoundingBoxArray::ConstPtr& box_array)
00286   {
00287     boost::mutex::scoped_lock lock(mutex_);
00288     initializePoseList(box_array->boxes.size());
00289     frame_id_list_.resize(box_array->boxes.size());
00290     dimensions_.resize(box_array->boxes.size());
00291     for (size_t i = 0; i < pose_list_.size(); i++) {
00292       tf::poseMsgToEigen(box_array->boxes[i].pose, pose_list_[i]);
00293       frame_id_list_[i] = box_array->boxes[i].header.frame_id;
00294       dimensions_[i] = Eigen::Vector3f(box_array->boxes[i].dimensions.x,
00295                                        box_array->boxes[i].dimensions.y,
00296                                        box_array->boxes[i].dimensions.z);
00297     }
00298   }
00299 
00300   void AttentionClipper::publishBoundingBox(
00301     const std_msgs::Header& header)
00302   {
00303     jsk_recognition_msgs::BoundingBoxArray box_array;
00304     box_array.header.frame_id = header.frame_id;
00305     box_array.header.stamp = header.stamp;
00306     for (size_t i = 0; i < pose_list_.size(); i++) {
00307       jsk_recognition_msgs::BoundingBox box;
00308       box.header.stamp = header.stamp;
00309       box.header.frame_id = frame_id_list_[i];
00310       tf::poseEigenToMsg(pose_list_[i], box.pose);
00311       jsk_pcl_ros::pointFromVectorToXYZ(dimensions_[i], box.dimensions);
00312       box_array.boxes.push_back(box);
00313     }
00314     pub_bounding_box_array_.publish(box_array);
00315   }
00316 
00317   void AttentionClipper::computeROI(
00318     const sensor_msgs::CameraInfo::ConstPtr& msg,
00319     std::vector<cv::Point2d>& points,
00320     cv::Mat& mask)
00321   {
00322     double min_u, min_v, max_u, max_v;
00323     min_u = msg->width;
00324     min_v = msg->height;
00325     max_u = max_v = 0;
00326     for (size_t i = 0; i < points.size(); i++) {
00327       cv::Point2d uv(points[i]);
00328       // check limit
00329       if (uv.x < 0) {
00330         uv.x = 0;
00331       }
00332       if (uv.y < 0) {
00333         uv.y = 0;
00334       }
00335       if (uv.x > msg->width) {
00336         uv.x = msg->width;
00337       }
00338 
00339       if (uv.y > msg->height) {
00340         uv.y = msg->height;
00341       }
00342       if (min_u > uv.x) {
00343         min_u = uv.x;
00344       }
00345       if (max_u < uv.x) {
00346         max_u = uv.x;
00347       }
00348       if (min_v > uv.y) {
00349         min_v = uv.y;
00350       }
00351 
00352       if (max_v < uv.y) {
00353         max_v = uv.y;
00354       }
00355     }
00356     // now we have min/max of u/v
00357     cv::Rect raw_roi(min_u, min_v, (max_u - min_u), (max_v - min_v));
00358     cv::Rect original(0, 0, msg->width, msg->height);
00359     cv::Rect roi_region = raw_roi & original;
00360     sensor_msgs::CameraInfo roi(*msg);
00361     roi.roi.x_offset = roi_region.x;
00362     roi.roi.y_offset = roi_region.y;
00363     roi.roi.width = roi_region.width;
00364     roi.roi.height = roi_region.height;
00365     roi.roi.do_rectify = true;
00366     pub_camera_info_.publish(roi);
00367     // mask computation
00368     mask = cv::Mat::zeros(msg->height, msg->width, CV_8UC1);
00369     cv::Size roi_size(roi_region.width, roi_region.height);
00370     cv::Rect roi_rect(cv::Point(roi_region.x, roi_region.y), roi_size);
00371     const cv::Scalar white(255);
00372     cv::rectangle(mask, roi_rect, white, CV_FILLED);
00373   }
00374 
00375   void AttentionClipper::clipPointcloud(
00376     const sensor_msgs::PointCloud2::ConstPtr& msg)
00377   {
00378     boost::mutex::scoped_lock lock(mutex_);
00379     JSK_NODELET_DEBUG("clipPointcloud");
00380     vital_checker_->poke();
00381     try {
00382       // 1. transform pointcloud
00383       // 2. crop by boundingbox
00384       // 3. publish indices
00385       pcl::PointIndices::Ptr all_indices (new pcl::PointIndices);
00386       jsk_recognition_msgs::ClusterPointIndices cluster_indices_msg;
00387       std::map<std::string, tf::StampedTransform> transforms;
00388       for (size_t i = 0; i < pose_list_.size(); i++) {
00389         std::string frame_id = frame_id_list_[i];
00390         // check transform cache
00391         if (transforms.find(frame_id) == transforms.end()) {
00392           tf::StampedTransform new_transform = lookupTransformWithDuration(
00393             tf_listener_,
00394             frame_id, msg->header.frame_id,
00395             msg->header.stamp,
00396             ros::Duration(1.0));
00397           transforms[frame_id] = new_transform;
00398         }
00399         tf::StampedTransform tf_transform = transforms[frame_id];
00400         Eigen::Affine3f transform;
00401         tf::transformTFToEigen(tf_transform, transform);
00402         pcl::PointCloud<pcl::PointXYZ>::Ptr
00403           cloud(new pcl::PointCloud<pcl::PointXYZ>);
00404         pcl::PointCloud<pcl::PointXYZ>::Ptr
00405           input_cloud(new pcl::PointCloud<pcl::PointXYZ>);
00406         pcl::fromROSMsg(*msg, *input_cloud);
00407         pcl::transformPointCloud(*input_cloud, *cloud, transform);
00408         pcl::CropBox<pcl::PointXYZ> crop_box(false);
00409         pcl::PointIndices::Ptr indices (new pcl::PointIndices);
00410         JSK_NODELET_DEBUG("max_points: [%f, %f, %f]", dimensions_[i][0]/2,
00411                       dimensions_[i][1]/2,
00412                       dimensions_[i][2]/2);
00413         JSK_NODELET_DEBUG("min_points: [%f, %f, %f]",
00414                       -dimensions_[i][0]/2,
00415                       -dimensions_[i][1]/2,
00416                       -dimensions_[i][2]/2);
00417         Eigen::Vector4f max_points(dimensions_[i][0]/2,
00418                                    dimensions_[i][1]/2,
00419                                    dimensions_[i][2]/2,
00420                                    0);
00421         Eigen::Vector4f min_points(-dimensions_[i][0]/2,
00422                                    -dimensions_[i][1]/2,
00423                                    -dimensions_[i][2]/2,
00424                                    0);
00425         float roll, pitch, yaw;
00426         pcl::getEulerAngles(pose_list_[i], roll, pitch, yaw);
00427         crop_box.setInputCloud(cloud);
00428         crop_box.setMax(max_points);
00429         crop_box.setMin(min_points);
00430         crop_box.setTranslation(pose_list_[i].translation());
00431         crop_box.setRotation(Eigen::Vector3f(roll, pitch, yaw));
00432         crop_box.filter(indices->indices);
00433         // indices->indices may include NaN and inf points
00434         // https://github.com/jsk-ros-pkg/jsk_recognition/issues/888
00435         pcl::PointIndices non_nan_indices;
00436         for (size_t j = 0; j < indices->indices.size(); j++) {
00437           pcl::PointXYZ p = cloud->points[indices->indices[j]];
00438           if (pcl_isfinite(p.x) && pcl_isfinite(p.y) && pcl_isfinite(p.z)) {
00439             non_nan_indices.indices.push_back(indices->indices[j]);
00440           }
00441         }
00442         PCLIndicesMsg indices_msg;
00443         pcl_conversions::fromPCL(non_nan_indices, indices_msg);
00444         cluster_indices_msg.cluster_indices.push_back(indices_msg);
00445         if(prefixes_.size()){
00446           indices_msg.header = msg->header;
00447           multiple_pub_indices_[i].publish(indices_msg);
00448         }
00449 
00450         all_indices = addIndices(*all_indices, non_nan_indices);
00451       }
00452       if (negative_) {
00453         // Publish indices which is NOT inside of box.
00454         pcl::PointIndices::Ptr tmp_indices (new pcl::PointIndices);
00455         std::set<int> positive_indices(all_indices->indices.begin(), all_indices->indices.end());
00456         for (size_t i = 0; i < msg->width * msg->height; i++) {
00457           if (positive_indices.find(i) == positive_indices.end()) {
00458             tmp_indices->indices.push_back(i);
00459           }
00460         }
00461         all_indices = tmp_indices;
00462       }
00463       PCLIndicesMsg indices_msg;
00464       pcl_conversions::fromPCL(*all_indices, indices_msg);
00465       cluster_indices_msg.header = indices_msg.header = msg->header;
00466       pub_indices_.publish(indices_msg);
00467       pub_cluster_indices_.publish(cluster_indices_msg);
00468       publishBoundingBox(msg->header);
00469     }
00470     catch (std::runtime_error &e) {
00471       NODELET_ERROR("[%s] Transform error: %s", __PRETTY_FUNCTION__, e.what());
00472     } 
00473   }
00474 
00475   void AttentionClipper::clip(const sensor_msgs::CameraInfo::ConstPtr& msg)
00476   {
00477     boost::mutex::scoped_lock lock(mutex_);
00478     vital_checker_->poke();
00479     // resolve tf for all interest
00480     try {
00481       image_geometry::PinholeCameraModel model;
00482       cv::Mat all_mask_image = cv::Mat::zeros(msg->height, msg->width, CV_8UC1);
00483       bool model_success_p = model.fromCameraInfo(msg);
00484       if (!model_success_p) {
00485         JSK_ROS_ERROR("failed to create camera model");
00486         return;
00487       }
00488       for (size_t i = 0; i < pose_list_.size(); i++) {
00489         std::string frame_id = frame_id_list_[i];
00490         tf_listener_->waitForTransform(frame_id,
00491                                        msg->header.frame_id,
00492                                        msg->header.stamp,
00493                                        ros::Duration(1.0));
00494         Eigen::Affine3f offset = pose_list_[i];
00495         if (tf_listener_->canTransform(msg->header.frame_id,
00496                                        frame_id,
00497                                        msg->header.stamp)) {
00498           tf::StampedTransform transform; // header -> frame_id_
00499           tf_listener_->lookupTransform(frame_id, msg->header.frame_id,
00500                                         msg->header.stamp, transform);
00501           Eigen::Affine3f eigen_transform;
00502           tf::transformTFToEigen(transform, eigen_transform);
00503           Vertices original_vertices = cubeVertices(dimensions_[i]);
00504           Vertices vertices;
00505           for (size_t i = 0; i < original_vertices.size(); i++) {
00506             vertices.push_back(eigen_transform.inverse()
00507                                * (offset * original_vertices[i]));
00508           }
00509           std::vector<cv::Point2d> local_points;
00510           for (size_t i = 0; i < vertices.size(); i++) {
00511             cv::Point3d p(vertices[i][0], vertices[i][1], vertices[i][2]);
00512             cv::Point2d uv = model.project3dToPixel(p);
00513             local_points.push_back(uv);
00514           }
00515           cv::Mat mask_image;
00516           computeROI(msg, local_points, mask_image);
00517           all_mask_image = all_mask_image | mask_image;
00518         }
00519       }
00520       // publish
00521       cv_bridge::CvImage mask_bridge(msg->header,
00522                                      sensor_msgs::image_encodings::MONO8,
00523                                      all_mask_image);
00524       pub_mask_.publish(mask_bridge.toImageMsg());
00525       publishBoundingBox(msg->header);
00526     }
00527     catch (std::runtime_error &e) {
00528       NODELET_ERROR("[%s] Transform error: %s", __PRETTY_FUNCTION__, e.what());
00529     } 
00530   }
00531 
00532   void AttentionClipper::updateDiagnostic(
00533     diagnostic_updater::DiagnosticStatusWrapper &stat)
00534   {
00535     if (vital_checker_->isAlive()) {
00536       stat.summary(diagnostic_msgs::DiagnosticStatus::OK,
00537                    "AttentionClipper running");
00538     }
00539     else {
00540       jsk_topic_tools::addDiagnosticErrorSummary(
00541         "AttentionClipper", vital_checker_, stat);
00542     }
00543   }
00544 
00545 }
00546 
00547 #include <pluginlib/class_list_macros.h>
00548 PLUGINLIB_EXPORT_CLASS (jsk_pcl_ros::AttentionClipper, nodelet::Nodelet);


jsk_pcl_ros
Author(s): Yohei Kakiuchi
autogenerated on Wed Sep 16 2015 04:36:47