iri_clothes_grasping_point_alg_node.cpp
Go to the documentation of this file.
00001 #include "iri_clothes_grasping_point_alg_node.h"
00002 
00003 using namespace cv;
00004 namespace enc = sensor_msgs::image_encodings;
00005 
00006 static const char WINDOW[] = "Image window";
00007 static const char WINDOW2[] = "Auxiliar window";
00008 
00009 IriClothesGraspingPointAlgNode::IriClothesGraspingPointAlgNode(void) : imgtransport_(public_node_handle_) 
00010 {
00011   //init class attributes if necessary
00012   //this->loop_rate_ = 2;//in [Hz]
00013 
00014   this->image_pub_ = imgtransport_.advertise("image/out", 1);
00015   this->image_sub_ = imgtransport_.subscribe("image/in", 1, &IriClothesGraspingPointAlgNode::image_callback, this);
00016   this->image_pub1_ = imgtransport_.advertise("image/out/1", 1);
00017   this->image_pub2_ = imgtransport_.advertise("image/out/2", 1);
00018   this->image_pub3_ = imgtransport_.advertise("image/out/3", 1);
00019   this->image_pub4_ = imgtransport_.advertise("image/out/4", 1);
00020   this->image_pub5_ = imgtransport_.advertise("image/out/5", 1);
00021   this->image_pub6_ = imgtransport_.advertise("image/out/6", 1);
00022   this->image_pub_result_ = imgtransport_.advertise("image/out/result", 1);
00023 
00024   cv::namedWindow(WINDOW);
00025   cv::namedWindow(WINDOW2);
00026 
00027   // [init publishers]
00028   this->point_list_publisher_ = this->public_node_handle_.advertise<iri_clothes_grasping_point::GraspingPointList>("point_list", 5);
00029   this->poses_list_publisher_ = this->public_node_handle_.advertise<iri_clothes_grasping_point::GraspingPointList3d>("point3d_list", 5);
00030   
00031   // [init subscribers]
00032   this->pcl2_sub_ = this->public_node_handle_.subscribe("input/pcl2/segmented", 1, &IriClothesGraspingPointAlgNode::pcl2_segmented_callback, this); 
00033   
00034   // [init services]
00035   
00036   // [init clients]
00037   
00038   // [init action servers]
00039   
00040   // [init action clients]
00041 }
00042 
00043 void IriClothesGraspingPointAlgNode::binaryObjectSelection(const cv::Mat labelled_image, cv::Mat& binary_image, unsigned char Red, unsigned char Green, unsigned char Blue)
00044 {
00045 
00046   cvtColor( labelled_image, binary_image, CV_BGR2GRAY );
00047 
00048   if(labelled_image.channels() == 3){
00049 //    ROS_INFO("Image depth is 3 assuming BGR");
00050     for(int i=0;i<binary_image.size().height;i++){
00051       for(int j=0;j<binary_image.size().width;j++){
00052         if(labelled_image.at<Vec3b>(i,j)[0] == Blue && labelled_image.at<Vec3b>(i,j)[1] == Green && labelled_image.at<Vec3b>(i,j)[2] == Red){
00053           binary_image.at<uchar>(i,j) = 255;
00054         }else{
00055 //          ROS_INFO(" %d %d %d ", labelled_image.at<Vec3b>(i,j)[0],labelled_image.at<Vec3b>(i,j)[1],labelled_image.at<Vec3b>(i,j)[2]);   
00056           binary_image.at<uchar>(i,j) = 0;
00057         }
00058       } 
00059     } 
00060   }else{
00061     ROS_ERROR("Incorrect number of channels"); 
00062   }
00063   
00064 }
00065 
00066 void IriClothesGraspingPointAlgNode::draw_contours_center(cv::Mat binary_img, cv::Mat& color_output)
00067 {
00068   RNG rng(12345);
00069 
00070   cv::Mat canny_output;
00071   vector<vector<cv::Point> > contours;
00072   vector<cv::Vec4i> hierarchy;
00073 
00075   Canny( binary_img, canny_output, canny_threshold_, canny_threshold_*2, 3 );
00077   findContours( canny_output, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(0, 0) );
00078 
00080   vector<Moments> mu(contours.size() );
00081   for( int i = 0; i < contours.size(); i++ ){
00082     mu[i] = moments( contours[i], false );
00083   }
00084 
00086   vector<Point2f> mc( contours.size() );
00087   for( int i = 0; i < contours.size(); i++ ){
00088     mc[i] = Point2f( mu[i].m10/mu[i].m00 , mu[i].m01/mu[i].m00 );
00089   }
00090 
00092   color_output = Mat::zeros( canny_output.size(), CV_8UC3 );
00093   for( int i = 0; i < contours.size(); i++ ) {
00094     if(mu[i].m00 > minarea_){
00095       ROS_INFO(" * Contour[%d] - Area (M_00) = %.2f (> %.2f) - Area OpenCV: %.2f - Length: %.2f Grasp point: %.2f %.2f", i, mu[i].m00, minarea_, contourArea(contours[i]), arcLength( contours[i], true ), mc[i].x, mc[i].y );
00096        Scalar color = Scalar( rng.uniform(0, 255), rng.uniform(0,255), rng.uniform(0,255) );
00097        drawContours( color_output, contours, i, color, 2, 8, hierarchy, 0, Point() );
00098        circle( color_output, mc[i], 4, color, -1, 8, 0 );
00099 
00100         pixel_msg_.xpixel = mc[i].x; 
00101         pixel_msg_.ypixel = mc[i].y; 
00102         pixel_msg_.area = mu[i].m00; 
00103         pixel_msg_.length = arcLength( contours[i], true); 
00104 
00105         //grasping_point_list_.push_back(mc[i]);
00106         graspingPointList_msg_.pixels.push_back(pixel_msg_); 
00107       
00108      }
00109   }
00110 
00112 //  printf("\t Info: Area and Contour Length \n");
00113 //  for( int i = 0; i < contours.size(); i++ ) {
00114 //    if(mu[i].m00 > minarea_){
00115 //      ROS_INFO(" * Contour[%d] - Area (M_00) = %.2f - Area OpenCV: %.2f - Length: %.2f \n", i, mu[i].m00, contourArea(contours[i]), arcLength( contours[i], true ) );
00116 //      Scalar color = Scalar( rng.uniform(0, 255), rng.uniform(0,255), rng.uniform(0,255) );
00117 //      drawContours( drawing, contours, i, color, 2, 8, hierarchy, 0, Point() );
00118 //      circle( drawing, mc[i], 4, color, -1, 8, 0 );
00119 //    }
00120 //  }
00121 }
00122 
00123 void IriClothesGraspingPointAlgNode::count_labels(cv::Mat labelled_image, std::set<unsigned int>& labels){
00124 
00125 //TODO getparam to prevent nodes counting over and over again?
00126 
00127   int r,g,b;
00128   unsigned int rgb;
00129   std::set<unsigned int>::iterator it;
00130     
00131   //check channels
00132   if(labelled_image.channels() != 3){
00133     ROS_ERROR("Incorrect image depth");
00134     return;
00135   }
00136 
00137   labels.clear();
00138   for(int i=0;i<labelled_image.size().height;i++){
00139     for(int j=0;j<labelled_image.size().width;j++){
00140       b = labelled_image.at<Vec3b>(i,j)[0];
00141       g = labelled_image.at<Vec3b>(i,j)[1];
00142       r = labelled_image.at<Vec3b>(i,j)[2];
00143       rgb = rgb2double(r,g,b);
00144       labels.insert(rgb);
00145     }
00146   }
00147   ROS_INFO("%d labels found", labels.size());
00148 
00149   //ROS_INFO("my set contains: ");
00150   for ( it=labels.begin(); it != labels.end(); it++ ){
00151     rgb = *it;
00152     double2rgb(r,g,b,rgb);
00153     //ROS_INFO(" %d %d %d %d ",r,g,b,rgb);
00154   }
00155 }
00156 
00157 void IriClothesGraspingPointAlgNode::draw_clothes_centers(cv::Mat& src_img){
00158 
00159   cv::Mat str_element = Mat();
00160   cvtColor(src_img, global_cloth_center_, CV_BGR2GRAY );
00161 
00162   global_cloth_center_.colRange(0,2).setTo(0);
00163   global_cloth_center_.rowRange(0,2).setTo(0);
00164   global_cloth_center_.colRange(global_cloth_center_.size().width-2,global_cloth_center_.size().width).setTo(0);
00165   global_cloth_center_.rowRange(global_cloth_center_.size().height-2,global_cloth_center_.size().height).setTo(0);
00166 
00167 //      cv_image.header.stamp = ros::Time::now();
00168 //      cv_image.header.frame_id = "camera";
00169 //      cv_image.encoding = "mono8"; 
00170 //      cv_image.image = global_cloth_center_;
00171 //  image_pub5_.publish(cv_image.toImageMsg());
00172 
00173   draw_contours_center(global_cloth_center_, global_cloth_center_color_);
00174 
00175 }
00176 
00177 void IriClothesGraspingPointAlgNode::draw_intersections(cv::Mat& src_img){
00178 
00179 
00180   cv::Mat str_element = Mat();
00181   std::set<unsigned int> labels;
00182   std::set<unsigned int>::iterator it1;
00183   std::set<unsigned int>::iterator it2;
00184   int numlabels;
00185   int r1,g1,b1;
00186   int r2,g2,b2;
00187   unsigned int rgb1;
00188   unsigned int rgb2;
00189 
00190   count_labels(src_img, labels);
00191   numlabels = labels.size();
00192   
00193   for ( it1=labels.begin(); it1 != labels.end(); it1++ ){
00194     for ( it2 = it1; it2 != labels.end(); it2++ ){
00195       rgb1 = *it1;
00196       rgb2 = *it2;
00197       double2rgb(r1,g1,b1,rgb1);
00198       double2rgb(r2,g2,b2,rgb2);
00199       if(r1 == 0 && g1 == 0 && b1 == 0 
00200       || r2 == 0 && g2 == 0 && b2 == 0
00201       || rgb1 == rgb2) 
00202         continue; 
00203 
00204 //      ROS_INFO("%d %d %d %d AND %d %d %d %d ",r1,g1,b1,rgb1,r2,g2,b2,rgb2);
00205 
00206 //      r1 = 1;
00207 //      g1 = 0;
00208 //      b1 = 128;
00209 //      r2 = 128;
00210 //      g2 = 0;
00211 //      b2 = 0;
00212 
00213 //      r1 = 128;
00214 //      g1 = 127;
00215 //      b1 = 254;
00216 //      r2 = 128;
00217 //      g2 = 0;
00218 //      b2 = 0;
00219 
00220       //select first label
00221       binaryObjectSelection(src_img, binary_img1_, r1, g1, b1);
00222 
00223       cv_image.header.stamp = ros::Time::now();
00224       cv_image.header.frame_id = "camera";
00225       cv_image.encoding = "mono8"; 
00226       cv_image.image = binary_img1_;
00227       image_pub1_.publish(cv_image.toImageMsg());
00228 
00229       //select second label
00230       binaryObjectSelection(src_img, binary_img2_, r2, g2, b2);
00231 
00232       cv_image.image = binary_img2_;
00233       cv_image.header.stamp = ros::Time::now();
00234       image_pub2_.publish(cv_image.toImageMsg());
00235 
00236       //dilate
00237       dilate(binary_img1_, binary_img1_, str_element);
00238       dilate(binary_img2_, binary_img2_, str_element);
00239 
00240       //intersect
00241       bitwise_and(binary_img1_, binary_img2_, intersect_);
00242 
00243       cv_image.image = intersect_;
00244       cv_image.header.stamp = ros::Time::now();
00245       image_pub3_.publish(cv_image.toImageMsg());
00246 
00247       //sum
00248       bitwise_or(intersect_, global_intersect_, global_intersect_);
00249 
00250       cv_image.header.stamp = ros::Time::now();
00251       cv_image.image = global_intersect_;
00252       image_pub4_.publish(cv_image.toImageMsg());
00253       sleep(1);
00254     }
00255   }
00256 
00257    //compute intersections moments to obtain grasping center
00258   draw_contours_center(global_intersect_, src_img ); 
00259 }
00260 
00261 void IriClothesGraspingPointAlgNode::image_processing(const cv::Mat src_img){
00262 
00263   //check image size changes
00264   if(global_cloth_center_.empty() || src_img.size().height != global_cloth_center_.size().height
00265   || src_img.size().width != global_cloth_center_.size().width){
00266     binary_img1_ = cv::Mat(src_img.size(),CV_8UC1);
00267     binary_img2_ = cv::Mat(src_img.size(),CV_8UC1);
00268     intersect_ = cv::Mat(src_img.size(),CV_8UC1);
00269     global_intersect_ = cv::Mat(src_img.size(),CV_8UC1);
00270     global_intersect_color_ = cv::Mat(src_img.size(),CV_8UC1);
00271     global_cloth_center_ = cv::Mat(src_img.size(),CV_8UC1);
00272     global_cloth_center_color_ = cv::Mat(src_img.size(),CV_8UC3);
00273   }
00274 
00275   graspingPointList_msg_.pixels.clear();
00276 
00277   if(!intersections_){
00278 
00279       ROS_INFO("Compute and draw moments");
00280       // Moments drawing
00281       global_cloth_center_color_ = src_img.clone();
00282       draw_clothes_centers(global_cloth_center_color_);
00283       //cv::imshow(WINDOW, global_cloth_center_color_ );
00284 
00285       cv_image.image = global_cloth_center_color_; 
00286 
00287   }else{
00288 
00289       ROS_INFO("Intersection heat map");
00290       // Intersection heat_map
00291       global_intersect_color_ = src_img.clone();
00292       draw_intersections(global_intersect_color_);
00293 
00294       cv_image.image = global_intersect_color_; 
00295 
00296       ROS_INFO("Done intersection heat map");
00297       //cv::imshow(WINDOW2, global_intersect_color_);
00298   }
00299   cv_image.header.stamp = ros::Time::now();
00300   cv_image.header.frame_id = "camera";
00301   cv_image.encoding = "bgr8"; 
00302   image_pub_result_.publish(cv_image.toImageMsg());
00303 
00304   //cv::waitKey(1);
00305 
00306 }
00307 
00308 void IriClothesGraspingPointAlgNode::image_callback(const sensor_msgs::ImageConstPtr& msg) {
00309   cv::Mat src_gray;
00310   cv_bridge::CvImagePtr cv_ptr;
00311 
00312   try
00313   {
00314     cv_ptr = cv_bridge::toCvCopy(msg, enc::BGR8);
00315   }
00316   catch (cv_bridge::Exception& e)
00317   {
00318     ROS_ERROR("cv_bridge exception: %s", e.what());
00319     return;
00320   }
00321 
00322   image_processing(cv_ptr->image);
00323 
00324   image_pub_.publish(cv_ptr->toImageMsg());
00325 
00326   graspingPointList_msg_.header = msg->header;
00327   point_list_publisher_.publish(graspingPointList_msg_); 
00328 
00329 }
00330 
00331 void IriClothesGraspingPointAlgNode::image_from_pcl2(cv::Mat& rgb_image){
00332 
00333   pcl::PointCloud<pcl::PointXYZRGB>::iterator pt_iter = this->pcl_xyzrgb_.begin();
00334 
00335   rgb_image.create(this->pcl_xyzrgb_.height, this->pcl_xyzrgb_.width, CV_8UC3);
00336   for (int rr = 0; rr < (int)this->pcl_xyzrgb_.height; ++rr) {
00337     for (int cc = 0; cc < (int)this->pcl_xyzrgb_.width; ++cc, ++pt_iter) {
00338       pcl::PointXYZRGB &pt = *pt_iter;
00339       RGBValue color;
00340       color.float_value = pt.rgb;
00341       rgb_image.at<Vec3b>(rr,cc)[0] = color.Blue;
00342       rgb_image.at<Vec3b>(rr,cc)[1] = color.Green;
00343       rgb_image.at<Vec3b>(rr,cc)[2] = color.Red;
00344     }
00345   }
00346 }
00347 
00348 void IriClothesGraspingPointAlgNode::pcl2_segmented_callback(const sensor_msgs::PointCloud2ConstPtr& msg)
00349 {
00350 
00351   cv::Mat rgb_image;
00352   pcl::PointXYZRGB point;
00353   ROS_INFO("Received segmented point cloud");
00354   pcl::fromROSMsg(*msg, this->pcl_xyzrgb_);
00355   image_from_pcl2(rgb_image);
00356 
00357   cv_image.header.stamp = ros::Time::now();
00358   cv_image.header.frame_id = "camera";
00359   cv_image.encoding = "bgr8"; 
00360   cv_image.image = rgb_image;
00361   image_pub_.publish(cv_image.toImageMsg());
00362 
00363   image_processing(rgb_image); //fill graspingPointList
00364 
00365   graspingPointList3d_msg_.poses.clear();
00366   graspingPointList3d_msg_.poses.resize(graspingPointList_msg_.pixels.size());
00367   for(int i=0; i<graspingPointList_msg_.pixels.size();i++){
00368 
00369     point = pcl_xyzrgb_(graspingPointList_msg_.pixels[i].xpixel,graspingPointList_msg_.pixels[i].ypixel);
00370     graspingPointList3d_msg_.poses[i].position.x = point.x;
00371     graspingPointList3d_msg_.poses[i].position.y = point.y;
00372     graspingPointList3d_msg_.poses[i].position.z = point.z;
00373     graspingPointList3d_msg_.poses[i].orientation.x = 0;
00374     graspingPointList3d_msg_.poses[i].orientation.y = 0;
00375     graspingPointList3d_msg_.poses[i].orientation.z = 0;
00376     graspingPointList3d_msg_.poses[i].orientation.w = sqrt(2)/2;
00377 
00378   }
00379 
00380   ROS_INFO("Publishing points and image"); 
00381 
00382 
00383   graspingPointList3d_msg_.header = msg->header;
00384   poses_list_publisher_.publish(graspingPointList3d_msg_); 
00385 
00386   graspingPointList_msg_.header = msg->header;
00387   point_list_publisher_.publish(graspingPointList_msg_); 
00388 
00389 }
00390 
00391 IriClothesGraspingPointAlgNode::~IriClothesGraspingPointAlgNode(void)
00392 {
00393   // [free dynamic memory]
00394     cv::destroyWindow(WINDOW);
00395     cv::destroyWindow(WINDOW2);
00396 }
00397 
00398 void IriClothesGraspingPointAlgNode::mainNodeThread(void)
00399 {
00400   // [fill msg structures]
00401   //this->GraspingPointList_msg.data = my_var;
00402   
00403   // [fill srv structure and make request to the server]
00404   
00405   // [fill action structure and make request to the action server]
00406 
00407   // [publish messages]
00408 //  this->point_list_publisher_.publish(this->GraspingPointList_msg_);
00409 }
00410 
00411 /*  [subscriber callbacks] */
00412 
00413 /*  [service callbacks] */
00414 
00415 /*  [action callbacks] */
00416 
00417 /*  [action requests] */
00418 
00419 void IriClothesGraspingPointAlgNode::node_config_update(Config &config, uint32_t level)
00420 {
00421   this->alg_.lock();
00422   ROS_INFO("Reconfigure request : %d %d %d %d", (int)config.minarea, config.cannyth, config.cannymaxth, (int)config.intersections);
00423   
00424     minarea_ = config.minarea;
00425     canny_threshold_ = config.cannyth;
00426     canny_max_thresh_ = config.cannymaxth;
00427     intersections_ = config.intersections;
00428 
00429   this->alg_.unlock();
00430 }
00431 
00432 void IriClothesGraspingPointAlgNode::addNodeDiagnostics(void)
00433 {
00434 }
00435 
00436 /* main function */
00437 int main(int argc,char *argv[])
00438 {
00439   return algorithm_base::main<IriClothesGraspingPointAlgNode>(argc, argv, "clothes_grasping_point");
00440 }


iri_clothes_grasping_point
Author(s):
autogenerated on Fri Dec 6 2013 20:29:58