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
00012
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
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
00032 this->pcl2_sub_ = this->public_node_handle_.subscribe("input/pcl2/segmented", 1, &IriClothesGraspingPointAlgNode::pcl2_segmented_callback, this);
00033
00034
00035
00036
00037
00038
00039
00040
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
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
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
00106 graspingPointList_msg_.pixels.push_back(pixel_msg_);
00107
00108 }
00109 }
00110
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121 }
00122
00123 void IriClothesGraspingPointAlgNode::count_labels(cv::Mat labelled_image, std::set<unsigned int>& labels){
00124
00125
00126
00127 int r,g,b;
00128 unsigned int rgb;
00129 std::set<unsigned int>::iterator it;
00130
00131
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
00150 for ( it=labels.begin(); it != labels.end(); it++ ){
00151 rgb = *it;
00152 double2rgb(r,g,b,rgb);
00153
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
00168
00169
00170
00171
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
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
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
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
00237 dilate(binary_img1_, binary_img1_, str_element);
00238 dilate(binary_img2_, binary_img2_, str_element);
00239
00240
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
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
00258 draw_contours_center(global_intersect_, src_img );
00259 }
00260
00261 void IriClothesGraspingPointAlgNode::image_processing(const cv::Mat src_img){
00262
00263
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
00281 global_cloth_center_color_ = src_img.clone();
00282 draw_clothes_centers(global_cloth_center_color_);
00283
00284
00285 cv_image.image = global_cloth_center_color_;
00286
00287 }else{
00288
00289 ROS_INFO("Intersection heat map");
00290
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
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
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);
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
00394 cv::destroyWindow(WINDOW);
00395 cv::destroyWindow(WINDOW2);
00396 }
00397
00398 void IriClothesGraspingPointAlgNode::mainNodeThread(void)
00399 {
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409 }
00410
00411
00412
00413
00414
00415
00416
00417
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
00437 int main(int argc,char *argv[])
00438 {
00439 return algorithm_base::main<IriClothesGraspingPointAlgNode>(argc, argv, "clothes_grasping_point");
00440 }