$search
00001 00034 #include <assert.h> 00035 00036 #include <ros/ros.h> 00037 #include "sensor_msgs/PointCloud2.h" 00038 #include <pcl_ros/transforms.h> 00039 00040 #include <pcl/sample_consensus/method_types.h> 00041 #include <pcl/sample_consensus/model_types.h> 00042 #include <pcl/segmentation/sac_segmentation.h> 00043 #include <pcl/ModelCoefficients.h> 00044 #include <pcl/filters/extract_indices.h> 00045 #include <pcl/features/normal_3d.h> 00046 00047 #include <pcl/io/pcd_io.h> 00048 00049 #include "roi_pcl_filter.h" 00050 00051 #include "cv_bridge/CvBridge.h" 00052 #include <opencv/cv.h> 00053 #include <opencv/highgui.h> 00054 #include "sensor_msgs/Image.h" 00055 #include "sensor_msgs/CameraInfo.h" 00056 #include <image_geometry/pinhole_camera_model.h> 00057 #include <tf_conversions/tf_eigen.h> 00058 #include <eigen_conversions/eigen_msg.h> 00059 00060 #include <pr2_interactive_segmentation/cornerPokePoseFind.h> 00061 #include <pr2_interactive_segmentation/cornerFind.h> 00062 #include <pr2_interactive_segmentation/depthImage.h> 00063 #include <pr2_interactive_segmentation/estimateRigid.h> 00064 #include <boost/foreach.hpp> 00065 00066 00067 00068 //#include <camera_self_filter/mask.h> 00069 00070 #define X_OUTPUT 1 00071 00072 using std::cout; 00073 using std::endl; 00074 using std::ostream; 00075 using namespace std; 00076 00077 00078 ostream& operator<< (ostream& out, const tf::Transform tf){ 00079 Eigen::Affine3d tf_eigen; 00080 tf::TransformTFToEigen(tf,tf_eigen); 00081 out << tf_eigen.matrix(); 00082 return out; 00083 } 00084 00085 static void 00086 icvGetRTMatrix( const CvPoint2D32f* a, const CvPoint2D32f* b, 00087 int count, CvMat* M, int full_affine ) 00088 { 00089 if( full_affine ) 00090 { 00091 double sa[36], sb[6]; 00092 CvMat A = cvMat( 6, 6, CV_64F, sa ), B = cvMat( 6, 1, CV_64F, sb ); 00093 CvMat MM = cvMat( 6, 1, CV_64F, M->data.db ); 00094 00095 int i; 00096 00097 memset( sa, 0, sizeof(sa) ); 00098 memset( sb, 0, sizeof(sb) ); 00099 00100 for( i = 0; i < count; i++ ) 00101 { 00102 sa[0] += a[i].x*a[i].x; 00103 sa[1] += a[i].y*a[i].x; 00104 sa[2] += a[i].x; 00105 00106 sa[6] += a[i].x*a[i].y; 00107 sa[7] += a[i].y*a[i].y; 00108 sa[8] += a[i].y; 00109 00110 sa[12] += a[i].x; 00111 sa[13] += a[i].y; 00112 sa[14] += 1; 00113 00114 sb[0] += a[i].x*b[i].x; 00115 sb[1] += a[i].y*b[i].x; 00116 sb[2] += b[i].x; 00117 sb[3] += a[i].x*b[i].y; 00118 sb[4] += a[i].y*b[i].y; 00119 sb[5] += b[i].y; 00120 } 00121 00122 sa[21] = sa[0]; 00123 sa[22] = sa[1]; 00124 sa[23] = sa[2]; 00125 sa[27] = sa[6]; 00126 sa[28] = sa[7]; 00127 sa[29] = sa[8]; 00128 sa[33] = sa[12]; 00129 sa[34] = sa[13]; 00130 sa[35] = sa[14]; 00131 00132 cvSolve( &A, &B, &MM, CV_SVD ); 00133 } 00134 else 00135 { 00136 double sa[16], sb[4], m[4], *om = M->data.db; 00137 CvMat A = cvMat( 4, 4, CV_64F, sa ), B = cvMat( 4, 1, CV_64F, sb ); 00138 CvMat MM = cvMat( 4, 1, CV_64F, m ); 00139 00140 int i; 00141 00142 memset( sa, 0, sizeof(sa) ); 00143 memset( sb, 0, sizeof(sb) ); 00144 00145 for( i = 0; i < count; i++ ) 00146 { 00147 sa[0] += a[i].x*a[i].x + a[i].y*a[i].y; 00148 sa[1] += 0; 00149 sa[2] += a[i].x; 00150 sa[3] += a[i].y; 00151 00152 sa[4] += 0; 00153 sa[5] += a[i].x*a[i].x + a[i].y*a[i].y; 00154 sa[6] += -a[i].y; 00155 sa[7] += a[i].x; 00156 00157 sa[8] += a[i].x; 00158 sa[9] += -a[i].y; 00159 sa[10] += 1; 00160 sa[11] += 0; 00161 00162 sa[12] += a[i].y; 00163 sa[13] += a[i].x; 00164 sa[14] += 0; 00165 sa[15] += 1; 00166 00167 sb[0] += a[i].x*b[i].x + a[i].y*b[i].y; 00168 sb[1] += a[i].x*b[i].y - a[i].y*b[i].x; 00169 sb[2] += b[i].x; 00170 sb[3] += b[i].y; 00171 } 00172 00173 cvSolve( &A, &B, &MM, CV_SVD ); 00174 00175 om[0] = om[4] = m[0]; 00176 om[1] = -m[1]; 00177 om[3] = m[1]; 00178 om[2] = m[2]; 00179 om[5] = m[3]; 00180 } 00181 } 00182 00183 //CV_IMPL 00184 int 00185 cvEstimateRigidTransform( const CvArr* matA, const CvArr* matB, CvMat* matM, int full_affine, std::vector<int>& status_inliers ) 00186 { 00187 // const int COUNT = 15; 00188 // const int WIDTH = 160, HEIGHT = 120; 00189 const int RANSAC_MAX_ITERS = 500; 00190 const int RANSAC_SIZE0 = 3; 00191 const double RANSAC_GOOD_RATIO = 0.5; 00192 // const double RANSAC_GOOD_RATIO = 0.2; 00193 const double RANSAC_BOUNDING_RECT_MULTIPLIER = 0.05; 00194 00195 cv::Ptr<CvMat> sA, sB; 00196 cv::AutoBuffer<CvPoint2D32f> pA, pB; 00197 cv::AutoBuffer<int> good_idx; 00198 cv::AutoBuffer<char> status; 00199 cv::Ptr<CvMat> gray; 00200 00201 CvMat stubA, *A = cvGetMat( matA, &stubA ); 00202 CvMat stubB, *B = cvGetMat( matB, &stubB ); 00203 CvSize sz0, sz1; 00204 int cn, equal_sizes; 00205 int i, j, k, k1; 00206 int count_x, count_y, count = 0; 00207 double scale = 1; 00208 CvRNG rng = cvRNG(-1); 00209 double m[6]={0}; 00210 CvMat M = cvMat( 2, 3, CV_64F, m ); 00211 int good_count = 0; 00212 CvRect brect; 00213 00214 if( !CV_IS_MAT(matM) ) 00215 CV_Error( matM ? CV_StsBadArg : CV_StsNullPtr, "Output parameter M is not a valid matrix" ); 00216 00217 if( !CV_ARE_SIZES_EQ( A, B ) ) 00218 CV_Error( CV_StsUnmatchedSizes, "Both input images must have the same size" ); 00219 00220 if( !CV_ARE_TYPES_EQ( A, B ) ) 00221 CV_Error( CV_StsUnmatchedFormats, "Both input images must have the same data type" ); 00222 00223 else if( CV_MAT_TYPE(A->type) == CV_32FC2 || CV_MAT_TYPE(A->type) == CV_32SC2 ) 00224 { 00225 count = A->cols*A->rows; 00226 CvMat _pA, _pB; 00227 pA.allocate(count); 00228 pB.allocate(count); 00229 _pA = cvMat( A->rows, A->cols, CV_32FC2, pA ); 00230 _pB = cvMat( B->rows, B->cols, CV_32FC2, pB ); 00231 cvConvert( A, &_pA ); 00232 cvConvert( B, &_pB ); 00233 } 00234 else 00235 CV_Error( CV_StsUnsupportedFormat, "Both input images must have either 8uC1 or 8uC3 type" ); 00236 00237 good_idx.allocate(count); 00238 00239 if( count < RANSAC_SIZE0 ) 00240 return 0; 00241 00242 CvMat _pB = cvMat(1, count, CV_32FC2, pB); 00243 brect = cvBoundingRect(&_pB, 1); 00244 00245 // RANSAC stuff: 00246 // 1. find the consensus 00247 for( k = 0; k < RANSAC_MAX_ITERS; k++ ) 00248 { 00249 int idx[RANSAC_SIZE0]; 00250 CvPoint2D32f a[3]; 00251 CvPoint2D32f b[3]; 00252 00253 memset( a, 0, sizeof(a) ); 00254 memset( b, 0, sizeof(b) ); 00255 00256 // choose random 3 non-complanar points from A & B 00257 for( i = 0; i < RANSAC_SIZE0; i++ ) 00258 { 00259 for( k1 = 0; k1 < RANSAC_MAX_ITERS; k1++ ) 00260 { 00261 idx[i] = cvRandInt(&rng) % count; 00262 00263 for( j = 0; j < i; j++ ) 00264 { 00265 if( idx[j] == idx[i] ) 00266 break; 00267 // check that the points are not very close one each other 00268 if( fabs(pA[idx[i]].x - pA[idx[j]].x) + 00269 fabs(pA[idx[i]].y - pA[idx[j]].y) < FLT_EPSILON ) 00270 break; 00271 if( fabs(pB[idx[i]].x - pB[idx[j]].x) + 00272 fabs(pB[idx[i]].y - pB[idx[j]].y) < FLT_EPSILON ) 00273 break; 00274 } 00275 00276 if( j < i ) 00277 continue; 00278 00279 if( i+1 == RANSAC_SIZE0 ) 00280 { 00281 // additional check for non-complanar vectors 00282 a[0] = pA[idx[0]]; 00283 a[1] = pA[idx[1]]; 00284 a[2] = pA[idx[2]]; 00285 00286 b[0] = pB[idx[0]]; 00287 b[1] = pB[idx[1]]; 00288 b[2] = pB[idx[2]]; 00289 00290 double dax1 = a[1].x - a[0].x, day1 = a[1].y - a[0].y; 00291 double dax2 = a[2].x - a[0].x, day2 = a[2].y - a[0].y; 00292 double dbx1 = b[1].x - b[0].y, dby1 = b[1].y - b[0].y; 00293 double dbx2 = b[2].x - b[0].x, dby2 = b[2].y - b[0].y; 00294 const double eps = 0.01; 00295 00296 if( fabs(dax1*day2 - day1*dax2) < eps*sqrt(dax1*dax1+day1*day1)*sqrt(dax2*dax2+day2*day2) || 00297 fabs(dbx1*dby2 - dby1*dbx2) < eps*sqrt(dbx1*dbx1+dby1*dby1)*sqrt(dbx2*dbx2+dby2*dby2) ) 00298 continue; 00299 } 00300 break; 00301 } 00302 00303 if( k1 >= RANSAC_MAX_ITERS ) 00304 break; 00305 } 00306 00307 if( i < RANSAC_SIZE0 ) 00308 continue; 00309 00310 // estimate the transformation using 3 points 00311 icvGetRTMatrix( a, b, 3, &M, full_affine ); 00312 00313 for( i = 0, good_count = 0; i < count; i++ ) 00314 { 00315 if( fabs( m[0]*pA[i].x + m[1]*pA[i].y + m[2] - pB[i].x ) + 00316 fabs( m[3]*pA[i].x + m[4]*pA[i].y + m[5] - pB[i].y ) < MAX(brect.width,brect.height)*RANSAC_BOUNDING_RECT_MULTIPLIER ) 00317 good_idx[good_count++] = i; 00318 } 00319 00320 if( good_count >= count*RANSAC_GOOD_RATIO ) 00321 break; 00322 } 00323 00324 if( k >= RANSAC_MAX_ITERS ) 00325 return 0; 00326 00327 if( good_count < count ) 00328 { 00329 status_inliers.resize(count, 0); //chris 00330 for( i = 0; i < good_count; i++ ) 00331 { 00332 j = good_idx[i]; 00333 pA[i] = pA[j]; 00334 pB[i] = pB[j]; 00335 status_inliers[j] = 1; //chris 00336 } 00337 }else{ 00338 status_inliers.resize(count, 1); //chris 00339 } 00340 00341 icvGetRTMatrix( pA, pB, good_count, &M, full_affine ); 00342 m[2] /= scale; 00343 m[5] /= scale; 00344 cvConvert( &M, matM ); 00345 00346 return 1; 00347 } 00348 00349 namespace cv{ 00350 int estimateRigidTransform( const Mat& A, 00351 const Mat& B, Mat& M, 00352 bool fullAffine, std::vector<int>& status_inliers ) 00353 { 00354 M = cv::Mat(2, 3, CV_64F); 00355 CvMat matA = A, matB = B, matM = M; 00356 return cvEstimateRigidTransform(&matA, &matB, &matM, fullAffine, status_inliers); 00357 00358 } 00359 }; 00360 00361 00362 00363 00364 class DepthTransfomer{ 00365 00366 typedef pcl::PointXYZ Point; 00367 // typedef pcl::PointXYZRGB Point; 00368 00369 ros::NodeHandle _nh; 00370 ros::NodeHandle _nh_private; 00371 ros::ServiceServer _getMaskServer, _estimateRigidServer; 00372 00373 // sensor_msgs::CameraInfoConstPtr _cam_info; 00374 // image_geometry::PinholeCameraModel _model; 00375 00376 // sensor_msgs::CameraInfoConstPtr _cam_info_new; 00377 sensor_msgs::CameraInfoPtr _cam_info_new; 00378 image_geometry::PinholeCameraModel _model_new; 00379 00380 00381 00382 00383 // ros::ServiceClient _self_mask_client; 00384 tf::TransformListener listener_; 00385 sensor_msgs::CvBridge _bridge; 00386 ROI_Filter<Point> roi_filter; 00387 00388 tf::Transform tf_virtual_cam; 00389 tf::Transform tf_virtual_cam_transl; 00390 00391 pcl::ModelCoefficients::Ptr coefficients; 00392 std::string point_cloud_topic; 00393 00394 int num_max_dilations; 00395 00396 00397 double virtual_cam_z; 00398 double virtual_cam_x; 00399 std::string base_frame; 00400 00401 cv::Mat last_depth; 00402 00403 00404 00405 00406 00407 // colormap for disparities, RGB order 00408 static unsigned char colormap[]; 00409 00410 00411 public: 00412 DepthTransfomer():_nh_private("~"){ 00413 _nh_private.param("num_max_dilations", num_max_dilations, 5); 00414 00415 std::string camera_name; 00416 _nh_private.param<std::string>("camera_name_info_topic_original",camera_name, "/kinect/rgb/cmaera_info"); 00417 00418 00419 std::string camera_name_new; 00420 _nh_private.param<std::string>("camera_name_info_topic_new",camera_name_new, "/prosilica/camera_info"); 00421 00422 _nh_private.param<std::string>("base_frame",base_frame, "base_link"); 00423 00424 00425 00426 _nh_private.param<std::string>("point_cloud_topic",point_cloud_topic, "/kinect/rgb/points"); 00427 00428 00429 // _cam_info = ros::topic::waitForMessage<sensor_msgs::CameraInfo>(camera_name , ros::Duration(5.0)); 00430 // _model.fromCameraInfo(_cam_info); 00431 00432 sensor_msgs::CameraInfoConstPtr cam_info_new = ros::topic::waitForMessage<sensor_msgs::CameraInfo>(camera_name_new, ros::Duration(5.0)); 00433 _cam_info_new = boost::const_pointer_cast<sensor_msgs::CameraInfo>(cam_info_new); 00434 _cam_info_new->header.frame_id = "high_def_optical_frame"; 00435 _model_new.fromCameraInfo(_cam_info_new); 00436 00437 _getMaskServer = _nh.advertiseService("getDepthImage", &DepthTransfomer::getPokePointServiceCB, this); 00438 _estimateRigidServer = _nh.advertiseService("estimateRigid", &DepthTransfomer::estimateRigidTransform2DRansacCB, this); 00439 00440 // _self_mask_client = _nh.serviceClient<camera_self_filter::mask>("self_mask"); 00441 00442 ROS_INFO("point_cloud_topic %s",point_cloud_topic.c_str()); 00443 00444 _nh_private.param("virtual_cam_z", virtual_cam_z, 1.5); 00445 _nh_private.param("virtual_cam_x",virtual_cam_x, .60); 00446 00447 //create location of cam over table 00448 tf_virtual_cam.setIdentity(); 00449 tf_virtual_cam_transl.setIdentity(); 00450 tf_virtual_cam_transl.setOrigin(tf::Vector3(virtual_cam_x, 0.0, virtual_cam_z)); 00451 //optical frame is rotated by 180 degree around y-axis 00452 btMatrix3x3 rot (0, -1, 0, 00453 -1, 0, 0, 00454 0, 0 , -1); 00455 tf::Quaternion q; 00456 rot.getRotation(q); 00457 tf_virtual_cam.setRotation(q); 00458 // tf_virtual_cam.setRotation(tf::Quaternion(tf::Vector3(0.0, 1.0, 0.0), M_PI)); 00459 // tf_virtual_cam.setRotation(tf::Quaternion(tf::Vector3(0.0, 1.0, 0.0), M_PI * 0.5)); 00460 00461 //inverse because later we transform into new cam from base_frame 00462 // tf_virtual_cam = tf_virtual_cam.inverse(); 00463 00464 cout<<"tf_virtual_cam"<<endl<<tf_virtual_cam<<endl; 00465 cout<<"tf_virtual_cam_transl"<<endl<<tf_virtual_cam_transl<<endl; 00466 cout<<"base_frame "<<base_frame<<endl; 00467 00468 00469 00470 00471 00472 } 00473 00474 bool getPokePointServiceCB(pr2_interactive_segmentation::depthImage::Request& req, pr2_interactive_segmentation::depthImage::Response& res){ 00475 00476 00477 sensor_msgs::PointCloud2ConstPtr cloud_msg = ros::topic::waitForMessage<sensor_msgs::PointCloud2>(point_cloud_topic, ros::Duration(5.0)); 00478 pcl::PointCloud<Point>::Ptr cloud(new pcl::PointCloud<Point>()); 00479 pcl::fromROSMsg<Point>(*cloud_msg, *cloud); 00480 00481 // cv::Mat top_view_rgb; 00482 getDepthImage(cloud, last_depth); 00483 00484 00485 IplImage ipl_mask(last_depth); 00486 00487 sensor_msgs::ImagePtr img_msg = sensor_msgs::CvBridge::cvToImgMsg(&ipl_mask); 00488 img_msg->header.frame_id = _cam_info_new->header.frame_id; 00489 img_msg->header.stamp = ros::Time::now(); 00490 res.depth_image = *img_msg; 00491 00492 00493 return true; 00494 00495 } 00496 00497 00498 bool getDepthImage(pcl::PointCloud<Point>::Ptr cloud_in, cv::Mat& depth_image_new){ 00499 00500 00501 00502 00503 pcl::PointCloud<Point>::Ptr cloud(new pcl::PointCloud<Point>() ); 00504 pcl::PassThrough<Point> pass; 00505 pass.setInputCloud (cloud_in); 00506 pass.setFilterFieldName ("x"); 00507 pass.setFilterLimits (-5.0, 5.0); 00508 //pass.setFilterLimitsNegative (true); 00509 pass.filter (*cloud); 00510 00511 00512 //get self mask 00513 // camera_self_filter::mask servicecall; 00514 // servicecall.request.header.frame_id = cloud.header.frame_id; 00515 // servicecall.request.header.stamp = cloud.header.stamp; 00516 // _self_mask_client.call(servicecall); 00517 // sensor_msgs::ImageConstPtr selfMaskPtr = boost::make_shared<sensor_msgs::Image>(servicecall.response.mask_image); 00518 // IplImage* ipl_self = _bridge.imgMsgToCv(selfMaskPtr, "passthrough"); 00519 // cv::Mat temp(ipl_self); 00520 // cv::Mat self_mask = temp.clone(); 00521 00522 //get all transforms 00523 00524 00525 tf::StampedTransform tf_realcam_in_base; 00526 00527 listener_.waitForTransform(_cam_info_new->header.frame_id , cloud->header.frame_id, ros::Time(0), ros::Duration(5.0)); 00528 listener_.lookupTransform(_cam_info_new->header.frame_id, cloud->header.frame_id, ros::Time(0), tf_realcam_in_base); 00529 cout<<"_cam_info_new->header.frame_id "<<_cam_info_new->header.frame_id<<endl; 00530 cout<<"cloud->header.frame_id "<<cloud->header.frame_id<<endl; 00531 // listener_.lookupTransform( cloud_msg->header.frame_id, base_frame, ros::Time(0), tf_realcam_in_base); 00532 00533 00534 00535 //transform cloud into baselink 00536 pcl::PointCloud<Point> cloud_in_virt_cam; 00537 00538 tf::Transform& full_tf = tf_realcam_in_base; 00539 // tf::Transform full_tf = tf_realcam_in_base; 00540 00541 cout<<"full_tf"<<endl<<full_tf<<endl; 00542 00543 Eigen::Affine3d transform_eigen; 00544 tf::TransformTFToEigen(full_tf,transform_eigen ); 00545 Eigen::Matrix4d transform_eigen3(transform_eigen.matrix()); 00546 Eigen::Matrix4f transform_eigen3f = transform_eigen3.cast<float>(); 00547 pcl::transformPointCloud( *cloud, cloud_in_virt_cam, transform_eigen3f ); 00548 00549 00550 00551 00552 00553 00554 // cloud_in_virt_cam.header.frame_id = base_frame; 00555 cloud_in_virt_cam.header.frame_id = _cam_info_new->header.frame_id; 00556 cloud_in_virt_cam.header.stamp = cloud->header.stamp; 00557 00558 00559 00560 //project 00561 00562 //all 00563 cv::Mat mask = cv::Mat::zeros(cv::Size(_cam_info_new->width, _cam_info_new->height), CV_32F); 00564 mask.setTo(numeric_limits<float>::max()); 00565 00566 sensor_msgs::ImageConstPtr imgp = ros::topic::waitForMessage<sensor_msgs::Image>("/prosilica/image_rect_color", ros::Duration(5.0)); 00567 sensor_msgs::CvBridge bridge_mask; 00568 IplImage* iplimagemask = bridge_mask.imgMsgToCv(imgp, "passthrough"); 00569 cv::Mat maskRGB(iplimagemask); 00570 00571 // cv::Mat maskRGB = cv::Mat::zeros(cv::Size(_cam_info_new->width, _cam_info_new->height), CV_8UC3); 00572 ROS_INFO("picel_coords %f %f %f", cloud->points[0].x, cloud->points[0].y,cloud->points[0].z ); 00573 vector<Point, Eigen::aligned_allocator<Point> >::iterator iter; 00574 for (iter = cloud_in_virt_cam.points.begin(); iter != cloud_in_virt_cam.points.end(); ++iter){ 00575 Point& point = *iter; 00576 00577 if (isnan(point.x) || isnan(point.y) || isnan(point.z)) 00578 continue; 00579 cv::Point3d p3d(point.x, point.y, point.z); 00580 cv::Point2d p2d; 00581 _model_new.project3dToPixel(p3d, p2d); 00582 int x = round(p2d.x); 00583 int y = round(p2d.y); 00584 if((x>mask.cols-1) || (x<0) || (y>mask.rows-1) || (y<0)) 00585 continue; 00586 float& current_val = mask.at<float>(y,x); 00587 if(point.z < current_val ){ 00588 00589 mask.at<float>(y,x) = point.z; 00590 int dist_index = int((point.z - 0.5) * 300); //goes till 256cm 00591 if (dist_index > 255) dist_index = 0; 00592 cv::circle(maskRGB, cv::Point(x,y), 1, cv::Scalar(colormap[3*dist_index], colormap[3*dist_index+1], colormap[3*dist_index+2] ), -1); 00593 00594 } 00595 00596 // maskRGB.at<unsigned char>(y, 3 * x) = point.b; 00597 // maskRGB.at<unsigned char>(y, 3 * x + 1) = point.g; 00598 // maskRGB.at<unsigned char>(y, 3 * x + 2) = point.r; 00599 } 00600 00601 00602 00603 std::vector<boost::shared_ptr<cv::Mat> > dilations; 00604 dilations.push_back(boost::make_shared<cv::Mat>(mask)); 00605 00606 cv::namedWindow("dils", 0); 00607 for (int i = 1 ; i<num_max_dilations; i++){ 00608 cv::Mat new_dil; 00609 cv::morphologyEx(*(dilations[i-1]),new_dil,CV_MOP_ERODE , getStructuringElement(cv::MORPH_ELLIPSE, cv::Size(3,3)), cv::Point(-1,-1), 1); 00610 dilations.push_back(boost::make_shared<cv::Mat>(new_dil)); 00611 cv::imshow("dils", new_dil); 00612 cv::waitKey(); 00613 } 00614 00615 00616 cv::Mat mask_new = cv::Mat::zeros(cv::Size(_cam_info_new->width, _cam_info_new->height), CV_32F); 00617 for (int y = 0; y<mask_new.rows; y++){ 00618 for(int x = 0; x<mask_new.cols; x++){ 00619 int i = 0; 00620 while( i<dilations.size()){ 00621 float& val = dilations[i]->at<float>(y,x); 00622 if (val < numeric_limits<float>::max()){ 00623 mask_new.at<float>(y,x) = val; 00624 break; 00625 } 00626 i++; 00627 } 00628 } 00629 } 00630 00631 depth_image_new = mask_new; 00632 00633 00634 00635 00636 #if X_OUTPUT 00637 00638 cv::namedWindow("test", 0); 00639 cv::waitKey(); 00640 00641 cv::imshow("test", maskRGB); 00642 00643 cv::waitKey(); 00644 00645 00646 cv::imshow("test", mask_new); 00647 00648 cv::waitKey(); 00649 00650 #endif 00651 00652 00653 // cv::morphologyEx(mask_object_tops,mask_object_tops,CV_MOP_CLOSE , getStructuringElement(cv::MORPH_RECT, cv::Size(3,3)), cv::Point(-1,-1), 3); 00654 // cv::dilate(mask_object_tops,mask_object_tops,getStructuringElement(cv::MORPH_RECT, cv::Size(5,5)) ); 00655 // cv::erode(mask_object_tops, mask_object_tops, cv::Mat(), cv::Point(-1, -1), 3 ); 00656 00657 00658 00659 00660 00661 00662 } 00663 00664 bool estimateRigidTransform2DRansacCB(pr2_interactive_segmentation::estimateRigid::Request& req, pr2_interactive_segmentation::estimateRigid::Response& res){ 00665 00666 std::vector<cv::Point2d> features_old, features_new; 00667 printf("from msg features old size %d features new size %d \n", req.features_old.size(), req.features_new.size()); 00668 features_old.reserve(req.features_old.size()); 00669 features_new.reserve(req.features_new.size()); 00670 for (int i = 0; i < req.features_old.size(); i++){ 00671 cv::Point2d p2d(req.features_old[i].x, req.features_old[i].y); 00672 features_old.push_back(p2d); 00673 } 00674 00675 for (int i = 0; i < req.features_new.size(); i++){ 00676 cv::Point2d p2d(req.features_new[i].x, req.features_new[i].y); 00677 features_new.push_back(p2d); 00678 } 00679 00680 00681 00682 00683 sensor_msgs::PointCloud2ConstPtr cloud_msg = ros::topic::waitForMessage<sensor_msgs::PointCloud2>(point_cloud_topic, ros::Duration(5.0)); 00684 pcl::PointCloud<Point>::Ptr cloud(new pcl::PointCloud<Point>()); 00685 pcl::fromROSMsg<Point>(*cloud_msg, *cloud); 00686 00687 cv::Mat new_depth; 00688 getDepthImage(cloud, new_depth); 00689 00690 std::vector<int> inliers; 00691 int success = estimateRigidTransform2DRansac(features_old, features_new, last_depth, new_depth, cloud_msg->header.frame_id, inliers, 5.0 ); 00692 00693 res.inliers = inliers; 00694 res.success = success; 00695 00696 return true; 00697 00698 } 00699 00700 00701 int estimateRigidTransform2DRansac(std::vector<cv::Point2d>& features_old, std::vector<cv::Point2d>& features_new, 00702 cv::Mat& depth_image_old, cv::Mat& depth_image_new, std::string depth_frame, std::vector<int>& inliers, float residual_error ){ 00703 assert(features_old.size() == features_new.size()); 00704 pcl::PointCloud<Point> cloud_old_features, cloud_new_features, cloud_old_features_table, cloud_new_features_table; 00705 cloud_old_features.points.reserve(features_old.size()); 00706 cloud_new_features.points.reserve(features_new.size()); 00707 for (int i=0; i < features_old.size(); i++){ 00708 cv::Point3d p3d = _model_new.projectPixelTo3dRay(features_old[i]); 00709 double z = depth_image_old.at<float>(features_old[i]); 00710 assert(p3d.z == 1.0); 00711 p3d *= z; 00712 Point p(p3d.x, p3d.y, p3d.z); 00713 cloud_old_features.points.push_back(p); 00714 } 00715 00716 for (int i=0; i < features_new.size(); i++){ 00717 cv::Point3d p3d = _model_new.projectPixelTo3dRay(features_new[i]); 00718 double z = depth_image_new.at<float>(features_new[i]); 00719 assert(p3d.z == 1.0); 00720 p3d *= z; 00721 Point p(p3d.x, p3d.y, p3d.z); 00722 cloud_new_features.points.push_back(p); 00723 } 00724 00725 //transform pointcloud into virtual frame 00726 tf::StampedTransform tf_realcam_in_base; 00727 00728 listener_.waitForTransform(base_frame, _cam_info_new->header.frame_id , ros::Time(0), ros::Duration(5.0)); 00729 listener_.lookupTransform(base_frame, _cam_info_new->header.frame_id, ros::Time(0), tf_realcam_in_base); 00730 00731 tf::Transform full_tf = tf_virtual_cam.inverse() * tf_virtual_cam_transl.inverse() * tf_realcam_in_base; 00732 Eigen::Affine3d transform_eigen; 00733 tf::TransformTFToEigen(full_tf,transform_eigen ); 00734 Eigen::Matrix4d transform_eigen3(transform_eigen.matrix()); 00735 Eigen::Matrix4f transform_eigen3f = transform_eigen3.cast<float>(); 00736 00737 00738 pcl::transformPointCloud( cloud_old_features, cloud_old_features_table, transform_eigen3f ); 00739 pcl::transformPointCloud( cloud_new_features, cloud_new_features_table, transform_eigen3f ); 00740 00741 00742 //project 00743 00744 00745 cv::Mat old_features_transformed (features_old.size(), 1, CV_32FC2); 00746 cv::Mat new_features_transformed (features_new.size(), 1, CV_32FC2); 00747 00748 vector<Point, Eigen::aligned_allocator<Point> >::iterator iter; 00749 int i = 0; 00750 for (iter = cloud_old_features_table.points.begin(); iter != cloud_old_features_table.points.end(); ++iter){ 00751 Point& point = *iter; 00752 00753 if (isnan(point.x) || isnan(point.y) || isnan(point.z)) 00754 continue; 00755 cv::Point3d p3d(point.x, point.y, point.z); 00756 cv::Point2d p2d; 00757 _model_new.project3dToPixel(p3d, p2d); 00758 // old_features_transformed.at<float>(i,0,0) = p2d.x; 00759 // old_features_transformed.at<float>(i,0,1) = p2d.y; 00760 old_features_transformed.ptr<float>()[i * 2 ] = p2d.x; 00761 old_features_transformed.ptr<float>()[i * 2 +1] = p2d.y; 00762 i++; 00763 } 00764 i = 0; 00765 00766 for (iter = cloud_new_features_table.points.begin(); iter != cloud_new_features_table.points.end(); ++iter){ 00767 Point& point = *iter; 00768 00769 if (isnan(point.x) || isnan(point.y) || isnan(point.z)) 00770 continue; 00771 cv::Point3d p3d(point.x, point.y, point.z); 00772 cv::Point2d p2d; 00773 _model_new.project3dToPixel(p3d, p2d); 00774 // new_features_transformed.at<float>(i,0,0) = p2d.x; 00775 // new_features_transformed.at<float>(i,0,1) = p2d.y; 00776 new_features_transformed.ptr<float>()[i * 2] = p2d.x; 00777 new_features_transformed.ptr<float>()[i *2 +1] = p2d.y; 00778 i++; 00779 } 00780 00781 cv::Mat M; 00782 00783 int success = cv::estimateRigidTransform(old_features_transformed, new_features_transformed, M, false, inliers); 00784 if (!success){ 00785 ROS_ERROR("rigid estimation failed!!!!!!!!"); 00786 } 00787 00788 return success; 00789 00790 } 00791 00792 00793 00794 }; 00795 00796 00797 unsigned char DepthTransfomer::colormap[768] = 00798 { 150, 150, 150, 00799 107, 0, 12, 00800 106, 0, 18, 00801 105, 0, 24, 00802 103, 0, 30, 00803 102, 0, 36, 00804 101, 0, 42, 00805 99, 0, 48, 00806 98, 0, 54, 00807 97, 0, 60, 00808 96, 0, 66, 00809 94, 0, 72, 00810 93, 0, 78, 00811 92, 0, 84, 00812 91, 0, 90, 00813 89, 0, 96, 00814 88, 0, 102, 00815 87, 0, 108, 00816 85, 0, 114, 00817 84, 0, 120, 00818 83, 0, 126, 00819 82, 0, 131, 00820 80, 0, 137, 00821 79, 0, 143, 00822 78, 0, 149, 00823 77, 0, 155, 00824 75, 0, 161, 00825 74, 0, 167, 00826 73, 0, 173, 00827 71, 0, 179, 00828 70, 0, 185, 00829 69, 0, 191, 00830 68, 0, 197, 00831 66, 0, 203, 00832 65, 0, 209, 00833 64, 0, 215, 00834 62, 0, 221, 00835 61, 0, 227, 00836 60, 0, 233, 00837 59, 0, 239, 00838 57, 0, 245, 00839 56, 0, 251, 00840 55, 0, 255, 00841 54, 0, 255, 00842 52, 0, 255, 00843 51, 0, 255, 00844 50, 0, 255, 00845 48, 0, 255, 00846 47, 0, 255, 00847 46, 0, 255, 00848 45, 0, 255, 00849 43, 0, 255, 00850 42, 0, 255, 00851 41, 0, 255, 00852 40, 0, 255, 00853 38, 0, 255, 00854 37, 0, 255, 00855 36, 0, 255, 00856 34, 0, 255, 00857 33, 0, 255, 00858 32, 0, 255, 00859 31, 0, 255, 00860 29, 0, 255, 00861 28, 0, 255, 00862 27, 0, 255, 00863 26, 0, 255, 00864 24, 0, 255, 00865 23, 0, 255, 00866 22, 0, 255, 00867 20, 0, 255, 00868 19, 0, 255, 00869 18, 0, 255, 00870 17, 0, 255, 00871 15, 0, 255, 00872 14, 0, 255, 00873 13, 0, 255, 00874 11, 0, 255, 00875 10, 0, 255, 00876 9, 0, 255, 00877 8, 0, 255, 00878 6, 0, 255, 00879 5, 0, 255, 00880 4, 0, 255, 00881 3, 0, 255, 00882 1, 0, 255, 00883 0, 4, 255, 00884 0, 10, 255, 00885 0, 16, 255, 00886 0, 22, 255, 00887 0, 28, 255, 00888 0, 34, 255, 00889 0, 40, 255, 00890 0, 46, 255, 00891 0, 52, 255, 00892 0, 58, 255, 00893 0, 64, 255, 00894 0, 70, 255, 00895 0, 76, 255, 00896 0, 82, 255, 00897 0, 88, 255, 00898 0, 94, 255, 00899 0, 100, 255, 00900 0, 106, 255, 00901 0, 112, 255, 00902 0, 118, 255, 00903 0, 124, 255, 00904 0, 129, 255, 00905 0, 135, 255, 00906 0, 141, 255, 00907 0, 147, 255, 00908 0, 153, 255, 00909 0, 159, 255, 00910 0, 165, 255, 00911 0, 171, 255, 00912 0, 177, 255, 00913 0, 183, 255, 00914 0, 189, 255, 00915 0, 195, 255, 00916 0, 201, 255, 00917 0, 207, 255, 00918 0, 213, 255, 00919 0, 219, 255, 00920 0, 225, 255, 00921 0, 231, 255, 00922 0, 237, 255, 00923 0, 243, 255, 00924 0, 249, 255, 00925 0, 255, 255, 00926 0, 255, 249, 00927 0, 255, 243, 00928 0, 255, 237, 00929 0, 255, 231, 00930 0, 255, 225, 00931 0, 255, 219, 00932 0, 255, 213, 00933 0, 255, 207, 00934 0, 255, 201, 00935 0, 255, 195, 00936 0, 255, 189, 00937 0, 255, 183, 00938 0, 255, 177, 00939 0, 255, 171, 00940 0, 255, 165, 00941 0, 255, 159, 00942 0, 255, 153, 00943 0, 255, 147, 00944 0, 255, 141, 00945 0, 255, 135, 00946 0, 255, 129, 00947 0, 255, 124, 00948 0, 255, 118, 00949 0, 255, 112, 00950 0, 255, 106, 00951 0, 255, 100, 00952 0, 255, 94, 00953 0, 255, 88, 00954 0, 255, 82, 00955 0, 255, 76, 00956 0, 255, 70, 00957 0, 255, 64, 00958 0, 255, 58, 00959 0, 255, 52, 00960 0, 255, 46, 00961 0, 255, 40, 00962 0, 255, 34, 00963 0, 255, 28, 00964 0, 255, 22, 00965 0, 255, 16, 00966 0, 255, 10, 00967 0, 255, 4, 00968 2, 255, 0, 00969 8, 255, 0, 00970 14, 255, 0, 00971 20, 255, 0, 00972 26, 255, 0, 00973 32, 255, 0, 00974 38, 255, 0, 00975 44, 255, 0, 00976 50, 255, 0, 00977 56, 255, 0, 00978 62, 255, 0, 00979 68, 255, 0, 00980 74, 255, 0, 00981 80, 255, 0, 00982 86, 255, 0, 00983 92, 255, 0, 00984 98, 255, 0, 00985 104, 255, 0, 00986 110, 255, 0, 00987 116, 255, 0, 00988 122, 255, 0, 00989 128, 255, 0, 00990 133, 255, 0, 00991 139, 255, 0, 00992 145, 255, 0, 00993 151, 255, 0, 00994 157, 255, 0, 00995 163, 255, 0, 00996 169, 255, 0, 00997 175, 255, 0, 00998 181, 255, 0, 00999 187, 255, 0, 01000 193, 255, 0, 01001 199, 255, 0, 01002 205, 255, 0, 01003 211, 255, 0, 01004 217, 255, 0, 01005 223, 255, 0, 01006 229, 255, 0, 01007 235, 255, 0, 01008 241, 255, 0, 01009 247, 255, 0, 01010 253, 255, 0, 01011 255, 251, 0, 01012 255, 245, 0, 01013 255, 239, 0, 01014 255, 233, 0, 01015 255, 227, 0, 01016 255, 221, 0, 01017 255, 215, 0, 01018 255, 209, 0, 01019 255, 203, 0, 01020 255, 197, 0, 01021 255, 191, 0, 01022 255, 185, 0, 01023 255, 179, 0, 01024 255, 173, 0, 01025 255, 167, 0, 01026 255, 161, 0, 01027 255, 155, 0, 01028 255, 149, 0, 01029 255, 143, 0, 01030 255, 137, 0, 01031 255, 131, 0, 01032 255, 126, 0, 01033 255, 120, 0, 01034 255, 114, 0, 01035 255, 108, 0, 01036 255, 102, 0, 01037 255, 96, 0, 01038 255, 90, 0, 01039 255, 84, 0, 01040 255, 78, 0, 01041 255, 72, 0, 01042 255, 66, 0, 01043 255, 60, 0, 01044 255, 54, 0, 01045 255, 48, 0, 01046 255, 42, 0, 01047 255, 36, 0, 01048 255, 30, 0, 01049 255, 24, 0, 01050 255, 18, 0, 01051 255, 12, 0, 01052 255, 6, 0, 01053 255, 0, 0, 01054 }; 01055 01056 int main(int argc, char** argv){ 01057 01058 ros::init(argc, argv, "depth_transformer_node"); 01059 // ros::NodeHandle nh; 01060 // ros::Duration(1.5).sleep(); 01061 01062 DepthTransfomer hcs; 01063 ros::spin(); 01064 01065 return 0; 01066 } 01067