closed_door_detector_alg_node.cpp
Go to the documentation of this file.
00001 #include "closed_door_detector_alg_node.h"
00002 
00003 using namespace std;
00004 namespace enc = sensor_msgs::image_encodings;
00005 
00006 static const char WINDOW_1[] = "Closed Door Detector";
00007 
00008 geometry_msgs::PoseStamped poses;
00009 
00010 ClosedDoorDetectorAlgNode::ClosedDoorDetectorAlgNode(void) :
00011   algorithm_base::IriBaseAlgorithm<ClosedDoorDetectorAlgorithm>()
00012 {
00013   //init class attributes if necessary
00014   //this->loop_rate_ = 2;//in [Hz]
00015 
00016   // [init publishers]
00017   this->door_handle_publisher_ = this->public_node_handle_.advertise<geometry_msgs::PoseStamped>("door_handle", 1);
00018   this->closed_door_coordinates_publisher_ = this->public_node_handle_.advertise<std_msgs::Int32MultiArray>("closed_door_coordinates", 1);
00019   
00020   // [init subscribers]
00021   this->door_action_start_subscriber_ = this->public_node_handle_.subscribe("/iri_door_detector/door_detector_actions/door_action_start", 1, &ClosedDoorDetectorAlgNode::door_action_start_callback, this);
00022 
00023   // [init services]
00024   
00025   // [init clients]
00026   
00027   // [init action servers]
00028   
00029   // [init action clients]
00030 
00031   // [init algorithm variables]
00032  
00033   //variable declaration
00034   start=0;
00035   captured_depth = 0;   
00036   handle_x=0;
00037   handle_y=0;
00038   door_x=0;
00039   door_y=0;
00040   support=0;
00041 
00042   white = CV_RGB(255,255,255);
00043   black = CV_RGB(0,0,0);
00044 }
00045 
00046 ClosedDoorDetectorAlgNode::~ClosedDoorDetectorAlgNode(void)
00047 {
00048   // [free dynamic memory]
00049 }
00050 
00051 void ClosedDoorDetectorAlgNode::mainNodeThread(void)
00052 {
00053   // [fill msg structures]
00054   //this->Marker_msg_.data = my_var;
00055   //this->PointCloud2_msg_.data = my_var;
00056   //this->PoseStamped_msg_.data = my_var;
00057   
00058   // [fill srv structure and make request to the server]
00059   
00060   // [fill action structure and make request to the action server]
00061 
00062   // [publish messages]
00063   //this->door_handle_publisher_.publish(poses);
00064 }
00065 
00066 /*  [subscriber callbacks] */
00067 void ClosedDoorDetectorAlgNode::door_action_start_callback(const std_msgs::Int8::ConstPtr& action_start) 
00068 { 
00069   //ROS_INFO("ClosedDoorDetectorAlgNode::door_action_start_callback: New Message Received"); 
00070 
00071   //use appropiate mutex to shared variables if necessary 
00072   //this->alg_.lock(); 
00073   this->door_action_start_mutex_.enter(); 
00074 
00075   start=action_start->data;
00076 
00077   if (start==0)
00078   {
00079         points_subscriber_.shutdown();
00080         image_color_subscriber_.shutdown();
00081         //cvDestroyWindow("Closed Door Detector");
00082   }
00083   if (start==1)
00084   {
00085         this->image_color_subscriber_ = this->public_node_handle_.subscribe("/camera/rgb/image_color", 1, &ClosedDoorDetectorAlgNode::image_color_callback, this);
00086         this->points_subscriber_ = this->public_node_handle_.subscribe("/camera/depth/points", 1, &ClosedDoorDetectorAlgNode::points_callback, this);
00087   }     
00088 
00089   //unlock previously blocked shared variables 
00090   //this->alg_.unlock(); 
00091   this->door_action_start_mutex_.exit(); 
00092 }
00093 
00094 void ClosedDoorDetectorAlgNode::points_callback(const sensor_msgs::PointCloud2::ConstPtr& points) 
00095 { 
00096   //ROS_INFO("ClosedDoorDetectorAlgNode::image_depth_callback: New Message Received"); 
00097 
00098   //use appropiate mutex to shared variables if necessary 
00099   //this->alg_.lock(); 
00100   this->points_mutex_.enter();          
00101 
00102   if(captured_depth==0)
00103   {
00104         pcl::fromROSMsg (*points, cloud);
00105   }
00106 
00107   captured_depth = 1;  
00108 
00109   //unlock previously blocked shared variables 
00110   //this->alg_.unlock(); 
00111   this->points_mutex_.exit(); 
00112 }
00113 
00114 void ClosedDoorDetectorAlgNode::image_color_callback(const sensor_msgs::Image::ConstPtr& image_color) 
00115 { 
00116   //ROS_INFO("ClosedDoorDetectorAlgNode::image_color_callback: New Message Received"); 
00117 
00118   //use appropiate mutex to shared variables if necessary 
00119   //this->alg_.lock(); 
00120   this->image_color_mutex_.enter(); 
00121 
00122   if(captured_depth==1)
00123   {
00124         try
00125         {
00126                 canny = cv_bridge::toCvCopy(image_color, enc::MONO8);                                   
00127                 blobs = cv_bridge::toCvCopy(image_color, enc::MONO8);
00128                 original = cv_bridge::toCvCopy(image_color, enc::BGR8);
00129                 gradient = cv_bridge::toCvCopy(image_color, enc::BGR8);
00130         }
00131         catch (cv_bridge::Exception& e)
00132         {
00133                 //if there is an error during conversion, display it
00134                 ROS_ERROR("Error while capturing color image: %s", e.what());
00135                 return;
00136         }  
00137         //ROS_INFO("ClosedDoorDetectorAlgNode::image_color_callback: New Message Received");    
00138 
00139         //Image denoising
00140         cv::medianBlur(gradient->image, gradient->image, 3);    
00141         cv::GaussianBlur(gradient->image, gradient->image, cv::Size(5,5), 0, 0);
00142         //cv::boxFilter(gradient->image, gradient->image, -1, cv::Size(7,7));
00143         //cv::bilateralFilter(gradient->image, gradient->image, 5, 10.0, 10.0);
00144         //cv::pyrMeanShiftFiltering(gradient->image, gradient->image, 3.0, 150.0, 0);
00145 
00146         //Get image gradient
00147         cv::morphologyEx(gradient->image, gradient->image, cv::MORPH_GRADIENT, (getStructuringElement(cv::MORPH_RECT, cv::Size(3,3), cv::Point(-1, -1))), cv::Point(-1,-1), 1); 
00148 
00149         //Get image borders
00150         cv::cvtColor(gradient->image, canny->image, CV_BGR2GRAY);
00151         cv::medianBlur(canny->image, canny->image, 3);
00152         cv::GaussianBlur( canny->image, canny->image, cv::Size(5,5), 0, 0);
00153         cv::Canny(canny->image, canny->image, segment_fidelity, segment_size, 3, true);
00154  
00155         //Perform Watershed segmentation
00156         compCount = 0;
00157         vector<vector<cv::Point> > contours;
00158         vector<cv::Vec4i> hierarchy;
00159 
00160         findContours(canny->image, contours, hierarchy, CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE);
00161 
00162         cv::Mat markers(canny->image.size(), CV_32S);
00163         markers = cv::Scalar::all(0);
00164 
00165         if( !contours.empty() )
00166         {
00167                 idx = 0;
00168                 for( ; idx >= 0; idx = hierarchy[idx][0], compCount++ )
00169                         drawContours(markers, contours, idx, cv::Scalar::all(compCount+1), -1, 8, hierarchy, INT_MAX);
00170 
00171                 colorTab.clear();
00172                 if( compCount != 0 )
00173                 {
00174                         for(int i = 0; i < compCount; i++ )
00175                         {
00176                                 int b = rng.uniform(0, 255);
00177                                 int g = rng.uniform(0, 255);
00178                                 int r = rng.uniform(0, 255);
00179 
00180                                 colorTab.push_back(cv::Vec3b((uchar)b, (uchar)g, (uchar)r));
00181                         }
00182                 }
00183         }       
00184         
00185         //Use gradient image as input for the watershed segmentation
00186         watershed( gradient->image, markers );
00187 
00188         cv::Mat wshed(markers.size(), CV_8UC3);
00189         wshed = cv::Scalar::all(0);
00190 
00191         // paint the watershed image
00192         for(int i = 0; i < markers.rows; i++ )
00193         {
00194                 for(int j = 0; j < markers.cols; j++ )
00195                 {
00196                     idx = markers.at<int>(i,j);
00197                     if( idx == -1 )
00198                     {
00199                         wshed.at<cv::Vec3b>(i,j) = cv::Vec3b(255,255,255);
00200                     }
00201                     else if( idx <= 0 || idx > compCount )
00202                         wshed.at<cv::Vec3b>(i,j) = cv::Vec3b(0,0,0);
00203                     else
00204                     {
00205                         wshed.at<cv::Vec3b>(i,j) = colorTab[idx - 1];
00206                     }
00207                 }
00208         }
00209         
00210         cv::GaussianBlur( blobs->image, blobs->image,cv::Size(7,7), 0, 0);
00211 
00212         //Prepare blobs extraction
00213         cv::Sobel(blobs->image, blobs->image, -1, 0, 1, 3, 1, 0); 
00214         cv::Canny(blobs->image, blobs->image, allowed_blobs, allowed_blobs, 3, true);
00215         cv::dilate(blobs->image, blobs->image, (getStructuringElement(cv::MORPH_ELLIPSE, cv::Size(3,3), cv::Point(-1, -1))), cv::Point(-1, -1), 2);
00216 
00217         /*for(int i = 1; i < blobs->image.rows; i++)
00218         {
00219                 for(int j = 1; j < blobs->image.cols; j++ )
00220                 {
00221                         if (wshed.at<cv::Vec3b>(i,j) == cv::Vec3b(255,255,255))
00222                                 blobs->image.data[i*blobs->image.cols+j]=0;
00223                 }       
00224         }*/
00225         
00226         cv::erode(blobs->image, blobs->image, (getStructuringElement(cv::MORPH_RECT, cv::Size(3,3), cv::Point(-1, -1))), cv::Point(-1, -1), 1);
00227         cv::dilate(blobs->image, blobs->image, (getStructuringElement(cv::MORPH_RECT, cv::Size(5,5), cv::Point(-1, -1))), cv::Point(-1, -1), 3);
00228         cv::erode(blobs->image, blobs->image, (getStructuringElement(cv::MORPH_ELLIPSE, cv::Size(5,5), cv::Point(-1, -1))), cv::Point(-1, -1), 3);
00229 
00230         cv::Mat blob_mat;
00231         blob_mat = cv::Mat::zeros(blobs->image.rows, blobs->image.cols, CV_8UC3);
00232         
00233         //Convert images to match cvBlob format
00234         IplImage ipl_1 = blobs->image;
00235 
00236         //Declare cvBlob output variables
00237         IplImage *labelImg = cvCreateImage(cv::Size(blobs->image.cols,blobs->image.rows), IPL_DEPTH_LABEL, 1);
00238         IplImage *blobsDst = cvCreateImage(cv::Size(blobs->image.cols,blobs->image.rows), IPL_DEPTH_8U, 3);
00239         cvZero(blobsDst);
00240         cvb::CvBlobs CVblobs;
00241 
00242         //Label Blobs and render 
00243         cvb::cvLabel(&ipl_1, labelImg, CVblobs);
00244         //cvFilterByArea(blobs, 1000, 50000);
00245         cvb::cvRenderBlobs(labelImg, CVblobs, blobsDst, blobsDst, CV_BLOB_RENDER_COLOR);
00246 
00247         //Convert back to general format
00248         blob_mat= cv::Mat(blobsDst,true);
00249                 
00250         cvReleaseImage(&labelImg);
00251         cvReleaseImage(&blobsDst);
00252         //ROS_ERROR("blobs size: %i, pixels: %i", blobs.size(), result);        
00253 
00254         vec_up.clear();
00255         vec_down.clear();
00256         vec_left.clear();
00257         vec_right.clear();
00258         ss_door_centroid.clear();
00259         ss_handle.clear();
00260         ss_handle_x.clear();
00261         ss_handle_y.clear();
00262         ss_handle_z.clear();
00263         ss_c1.clear();
00264         ss_c2.clear();
00265         ss_c3.clear();
00266         ss_c4.clear();
00267 
00268         step_x=canny->image.cols/(24);
00269         step_y=canny->image.rows/(18);
00270 
00271 
00272         CvPoint p_right, p_left;
00273         // watershed horizontal scan
00274         for(int i = 1; i < wshed.rows; i=i+step_y)
00275         {
00276                 point=0;
00277                 original_color = wshed.at<cv::Vec3b>(i,1);
00278                 color = wshed.at<cv::Vec3b>(i,1);
00279                 p_left = cvPoint(0,i);
00280                 p_right = cvPoint(0,0);
00281 
00282                 for(int j = 1; j < wshed.cols; j++ )
00283                 {
00284                         //Seed condition to allow skipping NaN depth readings
00285                         min_dst_h=1;
00286                         max_dst_h=0;
00287                         if( wshed.at<cv::Vec3b>(i,j) != color && (wshed.at<cv::Vec3b>(i,j) != cv::Vec3b(255,255,255) || j==wshed.cols-1))
00288                         {
00289                                 p_right=cvPoint(j,i);   
00290                                 if(j<wshed.cols-1)
00291                                 {       
00292                                         repeated_color=0;
00293                                         for(int n=j; n<wshed.cols; n++)
00294                                         {
00295                                                 if(wshed.at<cv::Vec3b>(i,n) == color && wshed.at<cv::Vec3b>(i,n) != cv::Vec3b(255,255,255))
00296                                                 {
00297                                                         repeated_color=1;
00298                                                         p_right = cvPoint(n,i);
00299                                                 }
00300                                         }
00301                                 }
00302                                 point3D = cloud.at((int)((p_left.x+p_right.x)/2),i);
00303                                 sensor_range=(!std::isnan(point3D.z) && point3D.z>0.0 && point3D.z<5.0);
00304                                 if(sensor_range)
00305                                 {
00306                                         min_dst_h=(min_door_width/point3D.z);
00307                                         max_dst_h=(max_door_width/point3D.z);
00308                                 
00309                                         if(p_left.x<=10 || p_right.x>=wshed.cols-10)
00310                                                 min_dst_h=min_dst_h/2;
00311                                         if(abs(p_left.x-p_right.x)>min_dst_h && abs(p_left.x-p_right.x)<max_dst_h)
00312                                         {
00313                                                 vec_left.push_back(p_left);
00314                                                 vec_right.push_back(p_right);
00315                                                 if(SVP)
00316                                                 {cv::line(original->image, p_left,p_left, CV_RGB(0,0,0), 10, 8, 0);
00317                                                 cv::line(original->image, p_right, p_right, CV_RGB(255,255,255), 10, 8, 0);}
00318                                                 point=1;
00319                                         }
00320                                 }
00321                                 p_left = cvPoint(j,i);                                  
00322                         }
00323                         if(j==wshed.cols-3 && point==0 && wshed.at<cv::Vec3b>(i,j) == original_color)
00324                         {
00325                                 vec_left.push_back(cvPoint(0,i));
00326                                 vec_right.push_back(cvPoint(j+2,i));
00327                                 if(SVP)
00328                                 {cv::line(original->image, cvPoint(0,i) , cvPoint(0,i), CV_RGB(0,0,0), 10, 8, 0);
00329                                 cv::line(original->image, cvPoint(j,i), cvPoint(j,i), CV_RGB(255,255,255), 10, 8, 0);}
00330                         }
00331                         if(wshed.at<cv::Vec3b>(i,j) != cv::Vec3b(255,255,255))
00332                                 color = wshed.at<cv::Vec3b>(i,j);
00333                 }
00334         }
00335 
00336         CvPoint p_up, p_down;
00337         // watershed vertical scan
00338         for(int j = 1; j < wshed.cols; j=j+step_x)
00339         {
00340         
00341                 point=0;
00342                 original_color=wshed.at<cv::Vec3b>(1,j);
00343                 color = wshed.at<cv::Vec3b>(1,j);
00344                 p_up = cvPoint(j,0);
00345                 p_down = cvPoint(0,0);
00346 
00347                 for(int i = 1; i < wshed.rows; i++ )
00348                 {
00349                         if( wshed.at<cv::Vec3b>(i,j) != color && (wshed.at<cv::Vec3b>(i,j) != cv::Vec3b(255,255,255) || i==wshed.rows-1))
00350                         {
00351                                 //Seed condition to allow skipping NaN depth readings
00352                                 min_dst_v=1;
00353                                 max_dst_v=0;
00354                                 p_down=cvPoint(j,i);
00355                                 if(i<wshed.rows-1)
00356                                 {       
00357                                         repeated_color=0;
00358                                         for(int n=i; n<wshed.rows; n++)
00359                                         {
00360                                                 if(wshed.at<cv::Vec3b>(n,j) == color && wshed.at<cv::Vec3b>(n,j) != cv::Vec3b(255,255,255))
00361                                                         repeated_color=1;
00362                                                 if(wshed.at<cv::Vec3b>(n,j) != color && wshed.at<cv::Vec3b>(n,j) != cv::Vec3b(255,255,255) && repeated_color==1)
00363                                                 {
00364                                                         p_down = cvPoint(j,n);
00365                                                         repeated_color=0;
00366                                                         i=n;
00367                                                 }
00368                                                 if(n==wshed.rows-3 && repeated_color==1)
00369                                                 {
00370                                                         p_down = cvPoint(j,n+2);
00371                                                         repeated_color=0;
00372                                                         i=n+2;
00373                                                 }
00374                                                 if(n==wshed.rows-3 && point==0 && wshed.at<cv::Vec3b>(n,j) == original_color)
00375                                                 {
00376                                                         vec_up.push_back(cvPoint(j,0));
00377                                                         vec_down.push_back(cvPoint(j,n+2));
00378                                                         if(SVP)
00379                                                         {cv::line(original->image, cvPoint(j,0), cvPoint(j,0), CV_RGB(0,0,0), 10, 8, 0);
00380                                                         cv::line(original->image, cvPoint(j,n), cvPoint(j,n), CV_RGB(255,255,255), 10, 8, 0);}
00381                                                 }
00382                                                 
00383                                         }
00384                                 }
00385                                 
00386                                 point3D = cloud.at(j,(int)((p_up.y+p_down.y)/2));
00387 
00388                                 sensor_range=(!std::isnan(point3D.z) && point3D.z>0 && point3D.z<5.0);
00389                                 if(sensor_range)
00390                                 {
00391                                         min_dst_v=(min_door_height/point3D.z);
00392                                         max_dst_v=(max_door_height/point3D.z);
00393         
00394                                         if(p_up.y<=10 || p_down.y>=wshed.rows-10)
00395                                                 min_dst_v=min_dst_v/2;
00396                                         if(abs(p_up.y-p_down.y)>min_dst_v && abs(p_up.y-p_down.y)<max_dst_v && sensor_range)
00397                                         {
00398                                                 vec_up.push_back(p_up);
00399                                                 vec_down.push_back(p_down);
00400                                                 if(SVP)
00401                                                 {cv::line(original->image, p_up,p_up, CV_RGB(0,0,0), 10, 8, 0);
00402                                                 cv::line(original->image, p_down, p_down, CV_RGB(255,255,255), 10, 8, 0);}
00403                                                 point=1;
00404                                         }
00405                                 }
00406                                 p_up = cvPoint(j,i);                            
00407                         }
00408                         if(i==wshed.rows-3 && point==0 && wshed.at<cv::Vec3b>(i,j) == original_color)
00409                         {
00410                                 vec_up.push_back(cvPoint(j,0));
00411                                 vec_down.push_back(cvPoint(j,i+2));
00412                                 if(SVP)
00413                                 {cv::line(original->image, cvPoint(j,0), cvPoint(j,0), CV_RGB(0,0,0), 10, 8, 0);
00414                                 cv::line(original->image, cvPoint(j,i), cvPoint(j,i), CV_RGB(255,255,255), 10, 8, 0);}
00415                         }
00416                         if(wshed.at<cv::Vec3b>(i,j) != cv::Vec3b(255,255,255))
00417                                 color = wshed.at<cv::Vec3b>(i,j);
00418                 }
00419         }               
00420 
00421         frames_size=min(min(vec_left.size(),vec_right.size()),min(vec_up.size(),vec_down.size()));
00422 
00423         if(frames_size>1)
00424         {       
00425                 for(size_t j=0;j<vec_up.size()-1;j++)
00426                 {       
00427                         for(size_t i=0;i<vec_left.size()-1;i++)
00428                         {       
00429                                 f_c1=0;
00430                                 f_c2=0;
00431                                 f_c3=0;
00432                                 f_c4=0;
00433                                 
00434                                 //look for the next left marker which is nearest to left marker i
00435                                 check=0;
00436                                 offset_l=0;
00437                                 dst=canny->image.cols*2;
00438                                 while(check==0)
00439                                 {
00440                                         while(vec_left.at(i+1+offset_l).y==vec_left.at(i).y)
00441                                         {
00442                                                 offset_l++;
00443                                                 if(i+1+offset_l>vec_left.size()-2)
00444                                                 {
00445                                                         offset_l--;
00446                                                         break;
00447                                                 }
00448                                         }
00449                                         if(i+1+offset_l>vec_left.size()-2)
00450                                         {
00451                                                 offset_l--;
00452                                                 break;
00453                                         }
00454                                         dst=min(dst,abs(vec_left.at(i+1+offset_l).x-vec_left.at(i).x));
00455                                         if(i+2+offset_l<vec_left.size()-1)
00456                                         {               
00457                                                 if(vec_left.at(i+2+offset_l).y>vec_left.at(i+1+offset_l).y)
00458                                                 {
00459                                                         check=1;
00460                                                 }               
00461                                         }
00462                                         if(check==0)
00463                                                 offset_l++;
00464                                 }
00465                                 if(offset_l>0)
00466                                 {
00467                                         for(int k=0; k<=offset_l; k++)
00468                                         {
00469                                                 if(abs(vec_left.at(i+1+k).x-vec_left.at(i).x)==dst)
00470                                                         offset_l=k;
00471                                         }
00472                                 }
00473                                         
00474                                 //look for the next up marker which is nearest to up marker i
00475                                 check=0;
00476                                 offset_u=0;
00477                                 dst=canny->image.cols*2;
00478                                 while(check==0)
00479                                 {
00480                                         while(vec_up.at(j+1+offset_u).x==vec_up.at(j).x)
00481                                         {
00482                                                 offset_u++;
00483                                                 if(j+1+offset_u>vec_up.size()-2)
00484                                                 {
00485                                                         offset_u--;
00486                                                         break;
00487                                                 }
00488                                         }
00489                                         if(j+1+offset_u>vec_up.size()-2)
00490                                         {
00491                                                 offset_u--;
00492                                                 break;
00493                                         }
00494                                         dst=min(dst,abs(vec_up.at(j+1+offset_u).y-vec_up.at(j).y));
00495                                         if(j+2+offset_u<vec_up.size()-1)
00496                                         {               
00497                                                 if(vec_up.at(j+2+offset_u).x>vec_up.at(j+1+offset_u).x)
00498                                                 {
00499                                                         check=1;
00500                                                 }
00501                                         }
00502                                         if(check==0)
00503                                                 offset_u++;             
00504                                 }
00505                                 if(offset_u>0)
00506                                 {
00507                                         for(int k=0; k<=offset_u; k++)
00508                                         {
00509                                                 if(abs(vec_up.at(j+1+k).y-vec_up.at(j).y)==dst)
00510                                                         offset_u=k;
00511                                         }
00512                                 }
00513 
00514                                 //look for the next right marker which is nearest to right marker i
00515                                 check=0;
00516                                 offset_r=0;
00517                                 dst=canny->image.cols*2;
00518                                 while(check==0)
00519                                 {
00520                                         while(vec_right.at(i+1+offset_r).y==vec_right.at(i).y)
00521                                         {
00522                                                 offset_r++;
00523                                                 if(i+1+offset_r>vec_right.size()-2)
00524                                                 {
00525                                                         offset_r--;
00526                                                         break;
00527                                                 }
00528                                         }
00529                                         if(i+1+offset_r>vec_right.size()-2)
00530                                         {
00531                                                 offset_r--;
00532                                                 break;
00533                                         }
00534                                         dst=min(dst,abs(vec_right.at(i+1+offset_r).x-vec_right.at(i).x));
00535                                         if(i+2+offset_r<vec_right.size()-1)
00536                                         {               
00537                                                 if(vec_right.at(i+2+offset_r).y>vec_right.at(i+1+offset_r).y)
00538                                                 {
00539                                                         check=1;
00540                                                 }               
00541                                         }
00542                                         if(check==0)
00543                                                 offset_r++;
00544                                 }
00545                                 if(offset_r>0)
00546                                 {
00547                                         for(int k=0; k<=offset_r; k++)
00548                                         {
00549                                                 if(abs(vec_right.at(i+1+k).x-vec_right.at(i).x)==dst)
00550                                                         offset_r=k;
00551                                         }
00552                                 }
00553 
00554                                 //look for the next left marker which is nearest to down marker i                                       
00555                                 check=0;
00556                                 offset_d=0;
00557                                 dst=canny->image.cols*2;
00558                                 while(check==0)
00559                                 {
00560                                         while(vec_down.at(j+1+offset_d).x==vec_down.at(j).x)
00561                                         {
00562                                                 offset_d++;
00563                                                 if(j+1+offset_d>vec_down.size()-2)
00564                                                 {
00565                                                         offset_d--;
00566                                                         break;
00567                                                 }
00568                                         }
00569                                         if(j+1+offset_d>vec_down.size()-2)
00570                                         {
00571                                                 offset_d--;
00572                                                 break;
00573                                         }
00574                                         dst=min(dst,abs(vec_down.at(j+1+offset_d).y-vec_down.at(j).y));
00575                                         if(j+2+offset_d<vec_down.size()-1)
00576                                         {               
00577                                                 if(vec_down.at(j+2+offset_d).x>vec_down.at(j+1+offset_d).x)
00578                                                 {
00579                                                         check=1;
00580                                                 }
00581                                         }
00582                                         if(check==0)
00583                                                 offset_d++;             
00584                                 }
00585                                 if(offset_d>0)
00586                                 {
00587                                         for(int k=0; k<=offset_d; k++)
00588                                         {
00589                                                 if(abs(vec_down.at(j+1+k).y-vec_down.at(j).y)==dst)
00590                                                         offset_d=k;
00591                                         }
00592                                 }
00593 
00594                                 if(vec_up.at(j).x>=vec_left.at(i).x+step_x && vec_up.at(j).y+step_y<=vec_left.at(i).y)
00595                                 {
00596                                         //get c1
00597                                         dy=(vec_left.at(i+1+offset_l).y-vec_left.at(i).y);
00598                                         dx=(vec_left.at(i+1+offset_l).x-vec_left.at(i).x);
00599                                         m1=dy/(dx+0.0001);
00600                                         b1=(vec_left.at(i+1+offset_l).y-m1*vec_left.at(i+1+offset_l).x);
00601 
00602                                         dy=(vec_up.at(j+1+offset_u).y-vec_up.at(j).y);
00603                                         dx=(vec_up.at(j+1+offset_u).x-vec_up.at(j).x);
00604                                         m2=dy/(dx+0.0001);
00605                                         b2=(vec_up.at(j+1+offset_u).y-m2*vec_up.at(j+1+offset_u).x);
00606 
00607                                         x = (b2 - b1)/(m1 - m2 + 0.0001);
00608                                         y = (m1*x)+b1;
00609 
00610                                         if(x<0)
00611                                                 x=0;
00612                                         if(y<0)
00613                                                 y=0;
00614                                         if(x>=canny->image.cols)        
00615                                                 x=canny->image.cols-1;
00616                                         if(y>=canny->image.rows)        
00617                                                 y=canny->image.rows-1;
00618 
00619                                         f_c1=1;
00620                                         c1= cvPoint((int)x,(int)y);
00621                                         //if(SVP)
00622                                                 //cv::line(original->image, cvPoint(vec_up.at(j).x,vec_up.at(j).y), cvPoint(vec_up.at(j+1+offset_u).x,vec_up.at(j+1+offset_u).y), CV_RGB(255,255,255), 2, 8, 0);        
00623                                 }
00624 
00625                                 if(vec_up.at(j+1+offset_u).x+step_x<=vec_right.at(i).x && vec_up.at(j+1+offset_u).y+step_y<=vec_right.at(i).y)
00626                                 {
00627                                         //get c2
00628                                         dy=(vec_right.at(i+1+offset_r).y-vec_right.at(i).y);
00629                                         dx=(vec_right.at(i+1+offset_r).x-vec_right.at(i).x);
00630                                         m1=dy/(dx+0.0001);
00631                                         b1=(vec_right.at(i+1+offset_r).y-m1*vec_right.at(i+1+offset_r).x);
00632 
00633                                         dy=(vec_up.at(j+1+offset_u).y-vec_up.at(j).y);
00634                                         dx=(vec_up.at(j+1+offset_u).x-vec_up.at(j).x);
00635                                         m2=dy/(dx+0.0001);
00636                                         b2=(vec_up.at(j+1+offset_u).y-m2*vec_up.at(j+1+offset_u).x);
00637 
00638                                         x = (b2 - b1)/(m1 - m2 + 0.0001);
00639                                         y = (m1*x)+b1;
00640         
00641                                         if(x<0)
00642                                                 x=0;
00643                                         if(y<0)
00644                                                 y=0;
00645                                         if(x>=canny->image.cols)        
00646                                                 x=canny->image.cols-1;
00647                                         if(y>=canny->image.rows)        
00648                                                 y=canny->image.rows-1;
00649 
00650                                         f_c2=1;
00651                                         c2= cvPoint((int)x,(int)y);
00652                                         //if(SVP)
00653                                                 //cv::line(original->image, cvPoint(vec_left.at(i).x,vec_left.at(i).y), cvPoint(vec_left.at(i+1+offset_l).x,vec_left.at(i+1+offset_l).y), CV_RGB(255,255,255), 2, 8, 0);        
00654                                 }                               
00655 
00656                                 if(vec_down.at(j+1+offset_d).x+step_x<=vec_right.at(i+1+offset_r).x && vec_down.at(j+1+offset_d).y>=vec_right.at(i+1+offset_r).y+step_y)
00657                                 {
00658                                         //get c3
00659                                         dy=(vec_right.at(i+1+offset_r).y-vec_right.at(i).y);
00660                                         dx=(vec_right.at(i+1+offset_r).x-vec_right.at(i).x);
00661                                         m1=dy/(dx+0.0001);
00662                                         b1=(vec_right.at(i+1+offset_r).y-m1*vec_right.at(i+1+offset_r).x);
00663 
00664                                         dy=(vec_down.at(j+1+offset_d).y-vec_down.at(j).y);
00665                                         dx=(vec_down.at(j+1+offset_d).x-vec_down.at(j).x);
00666                                         m2=dy/(dx+0.0001);
00667                                         b2=(vec_down.at(j+1+offset_d).y-m2*vec_down.at(j+1+offset_d).x);
00668 
00669                                         x = (b2 - b1)/(m1 - m2 + 0.0001);
00670                                         y = (m1*x)+b1;
00671 
00672                                         if(x<0)
00673                                                 x=0;
00674                                         if(y<0)
00675                                                 y=0;
00676                                         if(x>=canny->image.cols)        
00677                                                 x=canny->image.cols-1;
00678                                         if(y>=canny->image.rows)        
00679                                                 y=canny->image.rows-1;
00680 
00681                                         f_c3=1;
00682                                         c3= cvPoint((int)x,(int)y);
00683                                         //if(SVP)
00684                                                 //cv::line(original->image, cvPoint(vec_down.at(j).x,vec_down.at(j).y), cvPoint(vec_down.at(j+1+offset_d).x,vec_down.at(j+1+offset_d).y), CV_RGB(255,255,255), 2, 8, 0);                
00685                                 }
00686                                 
00687                                 if(vec_down.at(j).x>=vec_left.at(i+1+offset_l).x+step_x && vec_down.at(j).y>=vec_left.at(i+1+offset_l).y+step_y)
00688                                 {
00689                                         //get c4
00690                                         dy=(vec_left.at(i+1+offset_l).y-vec_left.at(i).y);
00691                                         dx=(vec_left.at(i+1+offset_l).x-vec_left.at(i).x);
00692                                         m1=dy/(dx+0.0001);
00693                                         b1=(vec_left.at(i+1+offset_l).y-m1*vec_left.at(i+1+offset_l).x);
00694 
00695                                         dy=(vec_down.at(j+1+offset_d).y-vec_down.at(j).y);
00696                                         dx=(vec_down.at(j+1+offset_d).x-vec_down.at(j).x);
00697                                         m2=dy/(dx+0.0001);
00698                                         b2=(vec_down.at(j+1+offset_d).y-m2*vec_down.at(j+1+offset_d).x);
00699 
00700                                         x = (b2 - b1)/(m1 - m2 + 0.0001);
00701                                         y = (m1*x)+b1;
00702 
00703                                         if(x<0)
00704                                                 x=0;
00705                                         if(y<0)
00706                                                 y=0;
00707                                         if(x>=canny->image.cols)        
00708                                                 x=canny->image.cols-1;
00709                                         if(y>=canny->image.rows)        
00710                                                 y=canny->image.rows-1;
00711 
00712                                         c4= cvPoint((int)x,(int)y);
00713                                         f_c4=1;
00714                                         //if(SVP)
00715                                                 //cv::line(original->image, cvPoint(vec_right.at(i).x,vec_right.at(i).y), cvPoint(vec_right.at(i+1+offset_r).x,vec_right.at(i+1+offset_r).y), CV_RGB(255,255,255), 2, 8, 0);    
00716                                 }
00717                                 
00718                                 if(f_c1*f_c2*f_c3*f_c4>0)
00719                                 {
00720                                         //distance between corners
00721                                         dst_up=sqrt((c2.x-c1.x)*(c2.x-c1.x)+(c2.y-c1.y)*(c2.y-c1.y));
00722                                         dst_right=sqrt((c3.x-c2.x)*(c3.x-c2.x)+(c3.y-c2.y)*(c3.y-c2.y));
00723                                         dst_down=sqrt((c4.x-c3.x)*(c4.x-c3.x)+(c4.y-c3.y)*(c4.y-c3.y));
00724                                         dst_left=sqrt((c4.x-c1.x)*(c4.x-c1.x)+(c4.y-c1.y)*(c4.y-c1.y));
00725 
00726                                         //compute angles between line pairs
00727                                         theta1 = AngleBetweenLines (c1, c2, c2, c3);
00728                                         theta2 = AngleBetweenLines (c2, c3, c4, c3);
00729                                         theta3 = AngleBetweenLines (c4, c3, c1, c4);
00730                                         theta4 = AngleBetweenLines (c1, c2, c1, c4);
00731                 
00732                                         theta=min(min(theta1,theta2),min(theta3,theta4));
00733                                         dst_h=(dst_down+dst_up)/2;
00734                                         dst_v=(dst_left+dst_right)/2;
00735 
00736                                         cx_min=min(min(c1.x,c2.x),min(c3.x,c4.x));
00737                                         cx_max=max(max(c1.x,c2.x),max(c3.x,c4.x));
00738                                         cy_min=min(min(c1.y,c2.y),min(c3.y,c4.y));
00739                                         cy_max=max(max(c1.y,c2.y),max(c3.y,c4.y));
00740 
00741                                         if (cx_min<0)                                           
00742                                                 cx_min=0;                       if (cx_max<4)
00743                                                                                         cx_max=4;
00744                                         if (cy_min<0)                                           
00745                                                 cy_min=0;                       if (cy_max<4)
00746                                                                                         cy_max=4;
00747                                         if (cx_min>blobs->image.cols-5)                                         
00748                                                 cx_min=blobs->image.cols-5;     if (cx_max>blobs->image.cols-1)
00749                                                                                         cx_max=blobs->image.cols-1;
00750                                         if (cy_min>blobs->image.rows-5)                                         
00751                                                 cy_min=blobs->image.rows-5;     if (cy_max>blobs->image.rows-1)
00752                                                                                         cy_max=blobs->image.rows-1;
00753                                         roi_x=abs(cx_max-cx_min);
00754                                         roi_y=abs(cy_max-cy_min);
00755                                         door_x=(int)(cx_min+cx_max)/2;
00756                                         door_y=(int)(cy_min+cy_max)/2;
00757 
00758                                         if(door_x<0)
00759                                                 door_x=0;
00760                                         if(door_y<0)
00761                                                 door_y=0;
00762                                         if(door_x>=original->image.cols)        
00763                                                 door_x=original->image.cols-1;
00764                                         if(door_y>=original->image.rows)        
00765                                                 door_y=original->image.rows-1;
00766                                         
00767                                         point3D = cloud.at(door_x,door_y);
00768                                         meters = point3D.z;
00769 
00770                                         if(std::isnan(meters) || meters < 0.0 || meters > 5.0)
00771                                         {
00772                                                 meters=0;
00773                                                 idx=0;
00774                                                 if(roi_x>5 && roi_y>5)
00775                                                 {
00776                                                         for(int k = cx_min; k < cx_max; k++)
00777                                                         {
00778                                                                 point3D = cloud.at(k,door_y);
00779                                                                 if(!std::isnan(point3D.z) && point3D.z>0.0 && point3D.z<5.0)
00780                                                                 {
00781                                                                         meters=meters+point3D.z;
00782                                                                         idx++;
00783                                                                 }
00784                                                         }
00785                                                         for(int k = cy_min; k < cy_max; k++)
00786                                                         {
00787                                                                 point3D = cloud.at(door_x,k);                                                   
00788                                                                 if(!std::isnan(point3D.z) && point3D.z>0.0 && point3D.z<5.0)
00789                                                                 {
00790                                                                         meters=meters+point3D.z;
00791                                                                         idx++;
00792                                                                 }
00793                                                         }
00794                                                 }
00795 
00796                                                 if(idx==0)
00797                                                         idx=1;
00798                                         
00799                                                 meters=meters/idx;
00800                                         }
00801                                         
00802                                         //Check for sensor saturation
00803                                         sensor_range = meters>0.0 && !std::isnan(meters) && meters<5.0;
00804 
00805                                         if(!Range_filter)
00806                                                 sensor_range =1;
00807                         
00808                                         if(sensor_range)
00809                                         {
00810                                                 min_dst_h=(min_door_width/meters);
00811                                                 max_dst_h=(max_door_width/meters);
00812                                                 min_dst_v=(min_door_height/meters);
00813                                                 max_dst_v=(max_door_height/meters);
00814 
00815                                                 r=roi_x/(roi_y+0.0001);
00816 
00817                                                 if(cx_min <= 10 || cx_max >= blobs->image.cols-10)
00818                                                 {
00819                                                         min_dst_h=min_dst_h/2;
00820                                                         aspect = (r>=0.4 && r<=0.8);    
00821                                                 }
00822                                                 if(cy_min <= 10 || cy_max >= blobs->image.rows-10)
00823                                                 {
00824                                                         min_dst_v=min_dst_v/3;
00825                                                         aspect = (r>=0.4 && r<=1.5);
00826                                                 }
00827                                                 if(cx_min >= 10 && cx_max <= blobs->image.cols-10 && cy_min >= 10 && cy_max <= blobs->image.rows-10)
00828                                                         aspect = (r>=0.4 && r<=0.8);
00829                                                 if((cx_min <= 10 || cx_max >= blobs->image.cols-10) && (cy_min <= 10 || cy_max >= blobs->image.rows-10))
00830                                                         aspect = (r>=0.4 && r<=1.5);
00831                                         
00832                                                 //ROS_ERROR("vmin: %f, hmin: %f, hr: %f ",min_dst_h, dst_h, h_r);
00833                                         
00834                                                 //filter false doors using physical constraints
00835                                                 perspective = (abs(dst_up-dst_down)<roi_x/2 && abs(dst_left-dst_right)<roi_y/2 && theta>0.45);
00836                                                 geometry = (c4.x<c3.x && c1.x<c2.x && c4.y>c1.y && c3.y>c2.y);
00837                                                 size = (dst_h>min_dst_h && dst_h<max_dst_h && dst_v>min_dst_v && dst_v<max_dst_v && roi_x>5 && roi_y>5);
00838          
00839                                                 if(!Persp_filter)
00840                                                         perspective=1; 
00841                                                 if(!Geom_filter)
00842                                                         geometry=1; 
00843                                                 if(!Size_filter)
00844                                                         size=1; 
00845                                                 if(!Aspect_filter)
00846                                                         aspect=1;
00847                                         
00848                                                 if(aspect && perspective && geometry && size)
00849                                                 {       
00850                                                         //cv::line(original->image, cvPoint(door_x,door_y), cvPoint(door_x,door_y), CV_RGB(255,0,0), 10, 8, 0);         
00851                                                         //Initialize mask matrices with ROI dimensions
00852                                                         cv::Mat area_mask, blobs_roi;
00853                                                         area_mask = cv::Mat::zeros(blobs->image.rows, blobs->image.cols, CV_8UC1);
00854 
00855                                                         //handle mask                   
00856                                                         c5=cvPoint((int)(c1.x+(c4.x-c1.x)*0.1),(int)(c1.y+(c4.y-c1.y)*0.1));
00857                                                         c6=cvPoint((int)(c2.x+(c3.x-c2.x)*0.1),(int)(c2.y+(c3.y-c2.y)*0.1));
00858                                                         c7=cvPoint((int)(c1.x+(c4.x-c1.x)*0.9),(int)(c1.y+(c4.y-c1.y)*0.9));
00859                                                         c8=cvPoint((int)(c2.x+(c3.x-c2.x)*0.9),(int)(c2.y+(c3.y-c2.y)*0.9));
00860                                                 
00861                                                         //Horiztonal location of handle mask 
00862                                                         c9=cvPoint((int)(c5.x+(c6.x-c5.x)*((float)handle_location/100)),(int)(c5.y+(c6.y-c5.y)*((float)handle_location/100)));
00863                                                         c10=cvPoint((int)(c7.x+(c8.x-c7.x)*((float)handle_location/100)),(int)(c7.y+(c8.y-c7.y)*((float)handle_location/100)));
00864                                                         c11=cvPoint((int)(c5.x+(c6.x-c5.x)*(1-((float)handle_location/100))),(int)(c5.y+(c6.y-c5.y)*(1-((float)handle_location/100))));
00865                                                         c12=cvPoint((int)(c7.x+(c8.x-c7.x)*(1-((float)handle_location/100))),(int)(c7.y+(c8.y-c7.y)*(1-((float)handle_location/100))));
00866                                 
00867                                                         h_r=max_dst_h*handle_width/100;
00868                                                         v_r=max_dst_h*handle_height/100;
00869                                                         handle_mask_width=max_dst_h/10;
00870 
00871                                                         if(handle_mask_width < 1.0)
00872                                                                 handle_mask_width=1.0;
00873 
00874                                                         //Draw handle mask
00875                                                         if(c1.x > 10 || c4.x > 10)
00876                                                                 cv::line(area_mask, c9, c10, white, (int)handle_mask_width, 8, 0);
00877                                                         if(c2.x < area_mask.cols-10 || c3.x < area_mask.cols-10)
00878                                                                 cv::line(area_mask, c11, c12, white, (int)handle_mask_width, 8, 0);
00879                                                 
00880                                                         if(SHM)
00881                                                         {
00882                                                                 if(c1.x > 10 || c4.x > 10)
00883                                                                         cv::line(original->image, c9, c10, white, (int)handle_mask_width, 8, 0);
00884                                                                 if(c2.x < area_mask.cols-10 || c3.x < area_mask.cols-10)
00885                                                                         cv::line(original->image, c11, c12, white, (int)handle_mask_width, 8, 0);
00886                                                         }
00887 
00888 
00889                                                         handle_x=0;
00890                                                         handle_y=0;
00891                                                         area=100000;
00892                                                         // "blobs" is the list of blobs, result of the "cvLabel" call at the beginning of the algorithm.
00893                                                         for (cvb::CvBlobs::const_iterator it=CVblobs.begin(); it!=CVblobs.end(); ++it)
00894                                                         {
00895                                                                 cvb::CvBlob *blob=it->second;
00896                                                                 blob->area=(blob->maxx-blob->minx)*(blob->maxy-blob->miny);
00897                                                                 if (blob->area < (v_r*h_r*2.0) && blob->area > (v_r*h_r*0.2) && blob->maxx-blob->minx < h_r*1.4 && blob->maxx-blob->minx > h_r*0.3 && blob->maxy-blob->miny < v_r*1.4 && blob->maxy-blob->miny > v_r*0.3 && area_mask.data[(int)blob->centroid.y*area_mask.cols+(int)blob->centroid.x]>0)
00898                                                                 {
00899                                                                         //ROS_ERROR("x: %d",(int)blob->centroid.x);
00900                                                                         if(abs(blob->area-v_r*h_r) < area)
00901                                                                         {
00902                                                                                 handle_x=(int)(blob->centroid.x);
00903                                                                                 handle_y=(int)(blob->centroid.y);
00904                                                                                 handle_minx=blob->minx;
00905                                                                                 handle_maxx=blob->maxx;
00906                                                                                 handle_miny=blob->miny;
00907                                                                                 handle_maxy=blob->maxy;
00908                                                                                 area=abs(blob->area-v_r*h_r);
00909                                                                                 cv::rectangle(blob_mat, cvPoint(blob->minx,blob->miny), cvPoint(blob->maxx,blob->maxy), CV_RGB(150,150,150), 2, 8, 0);
00910                                                                         }
00911                                                                 }
00912                                                         }
00913 
00914                                                         if(handle_x>30 && handle_y>30 && handle_x<original->image.cols-30 && handle_y<original->image.rows-30)
00915                                                         {                                                               
00916                                                                 cv::line(area_mask, cvPoint(handle_x,handle_y), cvPoint(handle_x,handle_y), CV_RGB(100,100,100), h_r*1.3, 8, 0);                
00917                                                                 flat=1;
00918                                                                 //horizontal flatness test
00919                                                                 i_min=cy_min; i_max=cy_max; k_min=cx_min; k_max=cx_max;
00920 
00921                                                                 //if(i_max > i_min+(int)(roi_x/5))
00922                                                                 for (int i = i_min; i < i_max; i=i+(int)((i_max-i_min)/5))
00923                                                                 {  
00924                                                                         point=0;
00925                                                                         for(int k = k_min; k < k_max; k=k+3)
00926                                                                         {       
00927                                                                                 if (k>(int)(cx_min+cx_max)/2 && area_mask.data[i*area_mask.cols+k]!=255)
00928                                                                                         point=0;
00929 
00930                                                                                 if(area_mask.data[i*area_mask.cols+k]==255)
00931                                                                                 {
00932                                                                                         if(!std::isnan(cloud.at(k,i).z) && cloud.at(k,i).z>0.0 && cloud.at(k,i).z<5.0)
00933                                                                                         {
00934                                                                                                 if(point==1)
00935                                                                                                 {
00936                                                                                                         point3D = cloud.at(k,i);
00937 
00938                                                                                                         if(SFT)
00939                                                                                                         cv::line(original->image, cvPoint(k,i), cvPoint(k,i), black, 1, 8, 0);
00940                                                                                                         if(abs(point3D.z-offsetPoint3D.z)>0.15)
00941                                                                                                         {
00942                                                                                                                 flat=0;
00943                                                                                                                 cv::line(original->image, cvPoint(k,i), cvPoint(k,i), CV_RGB(0,255,0), 5, 8, 0);
00944                                                                                                         }
00945                                                                                                 }
00946                                                                                                 offsetPoint3D = cloud.at(k,i);
00947                                                                                                 point=1;
00948                                                                                         }
00949                                                                                 }
00950                                                                         }   
00951                                                                 }
00952                                                         
00953                                                                 //vertical flatness test
00954                                                                 i_min=cy_min; i_max=cy_max; k_min=cx_min; k_max=cx_max;
00955 
00956                                                                 //if(i_max > i_min+(int)(roi_x/5))
00957                                                                 for (int k = k_min; k < k_max; k=k+(int)((k_max-k_min)/10))
00958                                                                 {  
00959                                                                         point=0;
00960                                                                         for(int i = i_min; i < i_max; i=i+3)
00961                                                                         {       
00962                                                                                 if (area_mask.data[i*area_mask.cols+k]!=255)
00963                                                                                         point=0;
00964 
00965                                                                                 if(area_mask.data[i*area_mask.cols+k]==255)
00966                                                                                 {
00967                                                                                         if(!std::isnan(cloud.at(k,i).z) && cloud.at(k,i).z>0.0 && cloud.at(k,i).z<5.0)
00968                                                                                         {
00969                                                                                                 if(point==1)
00970                                                                                                 {
00971                                                                                                         point3D = cloud.at(k,i);
00972 
00973                                                                                                         if(SFT)
00974                                                                                                         cv::line(original->image, cvPoint(k,i), cvPoint(k,i), black, 1, 8, 0);
00975                                                                                                         if(abs(point3D.z-offsetPoint3D.z)>0.15)
00976                                                                                                         {
00977                                                                                                                 flat=0;
00978                                                                                                                 cv::line(original->image, cvPoint(k,i), cvPoint(k,i), CV_RGB(0,255,0), 5, 8, 0);
00979                                                                                                         }
00980                                                                                                 }
00981                                                                                                 offsetPoint3D = cloud.at(k,i);
00982                                                                                                 point=1;
00983                                                                                         }
00984                                                                                 }
00985                                                                         }   
00986                                                                 }
00987 
00988                                                                 if(flat==1)
00989                                                                 {
00990                                                                         //cv::line(original->image, cvPoint(handle_x,handle_y), cvPoint(handle_x,handle_y), CV_RGB(255,0,0), 10);
00991                                                                         if(debugging_images==1)
00992                                                                         DrawRect (blob_mat, c1, c2, c3, c4, CV_RGB(150,150,150), 2, 0); 
00993                                                                         if(debugging_images==1)
00994                                                                         cv::rectangle(original->image, cvPoint(handle_minx,handle_miny), cvPoint(handle_maxx,handle_maxy), CV_RGB(150,150,150), 2, 8, 0);
00995                                                                                 
00996                                                                         x_i=0;
00997                                                                         y_i=0;
00998                                                                         z_i=0;
00999                                                                         compCount=0;
01000 
01001                                                                         for(int k = handle_miny; k < handle_maxy; k++)
01002                                                                         {
01003                                                                                 for(int i = handle_minx; i < handle_maxx; i++)
01004                                                                                 {
01005                                                                                         point3D = cloud.at(i,k);
01006                                                                                         if(!std::isnan(point3D.z) && point3D.z>0.0 && point3D.z<5.0)
01007                                                                                         {
01008                                                                                                 x_i=point3D.x+x_i;
01009                                                                                                 y_i=point3D.y+y_i;
01010                                                                                                 z_i=point3D.z+z_i;
01011                                                                                                 compCount++;
01012                                                                                         }
01013                                                                                 }
01014                                                                         }
01015                                                                         
01016                                                                         x_i=x_i/(float)compCount;
01017                                                                         y_i=y_i/(float)compCount;
01018                                                                         z_i=z_i/(float)compCount;
01019 
01020                                                                         //prepare locations of the selected door frames for the output message  
01021                                                                         ss_door_centroid.push_back(cvPoint(door_x,door_y));
01022                                                                         ss_handle.push_back(cvPoint(handle_x,handle_y));
01023                                                                         ss_handle_x.push_back(x_i);
01024                                                                         ss_handle_y.push_back(y_i);
01025                                                                         ss_handle_z.push_back(z_i);
01026                                                                         ss_c1.push_back(c1);
01027                                                                         ss_c2.push_back(c2);
01028                                                                         ss_c3.push_back(c3);
01029                                                                         ss_c4.push_back(c4);
01030                                                                 }
01031                                                         }
01032                                                         
01033                                                         handle_y=0;
01034                                                         handle_x=0;                                             
01035                                                 }
01036                                         }       
01037                                 }
01038                         }
01039                 }
01040         }
01041 
01042         if (ss_door_centroid.size()>0)
01043         {
01044                 b_door_centroid=cvPoint(0,0);
01045                 b_handle=cvPoint(0,0);
01046                 b_handle_x=0;
01047                 b_handle_y=0;
01048                 b_handle_z=0;
01049                 b_c1=cvPoint(0,0);
01050                 b_c2=cvPoint(0,0);
01051                 b_c3=cvPoint(0,0);
01052                 b_c4=cvPoint(0,0);
01053 
01054                 for (size_t i=0; i<ss_door_centroid.size(); i++)
01055                 {
01056                         b_door_centroid.x=(int)(b_door_centroid.x+ss_door_centroid.at(i).x);
01057                         b_door_centroid.y=(int)(b_door_centroid.y+ss_door_centroid.at(i).y);
01058                         b_handle.x=(int)(b_handle.x+ss_handle.at(i).x);
01059                         b_handle.y=(int)(b_handle.y+ss_handle.at(i).y);
01060                         b_handle_x=(b_handle_x+ss_handle_x.at(i));
01061                         b_handle_y=(b_handle_y+ss_handle_y.at(i));
01062                         b_handle_z=(b_handle_z+ss_handle_z.at(i));
01063                         b_c1.x=(int)(b_c1.x+ss_c1.at(i).x);
01064                         b_c1.y=(int)(b_c1.y+ss_c1.at(i).y);
01065                         b_c2.x=(int)(b_c2.x+ss_c2.at(i).x);
01066                         b_c2.y=(int)(b_c2.y+ss_c2.at(i).y);
01067                         b_c3.x=(int)(b_c3.x+ss_c3.at(i).x);
01068                         b_c3.y=(int)(b_c3.y+ss_c3.at(i).y);
01069                         b_c4.x=(int)(b_c4.x+ss_c4.at(i).x);
01070                         b_c4.y=(int)(b_c4.y+ss_c4.at(i).y);
01071                 }
01072                 b_door_centroid.x=(int)(b_door_centroid.x/ss_door_centroid.size());
01073                 b_door_centroid.y=(int)(b_door_centroid.y/ss_door_centroid.size());
01074                 b_handle.x=(int)(b_handle.x/ss_door_centroid.size());
01075                 b_handle.y=(int)(b_handle.y/ss_door_centroid.size());
01076                 b_handle_x=(b_handle_x/ss_door_centroid.size());
01077                 b_handle_y=(b_handle_y/ss_door_centroid.size());
01078                 b_handle_z=(b_handle_z/ss_door_centroid.size());
01079                 b_c1.x=(int)(b_c1.x/ss_door_centroid.size());
01080                 b_c1.y=(int)(b_c1.y/ss_door_centroid.size());
01081                 b_c2.x=(int)(b_c2.x/ss_door_centroid.size());
01082                 b_c2.y=(int)(b_c2.y/ss_door_centroid.size());
01083                 b_c3.x=(int)(b_c3.x/ss_door_centroid.size());
01084                 b_c3.y=(int)(b_c3.y/ss_door_centroid.size());
01085                 b_c4.x=(int)(b_c4.x/ss_door_centroid.size());
01086                 b_c4.y=(int)(b_c4.y/ss_door_centroid.size());
01087 
01088                 if(s_handle.x>0 && s_handle.y>0)
01089                 {
01090                         dx=abs(b_handle.x-s_handle.x);
01091                         dy=abs(b_handle.y-s_handle.y);
01092                         dst=sqrt(dx*dx+dy*dy);
01093                 
01094                         if(dst<min_dst_h/4)
01095                                 support++;
01096                 }
01097                 if(s_handle.x==0 && s_handle.y==0)
01098                         dst=max_dst_h/4;
01099                 
01100                 s_handle.x=b_handle.x;
01101                 s_handle.y=b_handle.y;
01102         }
01103         
01104         if(ss_door_centroid.size()==0)
01105                 support--;
01106         if(support < 0)
01107         {
01108                 support=0;
01109                 s_handle.x=0;
01110                 s_handle.y=0;
01111         }
01112 
01113         if(support >10)
01114                 support=10;     
01115 
01116         if(ss_door_centroid.size()>0 && dst<max_dst_h/4)
01117         {
01118                 x=b_handle_x;
01119                 y=b_handle_y;
01120                 z=b_handle_z;
01121 
01122                 //ROS_ERROR("boundaries loop!");
01123                 
01124                 if(!std::isnan(z) && z > 0.0 && z < 5.0)
01125                 {
01126                         if(debugging_images==1)
01127                         DrawRect (original->image, b_c1, b_c2, b_c3, b_c4, CV_RGB(255,255,0), 2, 0);
01128 
01129                         std::ostringstream zd;
01130                         zd << b_handle_z ;
01131                 
01132                         if(debugging_images==1)
01133                         cv::line(original->image, b_handle, b_handle, CV_RGB(0,0,255), 10, 8, 0);
01134 
01135                         if(b_handle.x+10>0 && b_handle.y+25>0 && b_handle.x+10<original->image.cols-50 && b_handle.y+25<original->image.rows-25)
01136                         {
01137                                 if(debugging_images==1)
01138                                 putText(original->image, zd.str(), cvPoint(b_handle.x+10,b_handle.y+25), cv::FONT_HERSHEY_SIMPLEX, 0.7, white,3);
01139                         }
01140 
01141 
01142                         poses.pose.position.x = x;
01143                         poses.pose.position.y = y;
01144                         poses.pose.position.z = z;
01145 
01146                         poses.pose.orientation.w = 0.0;
01147 
01148                         if(b_door_centroid.x > b_handle.x)
01149                                 poses.pose.orientation.w = -1.0; //left handle
01150                         if(b_door_centroid.x < b_handle.x)
01151                                 poses.pose.orientation.w = 1.0; //right handle
01152 
01153                         door_handle_publisher_.publish(poses);
01154                         b_handle_z=b_handle_z*1000;
01155                         
01156                         door_coordinates.data.clear();
01157                         door_coordinates.data.push_back(b_c1.x);
01158                         door_coordinates.data.push_back(b_c1.y);
01159                         door_coordinates.data.push_back(b_c2.x);
01160                         door_coordinates.data.push_back(b_c2.y);
01161                         door_coordinates.data.push_back(b_c3.x);
01162                         door_coordinates.data.push_back(b_c3.y);
01163                         door_coordinates.data.push_back(b_c4.x);
01164                         door_coordinates.data.push_back(b_c4.y);        
01165                         door_coordinates.data.push_back(b_handle.x);
01166                         door_coordinates.data.push_back(b_handle.y);
01167                         door_coordinates.data.push_back((int)b_handle_z);
01168                         door_coordinates.data.push_back(poses.pose.orientation.w);
01169 
01170                         closed_door_coordinates_publisher_.publish(door_coordinates);
01171                 }
01172         }
01173 
01174         point3D = cloud.at((int)(original->image.cols/2),(int)(original->image.rows/2));
01175         sensor_range= !std::isnan(point3D.z) && point3D.z>0.0 && point3D.z<5.0;
01176         if(sensor_range)
01177         {
01178                 min_dst_h=(min_door_width/point3D.z);
01179                 max_dst_h=(max_door_width/point3D.z);
01180                 min_dst_v=(min_door_height/point3D.z);
01181                 max_dst_v=(max_door_height/point3D.z);
01182         }
01183 
01184         if(DSC)
01185                 DoorSizeCalibration (original->image, min_dst_h, max_dst_h, min_dst_v, max_dst_v, handle_width, handle_height); 
01186         if(debugging_images==2)
01187                 original->image = blob_mat*0.5 + original->image*0.5;   
01188         if(debugging_images==3)
01189                 original->image = canny->image;
01190         if(debugging_images==4)
01191                 original->image = wshed;
01192         if(debugging_images==5)
01193                 original->image = gradient->image;
01194 
01195         if(debugging_images!=0)
01196         {
01197                 cv::imshow(WINDOW_1, original->image);
01198                 //cvMoveWindow(WINDOW_1, 0, 0);
01199                 cv::waitKey(3);
01200         }
01201   }
01202 
01203   captured_depth = 0;
01204 
01205   //unlock previously blocked shared variables 
01206   //this->alg_.unlock();
01207   this->image_color_mutex_.exit(); 
01208 }
01209 
01210 /*  [service callbacks] */
01211 
01212 /*  [action callbacks] */
01213 
01214 /*  [action requests] */
01215 
01216 void ClosedDoorDetectorAlgNode::node_config_update(Config &config, uint32_t level)
01217 {
01218   this->alg_.lock();
01219 
01220         this->allowed_blobs = config.allowed_blobs;
01221         this->segment_fidelity = config.segment_fidelity;
01222         this->segment_size = config.segment_size;
01223         this->min_door_width = config.min_door_width;
01224         this->max_door_width = config.max_door_width;
01225         this->min_door_height = config.min_door_height;
01226         this->max_door_height = config.max_door_height;
01227         this->handle_width = config.handle_width;
01228         this->handle_height = config.handle_height;
01229         this->handle_location = config.handle_location;
01230         this->debugging_images = config.debugging_images;
01231         this->no_simulator = config.no_simulator;
01232         this->DSC = config.DSC;
01233         this->SHM = config.SHM;
01234         this->SVP = config.SVP;
01235         this->SFT = config.SFT;
01236         this->Range_filter = config.Range_filter;
01237         this->Persp_filter = config.Persp_filter;
01238         this->Geom_filter = config.Geom_filter ;
01239         this->Size_filter = config.Size_filter ;
01240         this->Aspect_filter = config.Aspect_filter;
01241 
01242   this->alg_.unlock();
01243 }
01244 
01245 void ClosedDoorDetectorAlgNode::addNodeDiagnostics(void)
01246 {
01247 }
01248 
01249 /* main function */
01250 int main(int argc,char *argv[])
01251 {
01252   return algorithm_base::main<ClosedDoorDetectorAlgNode>(argc, argv, "closed_door_detector_alg_node");
01253 }
01254 
01255 /* algorithm functions */
01256 void ClosedDoorDetectorAlgNode::DoorSizeCalibration (cv::Mat inputImage, double min_dst_h, double max_dst_h, double min_dst_v, double max_dst_v, int handle_width, int handle_height)
01257 {       
01258 
01259         //Smallest door frame allowed
01260         c1= cvPoint((inputImage.cols/2)-(min_dst_h/2), (inputImage.rows/2)-(min_dst_v/2));
01261         c2= cvPoint((inputImage.cols/2)+(min_dst_h/2), (inputImage.rows/2)-(min_dst_v/2));
01262         c3= cvPoint((inputImage.cols/2)+(min_dst_h/2), (inputImage.rows/2)+(min_dst_v/2));
01263         c4= cvPoint((inputImage.cols/2)-(min_dst_h/2), (inputImage.rows/2)+(min_dst_v/2));
01264         
01265         DrawRect (inputImage, c1, c2, c3, c4, CV_RGB(255,0,0), 2, 0);
01266 
01267         //Biggest door frame allowed
01268         c1= cvPoint((inputImage.cols/2)-(max_dst_h/2), (inputImage.rows/2)-(max_dst_v/2));
01269         c2= cvPoint((inputImage.cols/2)+(max_dst_h/2), (inputImage.rows/2)-(max_dst_v/2));
01270         c3= cvPoint((inputImage.cols/2)+(max_dst_h/2), (inputImage.rows/2)+(max_dst_v/2));
01271         c4= cvPoint((inputImage.cols/2)-(max_dst_h/2), (inputImage.rows/2)+(max_dst_v/2));
01272         
01273         DrawRect (inputImage, c1, c2, c3, c4, CV_RGB(255,0,0), 2, 0);
01274         
01275         //Expected handle size
01276         c1= cvPoint((inputImage.cols/2)-(max_dst_h*handle_width)/200, (inputImage.rows/2)-(max_dst_h*handle_height)/200);
01277         c2= cvPoint((inputImage.cols/2)+(max_dst_h*handle_width)/200, (inputImage.rows/2)-(max_dst_h*handle_height)/200);
01278         c3= cvPoint((inputImage.cols/2)+(max_dst_h*handle_width)/200, (inputImage.rows/2)+(max_dst_h*handle_height)/200);
01279         c4= cvPoint((inputImage.cols/2)-(max_dst_h*handle_width)/200, (inputImage.rows/2)+(max_dst_h*handle_height)/200);
01280 
01281         DrawRect (inputImage, c1, c2, c3, c4, CV_RGB(0,255,0), 2, 0);
01282 }
01283 
01284 void ClosedDoorDetectorAlgNode::DrawRect (cv::Mat inputImage, cv::Point q1, cv::Point q2, cv::Point q3, cv::Point q4, cv::Scalar color, int lineSize, int filled)
01285 {       
01286         if(filled==0)
01287         {
01288                 cv::line(inputImage, q1, q2, color, lineSize);
01289                 cv::line(inputImage, q2, q3, color, lineSize);
01290                 cv::line(inputImage, q3, q4, color, lineSize);
01291                 cv::line(inputImage, q4, q1, color, lineSize);
01292         }
01293 
01294         if(filled==1)
01295         {
01296                 std::vector<cv::Point> pts;
01297                 pts.push_back(q1);
01298                 pts.push_back(q2);
01299                 pts.push_back(q3);
01300                 pts.push_back(q4);
01301         
01302                 cv::Point *pP = new cv::Point[pts.size()];
01303                 std::copy(pts.begin(), pts.end(), pP);
01304                 fillConvexPoly(inputImage, pP, 4, color);
01305         }
01306 }
01307 
01308 double ClosedDoorDetectorAlgNode::AngleBetweenLines (cv::Point point1, cv::Point point2, cv::Point point3, cv::Point point4)
01309 {       
01310         double m1, m2, dx, dy;
01311 
01312         dy=point2.y-point1.y;
01313         dx=point2.y-point1.y;
01314         m1=dy/(dx+0.0001);
01315         dy=point4.y-point3.y;
01316         dx=point4.x-point3.x;
01317         m2=dy/(dx+0.0001);
01318 
01319         double theta=abs(atan((m2-m1)/(1.0001+m1*m2)));
01320         
01321         return theta;
01322 }
01323 


iri_door_detector
Author(s): Jose Rodriguez
autogenerated on Fri Dec 6 2013 23:57:16