00001
00035 #define NO_ROS 0
00036
00037 #include "cv.h"
00038 #include "highgui.h"
00039 #include <stdio.h>
00040 #include <ctype.h>
00041 #include <Eigen/Eigen>
00042 #include <assert.h>
00043 #include <iostream>
00044 #include <set>
00045 #include <opencv2/core/eigen.hpp>
00046 #include <cmath>
00047 #include <ros/ros.h>
00048 #include "sensor_msgs/Image.h"
00049 #include "cv_bridge/CvBridge.h"
00050 #include "camera_self_filter/mask.h"
00051 #include "Timer.h"
00052 #include <fstream>
00053 #include <iostream>
00054
00055
00056 using std::cout;
00057 using std::endl;
00058
00059
00060
00061
00062
00063
00064 static void
00065 icvGetRTMatrix( const CvPoint2D32f* a, const CvPoint2D32f* b,
00066 int count, CvMat* M )
00067 {
00068
00069
00070 double sa[16], sb[4], m[4], *om = M->data.db;
00071 CvMat A = cvMat( 4, 4, CV_64F, sa ), B = cvMat( 4, 1, CV_64F, sb );
00072 CvMat MM = cvMat( 4, 1, CV_64F, m );
00073
00074 int i;
00075
00076 memset( sa, 0, sizeof(sa) );
00077 memset( sb, 0, sizeof(sb) );
00078
00079 for( i = 0; i < count; i++ )
00080 {
00081 sa[0] += a[i].x*a[i].x + a[i].y*a[i].y;
00082 sa[1] += 0;
00083 sa[2] += a[i].x;
00084 sa[3] += a[i].y;
00085
00086 sa[4] += 0;
00087 sa[5] += a[i].x*a[i].x + a[i].y*a[i].y;
00088 sa[6] += -a[i].y;
00089 sa[7] += a[i].x;
00090
00091 sa[8] += a[i].x;
00092 sa[9] += -a[i].y;
00093 sa[10] += 1;
00094 sa[11] += 0;
00095
00096 sa[12] += a[i].y;
00097 sa[13] += a[i].x;
00098 sa[14] += 0;
00099 sa[15] += 1;
00100
00101 sb[0] += a[i].x*b[i].x + a[i].y*b[i].y;
00102 sb[1] += a[i].x*b[i].y - a[i].y*b[i].x;
00103 sb[2] += b[i].x;
00104 sb[3] += b[i].y;
00105 }
00106
00107 cvSolve( &A, &B, &MM, CV_SVD );
00108
00109 om[0] = om[4] = m[0];
00110 om[1] = -m[1];
00111 om[3] = m[1];
00112 om[2] = m[2];
00113 om[5] = m[3];
00114
00115 }
00116
00117
00118
00119
00120
00121 cv::Mat cvEstimateRigidTransformFrom2( const cv::Mat& A, const cv::Mat& B) {
00122 cv::Mat M = cv::Mat(2, 3, CV_64F);
00123
00124 CvPoint2D32f* a = (CvPoint2D32f*) A.data;
00125 CvPoint2D32f* b = (CvPoint2D32f*) B.data;
00126 CvMat matM = M;
00127 icvGetRTMatrix(a,b, 2, &matM);
00128 return M;
00129 }
00130
00131
00132
00133
00134
00135
00136
00137
00138 class FeatureTracker{
00139 public:
00140
00141
00142 static const int MAX_CORNERS = 500;
00143 static const double quality = 0.01;
00144 static const double min_distance = 10;
00145 static const int WIN_SIZE = 10;
00146
00147
00148 const static int num_points_to_select = 3;
00149
00150 cv::Mat vis_image;
00151 cv::Mat vis_image_orig;
00152 cv::Mat last_image;
00153 std::vector<std::vector<cv::Point2f> > corner_trajectories;
00154 std::vector<std::vector<cv::Point2f> > corner_trajectories_filtered_and_transposed;
00155
00156 Eigen::VectorXi good_corners;
00157
00158
00159 int num_tracking_steps;
00160
00161
00162 static unsigned char colormap[];
00163
00164 static const float residual_error_comp = 0.1 ;
00165
00166 FeatureTracker():num_tracking_steps(0){}
00167
00168
00169
00170
00171 std::vector<cv::Point2f> findCorners(cv::Mat& first_image, cv::Mat* mask = 0);
00172
00173
00174
00175
00176
00177 bool tracking_step(cv::Mat& new_image);
00178
00179
00180
00181
00182 bool calcResiduals(const std::vector<Eigen::Matrix3f>& RTs, const std::vector<std::vector<cv::Point2f> >& corner_trajectories_t, Eigen::VectorXf& residuals );
00183
00184 bool filterTrajectories();
00185
00189 int draw(Eigen::VectorXf& prob_dist);
00190
00191 bool selectRandomFeatures(std::vector<int>& features_idx, const Eigen::VectorXf& mask);
00192
00193
00194
00195
00196 bool generateHypothesis(const Eigen::VectorXf& mask, std::vector<Eigen::Matrix3f>& RTs );
00197
00198 bool writeClustersToFile(int& idx,cv::Point2f& feature,std::ofstream& a_file);
00199
00200
00201
00202
00203
00204 bool evluateTrajectories();
00205
00206
00207
00208
00209
00210
00211
00212 float sampleHypothesisSet(std::vector<int>& feature_assocoation);
00213
00214 };
00215
00216
00217
00218
00219 std::vector<cv::Point2f> FeatureTracker::findCorners(cv::Mat& first_image, cv::Mat* mask){
00220 num_tracking_steps = 0;
00221 cv::Mat first_image_grey;
00222 cv::cvtColor(first_image, first_image_grey, CV_BGR2GRAY);
00223 std::vector<cv::Point2f> corners;
00224 cv::goodFeaturesToTrack(first_image_grey,corners, MAX_CORNERS, quality,min_distance);
00225
00226 good_corners = Eigen::VectorXi::Ones(corners.size());
00227 cv::cornerSubPix(first_image_grey, corners, cv::Size(WIN_SIZE, WIN_SIZE), cv::Size(-1,-1), cv::TermCriteria(CV_TERMCRIT_ITER|CV_TERMCRIT_EPS,20,0.03));
00228 corner_trajectories.push_back(corners);
00229 last_image = first_image_grey;
00230
00231
00232 vis_image_orig =first_image;
00233 vis_image = vis_image_orig.clone();
00234 for (unsigned int i = 0; i< corners.size(); i++){
00235 int color_idx = ((num_tracking_steps * 11) % 256) * 3;
00236 cv::circle(vis_image, corners[i], 3, cv::Scalar(colormap[color_idx], colormap[color_idx +1], colormap[color_idx +2],0), -1);
00237 }
00238
00239 return corners;
00240 }
00241
00242
00243
00244
00245
00246 bool FeatureTracker::tracking_step(cv::Mat& new_image){
00247 num_tracking_steps++;
00248 cv::Mat new_image_grey;
00249 cv::cvtColor(new_image, new_image_grey, CV_BGR2GRAY);
00250 std::vector<cv::Point2f> new_corners;
00251 std::vector<unsigned char> status;
00252 std::vector<float> error;
00253 cv::calcOpticalFlowPyrLK(last_image, new_image_grey, corner_trajectories.back(), new_corners, status, error, cv::Size(WIN_SIZE,WIN_SIZE), 3, cv::TermCriteria(CV_TERMCRIT_ITER|CV_TERMCRIT_EPS,20,0.03));
00254
00255 last_image = new_image_grey;
00256
00257 corner_trajectories.push_back(new_corners);
00258 for (unsigned int i = 0; i< good_corners.rows(); i++){
00259 good_corners[i] = good_corners[i] & status[i];
00260 }
00261 printf("num good corners %d %d new _corner_size %d \n", good_corners.sum(), good_corners.rows(), corner_trajectories.back().size());
00262
00263
00264 vis_image_orig =new_image;
00265 vis_image = vis_image_orig.clone();
00266 std::vector<cv::Point2f>& old_corners = corner_trajectories[num_tracking_steps - 1];
00267 for (unsigned int i = 0; i< new_corners.size(); i++){
00268 if (!good_corners[i]) continue;
00269 int color_idx = ((num_tracking_steps * 11) % 256) * 3;
00270
00271
00272
00273
00274 }
00275
00276 return true;
00277
00278
00279 }
00280
00281
00282
00283
00284
00285 bool FeatureTracker::calcResiduals(const std::vector<Eigen::Matrix3f>& RTs, const std::vector<std::vector<cv::Point2f> >& corner_trajectories_t, Eigen::VectorXf& residuals ){
00286
00287 residuals = Eigen::VectorXf(corner_trajectories_t.size());
00288 for (unsigned int t = 0; t < corner_trajectories_t.size(); t++){
00289 const std::vector<cv::Point2f>& current_trajectory = corner_trajectories_t[t];
00290
00291 assert(RTs.size() == current_trajectory.size() - 1);
00292 float residual = 0;
00293 for (unsigned int c = 0; c < current_trajectory.size() - 1; c++){
00294 Eigen::Vector3f old_corner (current_trajectory[c].x, current_trajectory[c].y, 1.0);
00295 Eigen::Vector3f new_corner (current_trajectory[c+1].x, current_trajectory[c+1].y, 1.0);
00296 Eigen::Vector3f res = new_corner - (RTs[c] * old_corner);
00297
00298
00299 residual += std::max(0.0f,res.squaredNorm() - residual_error_comp);
00300
00301 }
00302 residuals[t] = residual;
00303 }
00304 return true;
00305 }
00306
00307
00308 bool FeatureTracker::filterTrajectories(){
00309
00310 std::vector<std::vector<cv::Point2f> > corner_trajectories_filtered;
00311 printf("corner_trajectories size %d corner_trajectories[0].size() %d good _corners %d\n", corner_trajectories.size(), corner_trajectories[0].size(), good_corners.rows());
00312 int num_good_features = good_corners.sum();
00313
00314
00315 for (unsigned int j=0; j < corner_trajectories.size(); j++){
00316 std::vector<cv::Point2f> features_filtered;
00317 features_filtered.reserve(num_good_features);
00318 for (unsigned int i=0; i < good_corners.rows(); i++){
00319 if (good_corners[i]){
00320 features_filtered.push_back(corner_trajectories[j][i]);
00321 }
00322 }
00323 corner_trajectories_filtered.push_back(features_filtered);
00324 }
00325
00326
00327 corner_trajectories_filtered_and_transposed.clear();
00328 corner_trajectories_filtered_and_transposed.reserve(good_corners.rows());
00329 for (unsigned int i=0; i < good_corners.rows(); i++){
00330 std::vector<cv::Point2f> features_trans;
00331 features_trans.reserve(corner_trajectories_filtered.size());
00332 for (unsigned int j=0; j < corner_trajectories_filtered.size(); j++){
00333 features_trans.push_back(corner_trajectories_filtered[j][i]);
00334 }
00335 corner_trajectories_filtered_and_transposed.push_back(features_trans);
00336 }
00337
00338 printf("corner_trajectories_filtered size %d \n", corner_trajectories_filtered.size());
00339
00340 return true;
00341
00342 }
00343
00344
00348 int FeatureTracker::draw(Eigen::VectorXf& prob_dist){
00349 float pos = (float) rand() / RAND_MAX;
00350 int idx = 0;
00351 float accumulator = 0.0f;
00352 for (;;){
00353 accumulator += prob_dist[idx];
00354 if (accumulator > pos) break;
00355 idx++;
00356 }
00357 return idx;
00358
00359 }
00360
00361
00362
00363 bool FeatureTracker::selectRandomFeatures(std::vector<int>& features_idx, const Eigen::VectorXf& mask){
00364
00365 float variance = 200.0f * 200.0f;
00366
00367
00368 int num_non_masked_elements = mask.sum();
00369 if (num_non_masked_elements < 3){
00370 printf("num non masked elements %d\n", num_non_masked_elements);
00371 return false;
00372 }
00373 int* map_array = new int[num_non_masked_elements];
00374 int counter = 0;
00375 for (int i = 0; i < mask.rows() ; i++){
00376 if (mask[i] > 0.0){
00377 map_array[counter] = i;
00378 counter++;
00379 }
00380
00381
00382 }
00383
00384
00385 int idx1 = rand() % num_non_masked_elements;
00386 Eigen::VectorXf prob_dist(num_non_masked_elements);
00387 cv::Point2f current_point = corner_trajectories_filtered_and_transposed[map_array[idx1]].back();
00388 for(int i=0; i<num_non_masked_elements; i++){
00389 if (i==idx1){
00390 prob_dist[i] = 0.0;
00391 continue;
00392 }
00393 cv::Point2f other = corner_trajectories_filtered_and_transposed[map_array[i]].back();
00394 float dist_sqr = pow((other.x - current_point.x ),2) + pow((other.y - current_point.y ),2);
00395 printf("dist sqr %d %f\n", i, dist_sqr );
00396 float dist_sqr_n = dist_sqr / variance;
00397 prob_dist[i] = exp( -0.5 * dist_sqr_n);
00398
00399 }
00400
00401 cout<<"prob_dist\n"<<prob_dist<<endl;
00402 float normalizer = prob_dist.sum();
00403
00404
00405 if (normalizer < 0.0000000001){
00406 return false;
00407 }
00408
00409 prob_dist = prob_dist / normalizer;
00410 cout<<"prob_dist_n\n"<<prob_dist<<endl;
00411 int idx2 = draw(prob_dist);
00412
00413 assert(map_array[idx1] < mask.rows());
00414 assert(map_array[idx2] < mask.rows());
00415 features_idx.clear();
00416 features_idx.push_back(map_array[idx1]);
00417 features_idx.push_back(map_array[idx2]);
00418
00419
00420 delete [] map_array;
00421 return true;
00422 }
00423
00424
00425
00426
00427
00428 bool FeatureTracker::generateHypothesis(const Eigen::VectorXf& mask, std::vector<Eigen::Matrix3f>& RTs ){
00429
00430
00431 int num_elements = mask.sum();
00432 printf("in generateHypothesis num_elements %d\n",num_elements);
00433 if (num_elements < 3) return false;
00434
00435 std::vector<int> features_idx;
00436 if (!selectRandomFeatures(features_idx, mask)) return false;
00437
00438 RTs.reserve(num_tracking_steps);
00439 printf("num_tracking_steps %d\n",num_tracking_steps);
00440 for (int i = 1; i< num_tracking_steps+1; i++){
00441 printf("step gen %d \n", i);
00442 cv::Mat new_points (features_idx.size(), 1, CV_32FC2);
00443 cv::Mat old_points (features_idx.size(), 1, CV_32FC2);
00444 for (int j = 0; j < features_idx.size(); j++){
00445 cv::Point2f& new_point = corner_trajectories_filtered_and_transposed[features_idx[j]][i];
00446 new_points.ptr<float>()[j * 2] = new_point.x;
00447 new_points.ptr<float>()[j * 2 + 1] = new_point.y;
00448 cv::Point2f& old_point = corner_trajectories_filtered_and_transposed[features_idx[j]][i-1];
00449 old_points.ptr<float>()[j * 2] = old_point.x;
00450 old_points.ptr<float>()[j * 2 + 1] = old_point.y;
00451 }
00452
00453 cv::Mat RT_cv = cvEstimateRigidTransformFrom2(old_points, new_points);
00454 Eigen::Matrix3f RT = Eigen::Matrix3f::Identity();
00455 Eigen::Matrix<float, 2,3> rt_temp;
00456 cv::cv2eigen(RT_cv, rt_temp);
00457 RT.block<2,3>(0,0) = rt_temp;
00458 RTs.push_back(RT);
00459 }
00460 cout<<"last hyp tf \n"<<RTs.back()<<endl;
00461 return true;
00462
00463
00464 }
00465
00466 bool FeatureTracker::writeClustersToFile(int& idx,cv::Point2f& feature,std::ofstream& a_file){
00467
00468
00469
00470
00471
00472 a_file<< feature.x << " " << feature.y << " " << idx << std::endl;
00473
00474
00475
00476 }
00477
00478
00479
00480
00481
00482
00483 bool FeatureTracker::evluateTrajectories(){
00484
00485 int num_samples = 15;
00486 int num_hypotheses = 10;
00487 filterTrajectories();
00488 Eigen::VectorXf scores = Eigen::VectorXf::Zero(num_samples);
00489 std::vector<std::vector<int > > feature_assocoations;
00490
00491
00492 for (int i = 0; i<num_samples; i++){
00493 std::vector<int> feature_assocoation;
00494 scores[i] = sampleHypothesisSet(feature_assocoation);
00495 feature_assocoations.push_back(feature_assocoation);
00496
00497
00498
00499
00500 }
00501
00502
00503 int best_hypthesis_set_idx;
00504 scores.minCoeff(&best_hypthesis_set_idx);
00505
00506
00507 std::vector<int>& final_feature_association = feature_assocoations[best_hypthesis_set_idx];
00508
00509 vis_image = vis_image_orig.clone();
00510
00511
00512 std::stringstream ss;
00513 ss<<ros::Time::now();
00514 std::ofstream a_file ( ss.str().c_str() );
00515
00516 for (int i = 0; i < corner_trajectories_filtered_and_transposed.size(); i++){
00517 int idx = final_feature_association[i];
00518
00519 writeClustersToFile(idx,corner_trajectories_filtered_and_transposed[i].back(),a_file);
00520
00521
00522 if (idx >= 0){
00523 cv::circle(vis_image, corner_trajectories_filtered_and_transposed[i].back(), 9, cv::Scalar( colormap[3*idx], colormap[3*idx+1], colormap[3*idx+2],0), 5);
00524
00525
00526
00527
00528 }
00529 }
00530
00531 a_file.close();
00532
00533 return true;
00534
00535 }
00536
00537
00538
00539
00540
00541
00542
00543 float FeatureTracker::sampleHypothesisSet(std::vector<int>& feature_assocoation){
00544 int num_hypotheses = 10;
00545 float mask_threshold = 80;
00546
00547 Eigen::MatrixXf residualMatrix (corner_trajectories_filtered_and_transposed.size(), num_hypotheses);
00548
00549 std::vector<std::vector<Eigen::Matrix3f> > hypothesis;
00550
00551
00552 std::vector<Eigen::Matrix3f> RTs_I;
00553 RTs_I.resize(num_tracking_steps, Eigen::Matrix3f::Identity());
00554 printf ("num_tracking_steps %d RTs_I.size() %d \n", num_tracking_steps, RTs_I.size());
00555 hypothesis.push_back(RTs_I);
00556
00557 Eigen::VectorXf mask = Eigen::VectorXf::Ones(corner_trajectories_filtered_and_transposed.size());
00558 bool points_left;
00559 int i=1;
00560 for (; i<num_hypotheses; i++){
00561 Eigen::VectorXf residuals;
00562 std::vector<Eigen::Matrix3f>& last_hypothesis = hypothesis[i-1];
00563 printf("last_hypothesis size %d\n", last_hypothesis.size());
00564
00565
00566 calcResiduals(last_hypothesis, corner_trajectories_filtered_and_transposed , residuals);
00567
00568
00569 residualMatrix.col(i-1) = residuals;
00570
00571
00572
00573
00574
00575 Eigen::VectorXf mask_bin = (residuals.array() - mask_threshold).matrix();
00576 for (int i = 0; i< mask_bin.rows(); i++){
00577 mask_bin[i] = (mask_bin[i] > 0.0f) ? 1.0f : 0.0f;
00578 }
00579
00580 Eigen::ArrayXf mask_array= mask.array();
00581 Eigen::ArrayXf mask_array_bin= mask_bin.array();
00582
00583
00584 mask = mask_array.min(mask_array_bin);
00585
00586
00587
00588 std::vector<Eigen::Matrix3f> new_hypothesis;
00589
00590
00591 points_left = generateHypothesis(mask, new_hypothesis );
00592 if (!points_left) break;
00593 printf("generated new hyp of size %d\n", new_hypothesis.size());
00594 hypothesis.push_back(new_hypothesis);
00595
00596 }
00597
00598 int& actual_num_hypothesis = i;
00599 printf("actual_num_hypothesis %d num_hypotheses %d\n", actual_num_hypothesis,num_hypotheses);
00600 if (actual_num_hypothesis == num_hypotheses){
00601 Eigen::VectorXf residuals;
00602 printf("ypothesis.back() size %d\n", hypothesis.back().size());
00603 calcResiduals(hypothesis.back(), corner_trajectories_filtered_and_transposed ,residuals );
00604
00605 residualMatrix.col(residualMatrix.cols()-1) = residuals;
00606 }else{
00607
00608 Eigen::MatrixXf residualMatrix2 = residualMatrix.block(0,0, residualMatrix.rows(), actual_num_hypothesis);
00609 residualMatrix = residualMatrix2;
00610
00611 }
00612
00613
00614 cout<<"residuals_mat \n"<<residualMatrix<<endl;
00615
00616 Eigen::VectorXf summed_residuals = residualMatrix.colwise().sum();
00617
00618 cout<<"summed_residuals \n"<<summed_residuals<<endl;
00619
00620 Eigen::VectorXf summed_residuals_per_h = Eigen::VectorXf::Zero(residualMatrix.cols());
00621
00622
00623
00624 std::vector<int> best_feature_h_idx;
00625 best_feature_h_idx.resize(corner_trajectories_filtered_and_transposed.size(),0);
00626 Eigen::VectorXf feature_per_hyp_count = Eigen::VectorXf::Ones(residualMatrix.cols());
00627 feature_per_hyp_count *= 0.0000001f;
00628 int num_outliers = 0;
00629 for (int i = 0; i < corner_trajectories_filtered_and_transposed.size(); i++){
00630 int idx;
00631 residualMatrix.row(i).minCoeff(&idx);
00632 float residual_value = residualMatrix(i,idx);
00633
00634
00635 if (mask[i] > 0.0f){
00636 num_outliers++;
00637 best_feature_h_idx[i] = -1;
00638 continue;
00639 }
00640
00641 best_feature_h_idx[i] = idx;
00642 feature_per_hyp_count[idx]++;
00643 summed_residuals_per_h[idx] += residualMatrix(i,idx);
00644
00645
00646
00647
00648
00649
00650
00655 }
00656
00657 vis_image = vis_image_orig.clone();
00658 for (int i = 0; i < corner_trajectories_filtered_and_transposed.size(); i++){
00659 int idx = best_feature_h_idx[i];
00660 if (idx >= 0 && feature_per_hyp_count[idx] > 5.1){
00661 cv::circle(vis_image, corner_trajectories_filtered_and_transposed[i].back(), 9, cv::Scalar( colormap[3*idx], colormap[3*idx+1], colormap[3*idx+2],0), 5);
00662 }else{
00663 best_feature_h_idx[i] = -1;
00664 }
00665 }
00666
00667
00668 cout<<"num feature_per_hyp_count \n"<<feature_per_hyp_count<<endl;
00669 summed_residuals.array() /= feature_per_hyp_count.array();
00670
00671 cout<<"summed_residuals \n"<<summed_residuals<<endl;
00672
00673 cout<<"summed_residuals_per_h \n"<<summed_residuals_per_h<<endl;
00674
00675 summed_residuals_per_h.array() /= feature_per_hyp_count.array();
00676 cout<<"summed_residuals_per_h \n"<<summed_residuals_per_h<<endl;
00677
00678 cout<<"total average residual error "<<summed_residuals_per_h.sum()<<endl;
00679
00680 feature_assocoation = best_feature_h_idx;
00681 float outlier_penalty = num_outliers * 100.0;
00682 printf("outlier num %d penalty %f\n", num_outliers, outlier_penalty);
00683 return summed_residuals_per_h.sum() ;
00684
00685
00686 }
00687
00688 unsigned char FeatureTracker::colormap[36] =
00689 {
00690 255,0,0,
00691 0,255,0,
00692 0,0,255,
00693 255,255,0,
00694 255,0,255,
00695 0,255,255,
00696 127,0,0,
00697 0,127,0,
00698 0,0,127,
00699 127,127,0,
00700 127,0,127,
00701 0,127,127,
00702 };
00703
00704
00705
00706
00707
00708
00709
00710
00711
00712
00713
00714
00715
00716
00717
00718
00719
00720
00721
00722
00723
00724
00725
00726
00727
00728
00729
00730
00731
00732
00733
00734
00735
00736
00737
00738
00739
00740
00741
00742
00743
00744
00745
00746
00747
00748
00749
00750
00751
00752
00753
00754
00755
00756
00757
00758
00759
00760
00761
00762
00763
00764
00765
00766
00767
00768
00769
00770
00771
00772
00773
00774
00775
00776
00777
00778
00779
00780
00781
00782
00783
00784
00785
00786
00787
00788
00789
00790
00791
00792
00793
00794
00795
00796
00797
00798
00799
00800
00801
00802
00803
00804
00805
00806
00807
00808
00809
00810
00811
00812
00813
00814
00815
00816
00817
00818
00819
00820
00821
00822
00823
00824
00825
00826
00827
00828
00829
00830
00831
00832
00833
00834
00835
00836
00837
00838
00839
00840
00841
00842
00843
00844
00845
00846
00847
00848
00849
00850
00851
00852
00853
00854
00855
00856
00857
00858
00859
00860
00861
00862
00863
00864
00865
00866
00867
00868
00869
00870
00871
00872
00873
00874
00875
00876
00877
00878
00879
00880
00881
00882
00883
00884
00885
00886
00887
00888
00889
00890
00891
00892
00893
00894
00895
00896
00897
00898
00899
00900
00901
00902
00903
00904
00905
00906
00907
00908
00909
00910
00911
00912
00913
00914
00915
00916
00917
00918
00919
00920
00921
00922
00923
00924
00925
00926
00927
00928
00929
00930
00931
00932
00933
00934
00935
00936
00937
00938
00939
00940
00941
00942
00943
00944
00945
00946
00947
00948
00949
00950
00951
00952
00953
00954
00955
00956
00957
00958
00959
00960
00961
00962
00963
00964
00965
00966
00967
00968
00969
00970
00971
00972
00973
00974
00975
00976
00977
00978
00979
00980 #if NO_ROS
00981 int main( int argc, char** argv )
00982 {
00983 if (argc == 1)
00984 {
00985 std::cerr << "Usage: " << argv[0] << " <images>" << std::endl;
00986 exit(0);
00987 }
00988 cv::namedWindow("tracker", 0);
00989 cv::namedWindow("tracker_temp", 0);
00990
00991 int num_images = argc - 1;
00992 int num_images_loaded = 0;
00993 IplImage** all_images = new IplImage*[num_images];
00994
00995
00996
00997
00998 FeatureTracker ft;
00999 all_images[0] = cvLoadImage(argv[1]);
01000 num_images_loaded++;
01001 cv::Mat img(all_images[0]);
01002 ft.findCorners(img);
01003
01004 cv::imshow("tracker", ft.vis_image);
01005 cv::waitKey();
01006
01007 int c;
01008 for (int i = 1 ; i < num_images; i++){
01009 all_images[i] = cvLoadImage(argv[i+1]);
01010 num_images_loaded++;
01011 printf("loading image %s\n", argv[i+1]);
01012 cv::Mat img(all_images[i]);
01013 ft.tracking_step(img);
01014
01015 if( (i-1) % 5 == 0){
01016 Timer t;
01017 ft.evluateTrajectories();
01018 printf("took %f secs\n", t.stop());
01019 cv::imshow("tracker", ft.vis_image);
01020 c = cvWaitKey();
01021 if( (char)c == 27 )
01022 break;
01023 }
01024
01025 }
01026
01027 for (int i = 0 ; i < num_images_loaded; i++){
01028 cvReleaseImage(&all_images[i]);
01029 }
01030 delete [] all_images;
01031
01032
01033 }
01034
01035 #else
01036
01037
01038
01039
01040
01041 int main( int argc, char** argv )
01042 {
01043
01044 ros::init(argc, argv, "image_tracker");
01045 ros::NodeHandle nh;
01046 sensor_msgs::CvBridge _bridge;
01047 cv::namedWindow("tracker", 0);
01048 cv::namedWindow("tracker_temp", 0);
01049
01050
01051 std::string input_image_topic =
01052 argc == 2 ? argv[1] : "/camera/rgb/image_color";
01053
01054 FeatureTracker ft;
01055
01056 sensor_msgs::ImageConstPtr imgmasg_ptr = ros::topic::waitForMessage<sensor_msgs::Image>("prosilica/image_rect_color", ros::Duration(5.0));
01057 IplImage* ipl_img = _bridge.imgMsgToCv(imgmasg_ptr, "passthrough");
01058 cv::Mat img(ipl_img);
01059
01060 ros::ServiceClient svc = nh.serviceClient<camera_self_filter::mask>("self_mask");
01061 camera_self_filter::mask servicecall;
01062 servicecall.request.header.frame_id = "high_def_optical_frame";
01063 servicecall.request.header.stamp = ros::Time::now();
01064 svc.call(servicecall);
01065 sensor_msgs::ImageConstPtr maskptr = boost::make_shared<sensor_msgs::Image>(boost::ref(servicecall.response.mask_image));
01066
01067 IplImage* ipl_mask = _bridge.imgMsgToCv(maskptr, "passthrough");
01068 cvDilate(ipl_mask, ipl_mask, 0, 3);
01069 cvNot(ipl_mask,ipl_mask);
01070 cv::Mat mask(ipl_mask);
01071
01072 cv::Mat ROI_mat = cv::Mat::zeros(img.rows, img.cols, CV_8U);
01073 cv::rectangle(ROI_mat, cv::Point(0,0), cv::Point(img.cols-1, 1400),cv::Scalar(255,255,255,0), -1);
01074
01075 cv::resize(mask, mask, cv::Size(img.cols, img.rows), 0, 0, CV_INTER_NN);
01076
01077 cv::bitwise_and(ROI_mat,mask, mask);
01078
01079
01080 cv::imshow("tracker", mask);
01081 cv::waitKey();
01082
01083
01084 ft.findCorners(img, &mask);
01085
01086 cv::imshow("tracker", ft.vis_image);
01087 cv::waitKey();
01088
01089 int c;
01090 for ( ; ; ){
01091
01092 sensor_msgs::ImageConstPtr imgmasg_ptr = ros::topic::waitForMessage<sensor_msgs::Image>("prosilica/image_rect_color", ros::Duration(5.0));
01093 IplImage* ipl_img = _bridge.imgMsgToCv(imgmasg_ptr, "passthrough");
01094 cv::Mat img(ipl_img);
01095 Timer t;
01096 ft.tracking_step(img);
01097 ft.evluateTrajectories();
01098 printf("took %f secs\n", t.stop());
01099 cv::imshow("tracker", ft.vis_image);
01100 c = cvWaitKey();
01101 if( (char)c == 27 )
01102 break;
01103
01104 }
01105
01106 return 0;
01107
01108 }
01109
01110
01111 #endif
01112
01113