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
00014
00015
00016
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
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
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
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
00049 }
00050
00051 void ClosedDoorDetectorAlgNode::mainNodeThread(void)
00052 {
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064 }
00065
00066
00067 void ClosedDoorDetectorAlgNode::door_action_start_callback(const std_msgs::Int8::ConstPtr& action_start)
00068 {
00069
00070
00071
00072
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
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
00090
00091 this->door_action_start_mutex_.exit();
00092 }
00093
00094 void ClosedDoorDetectorAlgNode::points_callback(const sensor_msgs::PointCloud2::ConstPtr& points)
00095 {
00096
00097
00098
00099
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
00110
00111 this->points_mutex_.exit();
00112 }
00113
00114 void ClosedDoorDetectorAlgNode::image_color_callback(const sensor_msgs::Image::ConstPtr& image_color)
00115 {
00116
00117
00118
00119
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
00134 ROS_ERROR("Error while capturing color image: %s", e.what());
00135 return;
00136 }
00137
00138
00139
00140 cv::medianBlur(gradient->image, gradient->image, 3);
00141 cv::GaussianBlur(gradient->image, gradient->image, cv::Size(5,5), 0, 0);
00142
00143
00144
00145
00146
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
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
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
00186 watershed( gradient->image, markers );
00187
00188 cv::Mat wshed(markers.size(), CV_8UC3);
00189 wshed = cv::Scalar::all(0);
00190
00191
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
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
00218
00219
00220
00221
00222
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
00234 IplImage ipl_1 = blobs->image;
00235
00236
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
00243 cvb::cvLabel(&ipl_1, labelImg, CVblobs);
00244
00245 cvb::cvRenderBlobs(labelImg, CVblobs, blobsDst, blobsDst, CV_BLOB_RENDER_COLOR);
00246
00247
00248 blob_mat= cv::Mat(blobsDst,true);
00249
00250 cvReleaseImage(&labelImg);
00251 cvReleaseImage(&blobsDst);
00252
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
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
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
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
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
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
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
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
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
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
00622
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
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
00653
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
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
00684
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
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
00715
00716 }
00717
00718 if(f_c1*f_c2*f_c3*f_c4>0)
00719 {
00720
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
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
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
00833
00834
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
00851
00852 cv::Mat area_mask, blobs_roi;
00853 area_mask = cv::Mat::zeros(blobs->image.rows, blobs->image.cols, CV_8UC1);
00854
00855
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
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
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
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
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
00919 i_min=cy_min; i_max=cy_max; k_min=cx_min; k_max=cx_max;
00920
00921
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
00954 i_min=cy_min; i_max=cy_max; k_min=cx_min; k_max=cx_max;
00955
00956
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
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
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
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;
01150 if(b_door_centroid.x < b_handle.x)
01151 poses.pose.orientation.w = 1.0;
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
01199 cv::waitKey(3);
01200 }
01201 }
01202
01203 captured_depth = 0;
01204
01205
01206
01207 this->image_color_mutex_.exit();
01208 }
01209
01210
01211
01212
01213
01214
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
01250 int main(int argc,char *argv[])
01251 {
01252 return algorithm_base::main<ClosedDoorDetectorAlgNode>(argc, argv, "closed_door_detector_alg_node");
01253 }
01254
01255
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
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
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
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