00001 class FlowClustering
00002 {
00003 public:
00004 FlowClustering(FeatureTracker* ft,
00005 int kmeans_max_iter=200, double kmeans_epsilon=0.5,
00006 int kmeans_tries=5, int affine_estimate_radius=5,
00007 double surf_hessian=100) :
00008 ft_(ft),
00009 kmeans_max_iter_(kmeans_max_iter), kmeans_epsilon_(kmeans_epsilon),
00010 kmeans_tries_(kmeans_tries),
00011 affine_estimate_radius_(affine_estimate_radius)
00012 {
00013
00014 cv::getDerivKernels(dy_kernel_, dx_kernel_, 1, 0, CV_SCHARR, true, CV_32F);
00015 cv::flip(dy_kernel_, dy_kernel_, -1);
00016 cv::transpose(dy_kernel_, dx_kernel_);
00017 }
00018
00019 AffineFlowMeasures clusterFlowFields(cv::Mat& color_img, cv::Mat& depth_img,
00020 cv::Mat& u, cv::Mat& v, cv::Mat& mask)
00021 {
00022
00023 return clusterSparseFlowKMeans(color_img, depth_img, u, v, mask);
00024 }
00025
00026 AffineFlowMeasures clusterFlowFieldsKMeans(cv::Mat& color_img,
00027 cv::Mat& depth_img,
00028 cv::Mat& u, cv::Mat& v,
00029 cv::Mat& mask)
00030 {
00031
00032 AffineFlowMeasures points;
00033 points.clear();
00034 for (int r = 0; r < mask.rows; ++r)
00035 {
00036 uchar* mask_row = mask.ptr<uchar>(r);
00037 for (int c = 0; c < mask.cols; ++c)
00038 {
00039 if ( mask_row[c] > 0)
00040 {
00041 AffineFlowMeasure p;
00042 p.u = u.at<float>(r,c);
00043 p.v = v.at<float>(r,c);
00044 p.x = c;
00045 p.y = r;
00046 p.a = estimateAffineTransform(u, v, r, c, affine_estimate_radius_);
00047 if (std::sqrt(p.u*p.u+p.v*p.v) > 1.0 )
00048 points.push_back(p);
00049 }
00050 }
00051 }
00052
00053 if (points.size() < 1)
00054 {
00055 AffineFlowMeasures cluster_centers;
00056 cluster_centers.clear();
00057 return cluster_centers;
00058 }
00059 AffineFlowMeasures cluster_centers = clusterAffineKMeans(color_img, u, v,
00060 points);
00061 return cluster_centers;
00062 }
00063
00064 AffineFlowMeasures clusterFlowFieldsRANSAC(cv::Mat& color_img,
00065 cv::Mat& depth_img,
00066 cv::Mat& u, cv::Mat& v,
00067 cv::Mat& mask)
00068 {
00069 AffineFlowMeasures points;
00070 for (int r = 0; r < mask.rows; ++r)
00071 {
00072 uchar* mask_row = mask.ptr<uchar>(r);
00073 for (int c = 0; c < mask.cols; ++c)
00074 {
00075 if ( mask_row[c] > 0)
00076 {
00077 AffineFlowMeasure p;
00078 p.u = u.at<float>(r,c);
00079 p.v = v.at<float>(r,c);
00080 p.x = c;
00081 p.y = r;
00082 if (std::sqrt(p.u*p.u+p.v*p.v) > 1.0 )
00083 points.push_back(p);
00084 }
00085 }
00086 }
00087
00088 AffineFlowMeasures cluster_centers;
00089 if (points.size() < 1)
00090 {
00091 cluster_centers.clear();
00092 return cluster_centers;
00093 }
00094
00095
00096
00097 int k = 0;
00098 AffineFlowMeasures active_points = points;
00099 while (active_points.size() > min_affine_point_set_size_ &&
00100 k < max_k_)
00101 {
00102 AffineFlowMeasures inliers;
00103 inliers.clear();
00104 cv::Mat new_estimate = affineRANSAC(active_points, inliers,
00105 ransac_inlier_percent_est_,
00106 ransac_epsilon_, max_ransac_iters_);
00107 AffineFlowMeasure new_center;
00108 new_center.a = new_estimate;
00109 new_center.label = k;
00110 new_center.x = 0;
00111 new_center.y = 0;
00112 for (unsigned int i = 0; i < inliers.size(); ++i)
00113 {
00114 new_center.x += inliers[i].x;
00115 new_center.y += inliers[i].y;
00116
00117
00118 for (unsigned int j = 0; j < points.size(); ++j)
00119 {
00120 if (points[j] == inliers[i])
00121 {
00122 points[j].label = k;
00123 }
00124 }
00125
00126 for (unsigned int j = 0; j < active_points.size(); )
00127 {
00128 if (inliers[i] == active_points[j])
00129 {
00130 active_points.erase(active_points.begin()+j);
00131 }
00132 else
00133 {
00134 ++j;
00135 }
00136 }
00137 }
00138 if (inliers.size() > 0)
00139 {
00140 new_center.x /= inliers.size();
00141 new_center.y /= inliers.size();
00142 cv::Mat V = new_center.a*new_center.X();
00143 new_center.u = V.at<float>(0,0);
00144 new_center.v = V.at<float>(1,0);
00145 }
00146 else
00147 {
00148 new_center.x = 0;
00149 new_center.y = 0;
00150 new_center.u = 0;
00151 new_center.v = 0;
00152 }
00153 cluster_centers.push_back(new_center);
00154 ROS_INFO_STREAM("Fit affine transform " << k << " with center ("
00155 << new_center.x << ", " << new_center.y << ")");
00156 ROS_INFO_STREAM("Number of points remaining: " << active_points.size());
00157 ++k;
00158 }
00159
00160 #ifdef DISPLAY_FLOW_FIELD_CLUSTERING
00161
00162 displayClusterCenters(cluster_centers, points, color_img);
00163
00164 #endif // DISPLAY_FLOW_FIELD_CLUSTERING
00165
00166 return cluster_centers;
00167 }
00168
00169 AffineFlowMeasures clusterSparseFlowKMeans(cv::Mat& color_img,
00170 cv::Mat& depth_img,
00171 cv::Mat& u, cv::Mat& v,
00172 cv::Mat& mask)
00173 {
00174 cv::Mat img_bw;
00175 cv::cvtColor(color_img, img_bw, CV_BGR2GRAY);
00176
00177 AffineFlowMeasures sparse_flow = ft_->getMostRecentFlow();
00178
00179
00180
00181
00182 for (unsigned int i = 0; i < sparse_flow.size(); ++i)
00183 {
00184 sparse_flow[i].a = estimateAffineTransform(u, v, sparse_flow[i].y,
00185 sparse_flow[i].x,
00186 affine_estimate_radius_);
00187 }
00188 AffineFlowMeasures cluster_centers;
00189 if (sparse_flow.size() < 2)
00190 {
00191 cluster_centers.clear();
00192 return cluster_centers;
00193 }
00194 cluster_centers = clusterAffineKMeans(color_img, u, v, sparse_flow);
00195 return cluster_centers;
00196 }
00197
00198 AffineFlowMeasures clusterSparseFlowRANSAC(cv::Mat& color_img,
00199 cv::Mat& depth_img,
00200 cv::Mat& u, cv::Mat& v,
00201 cv::Mat& mask)
00202 {
00203 return clusterSparseFlowKMeans(color_img, depth_img, u, v, mask);
00204 }
00205
00206
00207
00208
00209
00210 AffineFlowMeasures clusterAffineKMeans(cv::Mat& color_img, cv::Mat& u,
00211 cv::Mat& v, AffineFlowMeasures& points)
00212 {
00213 const int num_samples = points.size();
00214 const int r_scale = color_img.cols / 2;
00215
00216 const int num_sample_elements = 8;
00217
00218
00219 cv::Mat samples(num_samples, num_sample_elements, CV_32FC1);
00220 for (unsigned int i = 0; i < points.size(); ++i)
00221 {
00222 AffineFlowMeasure p = points[i];
00223
00224
00225 samples.at<float>(i, 0) = p.a.at<float>(0,0)*r_scale;
00226 samples.at<float>(i, 1) = p.a.at<float>(0,1)*r_scale;
00227 samples.at<float>(i, 2) = p.a.at<float>(0,2);
00228 samples.at<float>(i, 3) = p.a.at<float>(1,0)*r_scale;
00229 samples.at<float>(i, 4) = p.a.at<float>(1,1)*r_scale;
00230 samples.at<float>(i, 5) = p.a.at<float>(1,2);
00231 samples.at<float>(i, 6) = p.x;
00232 samples.at<float>(i, 7) = p.y;
00233 }
00234
00235 std::vector<cv::Mat> labels;
00236 std::vector<cv::Mat> centers;
00237 double compactness[max_k_];
00238 cv::TermCriteria term_crit(CV_TERMCRIT_EPS + CV_TERMCRIT_ITER,
00239 kmeans_max_iter_, kmeans_epsilon_);
00240
00241 AffineFlowMeasures cluster_centers;
00242 AffineFlowMeasures fewer_centers;
00243 AffineFlowMeasures best_centers;
00244 for (int K = 1; K <= min(max_k_, num_samples); ++K)
00245 {
00246
00247 cv::Mat labels_k;
00248 cv::Mat centers_k;
00249 double slack = cv::kmeans(samples, K, labels_k, term_crit,
00250 kmeans_tries_, cv::KMEANS_PP_CENTERS,
00251 centers_k);
00252 compactness[K-1] = slack;
00253 labels.push_back(labels_k);
00254 centers.push_back(centers_k);
00255 cluster_centers.clear();
00256
00257 for (int c = 0; c < K; ++c)
00258 {
00259 AffineFlowMeasure new_center;
00260 new_center.x = 0;
00261 new_center.y = 0;
00262 new_center.label = c;
00263 int num_members = 0;
00264 for (int i = 0; i < num_samples; ++i)
00265 {
00266 if (labels[K-1].at<uchar>(i,0) == c)
00267 {
00268 new_center.x += points[i].x;
00269 new_center.y += points[i].y;
00270 points[i].label = c;
00271 ++num_members;
00272 }
00273 }
00274
00275 if (num_members <= 0 ||
00276 centers[K-1].cols == 0 || centers[K-1].rows == 0)
00277 {
00278 new_center.x = 0;
00279 new_center.y = 0;
00280 new_center.u = 0;
00281 new_center.v = 0;
00282 }
00283 else
00284 {
00285 new_center.x = new_center.x/num_members;
00286 new_center.y = new_center.y/num_members;
00287
00288
00289
00290
00291 new_center.a.create(2, 3, CV_32FC1);
00292 new_center.a.at<float>(0,0) = centers[K-1].at<float>(c,0) / r_scale;;
00293 new_center.a.at<float>(0,1) = centers[K-1].at<float>(c,1) / r_scale;;
00294 new_center.a.at<float>(0,2) = centers[K-1].at<float>(c,2);
00295 new_center.a.at<float>(1,0) = centers[K-1].at<float>(c,3) / r_scale;;
00296 new_center.a.at<float>(1,1) = centers[K-1].at<float>(c,4) / r_scale;;
00297 new_center.a.at<float>(1,2) = centers[K-1].at<float>(c,5);
00298
00299
00300 cv::Mat V = new_center.a*new_center.X();
00301 new_center.u = V.at<float>(0,0);
00302 new_center.v = V.at<float>(1,0);
00303 }
00304 cluster_centers.push_back(new_center);
00305 }
00306
00307 if (K > 1)
00308 {
00309 float farthest_nearest_neighbor = 0;
00310 for (unsigned int i = 0; i < cluster_centers.size(); ++i)
00311 {
00312 float nn = FLT_MAX;
00313 for (unsigned int j = 0; j < fewer_centers.size(); ++j)
00314 {
00315 float dist = cluster_centers[i] - fewer_centers[j];
00316 if (dist < nn)
00317 nn = dist;
00318 }
00319 if (nn > farthest_nearest_neighbor)
00320 farthest_nearest_neighbor = nn;
00321 }
00322
00323
00324 if (farthest_nearest_neighbor < minimum_new_cluster_separation_)
00325 {
00326 best_centers = fewer_centers;
00327 break;
00328 }
00329 }
00330
00331 fewer_centers = cluster_centers;
00332 best_centers = cluster_centers;
00333 }
00334 ROS_INFO_STREAM("Chose " << best_centers.size() << " clusters");
00335 #ifdef DISPLAY_FLOW_FIELD_CLUSTERING
00336 displayClusterCenters(best_centers, points, color_img, 0);
00337 #endif // DISPLAY_FLOW_FIELD_CLUSTERING
00338 return best_centers;
00339 }
00340
00341 cv::Mat estimateAffineTransform(cv::Mat& u, cv::Mat& v,
00342 const int r, const int c, const int radius)
00343 {
00344 const int r_min = max(r - radius, 0);
00345 const int r_max = min(r + radius, u.rows-1);
00346 const int c_min = max(c - radius, 0);
00347 const int c_max = min(c + radius, u.cols-1);
00348 const int r_range = r_max-r_min+1;
00349 const int c_range = c_max-c_min+1;
00350 const int num_eqs = r_range*c_range*2;
00351 cv::Mat a(6, 1, CV_32FC1, cv::Scalar(1.0));
00352 if (num_eqs < 6)
00353 {
00354 ROS_WARN_STREAM("Too few equations; num equations is: " << num_eqs);
00355 cv::Mat A = a.reshape(1, 2);
00356 return A;
00357 }
00358 cv::Mat phi(num_eqs, 6, CV_32FC1, cv::Scalar(0.0));
00359 cv::Mat V(num_eqs, 1, CV_32FC1, cv::Scalar(0.0));
00360 for (int r = r_min, out_row = 0; r <= r_max; ++r)
00361 {
00362 for (int c = c_min; c <= c_max; ++c, ++out_row)
00363 {
00364 phi.at<float>(out_row, 0) = r;
00365 phi.at<float>(out_row, 1) = c;
00366 phi.at<float>(out_row, 2) = 1.0;
00367 V.at<float>(out_row, 0) = u.at<float>(r,c);
00368 ++out_row;
00369 phi.at<float>(out_row, 3) = r;
00370 phi.at<float>(out_row, 4) = c;
00371 phi.at<float>(out_row, 5) = 1.0;
00372 V.at<float>(out_row, 0) = v.at<float>(r,c);
00373 }
00374 }
00375 try
00376 {
00377 cv::solve(phi, V, a, cv::DECOMP_SVD);
00378 }
00379 catch (cv::Exception cve)
00380 {
00381 ROS_ERROR_STREAM(cve.what());
00382 }
00383 cv::Mat A = a.reshape(1, 2);
00384 return A;
00385 }
00386
00387 cv::Mat estimateAffineTransform(AffineFlowMeasures& points)
00388 {
00389 const int num_eqs = points.size()*2;
00390 cv::Mat phi(num_eqs, 6, CV_32FC1, cv::Scalar(0.0));
00391 cv::Mat V(num_eqs, 1, CV_32FC1, cv::Scalar(0.0));
00392 cv::Mat a(6, 1, CV_32FC1, cv::Scalar(1.0));
00393 if (num_eqs < 6)
00394 {
00395 ROS_WARN_STREAM("Too few equations; num equations is: " << num_eqs);
00396 cv::Mat A = a.reshape(1, 2);
00397 return A;
00398 }
00399 for (unsigned int i = 0, out_row = 0; i < points.size(); ++i, ++out_row)
00400 {
00401 AffineFlowMeasure p = points[i];
00402 phi.at<float>(out_row, 0) = p.y;
00403 phi.at<float>(out_row, 1) = p.x;
00404 phi.at<float>(out_row, 2) = 1.0;
00405 V.at<float>(out_row, 0) = p.u;
00406 ++out_row;
00407 phi.at<float>(out_row, 3) = p.y;
00408 phi.at<float>(out_row, 4) = p.x;
00409 phi.at<float>(out_row, 5) = 1.0;
00410 V.at<float>(out_row, 0) = p.v;
00411 }
00412 cv::solve(phi, V, a, cv::DECOMP_SVD);
00413 cv::Mat A = a.reshape(1, 2);
00414 return A;
00415 }
00416
00425 float getAffineDistortion(AffineFlowMeasure f, cv::Mat A)
00426 {
00427 cv::Mat X(3, 1, CV_32FC1, cv::Scalar(1.0));
00428 X.at<float>(0,0) = f.x;
00429 X.at<float>(1,0) = f.y;
00430
00431 cv::Mat V(2, 1, CV_32FC1, cv::Scalar(1.0));
00432 V.at<float>(0,0) = f.u;
00433 V.at<float>(0,0) = f.v;
00434
00435 cv::Mat d = V - A*X;
00436 return d.at<float>(0,0)*d.at<float>(0,0)+d.at<float>(1,0)*d.at<float>(1,0);
00437 }
00438
00448 AffineFlowMeasures getAffineConsensus(AffineFlowMeasures points,
00449 cv::Mat cur_transform, float epsilon)
00450 {
00451 AffineFlowMeasures inliers;
00452 for (unsigned int i = 0; i < points.size(); ++i)
00453 {
00454 float score = getAffineDistortion(points[i], cur_transform);
00455 if (score < epsilon)
00456 {
00457 inliers.push_back(points[i]);
00458 }
00459 }
00460 return inliers;
00461 }
00462
00475 cv::Mat affineRANSAC(AffineFlowMeasures& points, AffineFlowMeasures& inliers,
00476 float inlier_percent_est, float epsilon,
00477 int max_iterations=0, int min_iterations = 2)
00478 {
00479 AffineFlowMeasures sample_points;
00480 AffineFlowMeasures cur_inliers;
00481 AffineFlowMeasures best_inliers;
00482 best_inliers.clear();
00483 bool done;
00484 int iter = 0;
00485
00486
00487 if (max_iterations == 0)
00488 {
00489
00490 const float p = 0.99;
00491
00492 const float s = 3.0f;
00493 max_iterations = log(1 - p) / log(1-pow(inlier_percent_est, s));
00494 }
00495
00496 while ( !done )
00497 {
00498
00499 sample_points.clear();
00500 for (int i = 0; i < 3; ++i)
00501 {
00502 int r_idx = (rand() % (points.size()+1));
00503 sample_points.push_back(points[r_idx]);
00504 }
00505
00506 cv::Mat cur_transform = estimateAffineTransform(sample_points);
00507 cur_inliers = getAffineConsensus(points, cur_transform, epsilon);
00508
00509 if ( best_inliers.size() < cur_inliers.size() )
00510 {
00511 best_inliers = cur_inliers;
00512 }
00513
00514 iter++;
00515 done = ((iter > min_iterations &&
00516 (static_cast<float>(best_inliers.size())/points.size() >
00517 inlier_percent_est ||
00518 best_inliers.size() > inlier_percent_est*points.size() )) ||
00519 iter > max_iterations);
00520 }
00521 inliers = best_inliers;
00522 return estimateAffineTransform(inliers);
00523 }
00524
00525
00526
00527
00528
00536 void displayClusterCenters(AffineFlowMeasures& cluster_centers,
00537 AffineFlowMeasures& samples,
00538 cv::Mat& color_img, int cur_max_k=0)
00539 {
00540 cv::Mat flow_center_disp = color_img.clone();
00541 for (unsigned int i = 0; i < cluster_centers.size(); ++i)
00542 {
00543 cv::Point pt_a(cluster_centers[i].x, cluster_centers[i].y);
00544 cv::Point pt_b(pt_a.x - cluster_centers[i].u,
00545 pt_a.y - cluster_centers[i].v);
00546 cv::circle(flow_center_disp, pt_a, 20, cv::Scalar(0,255,0));
00547 cv::line(flow_center_disp, pt_a, pt_b, cv::Scalar(0,255,0));
00548 }
00549 std::stringstream center_disp_name;
00550 center_disp_name << "Flow Cluster Centers";
00551 if (cur_max_k != 0) center_disp_name << " " << cur_max_k;
00552 cv::imshow(center_disp_name.str(), flow_center_disp);
00553 cv::Mat flow_clusters_disp = color_img.clone();
00554 std::vector<cv::Scalar> colors;
00555 for (unsigned int k = 0; k < cluster_centers.size(); ++k)
00556 {
00557 cv::Scalar rand_color;
00558 rand_color[0] = (static_cast<float>(rand()) /
00559 static_cast<float>(RAND_MAX))*255;
00560 rand_color[1] = (static_cast<float>(rand()) /
00561 static_cast<float>(RAND_MAX))*255;
00562 rand_color[2] = (static_cast<float>(rand()) /
00563 static_cast<float>(RAND_MAX))*255;
00564 colors.push_back(rand_color);
00565 }
00566 for (unsigned int i = 0; i < samples.size(); ++i)
00567 {
00568 AffineFlowMeasure s = samples[i];
00569 if (s.label < 0 || s.label > (cluster_centers.size()-1)) continue;
00570 if (std::sqrt(s.u*s.u+s.v*s.v) > 1.0)
00571 {
00572 cv::Scalar cur_color = colors[s.label];
00573 cv::line(flow_clusters_disp, cv::Point(s.x, s.y),
00574 cv::Point(s.x - s.u, s.y - s.v), cur_color);
00575 }
00576 }
00577 std::stringstream cluster_disp_name;
00578 cluster_disp_name << "Flow Clusters";
00579 if (cur_max_k != 0) cluster_disp_name << " " << cur_max_k;
00580 cv::imshow(cluster_disp_name.str(), flow_clusters_disp);
00581 }
00582
00583
00584
00585
00586 protected:
00587 cv::Mat dx_kernel_;
00588 cv::Mat dy_kernel_;
00589 cv::Mat g_kernel_;
00590 FeatureTracker* ft_;
00591 public:
00592 int kmeans_max_iter_;
00593 double kmeans_epsilon_;
00594 double ransac_epsilon_;
00595 double ransac_inlier_percent_est_;
00596 int kmeans_tries_;
00597 int max_k_;
00598 int affine_estimate_radius_;
00599 int min_affine_point_set_size_;
00600 int max_ransac_iters_;
00601 double minimum_new_cluster_separation_;
00602 };