jockey.cpp
Go to the documentation of this file.
00001 #include <anj_featurenav/jockey.h>
00002 
00003 #define GET_PARAM(prefix, type_t, name, default) \
00004   type_t name = default; \
00005   private_nh_.getParam(#prefix"/"#name, name); \
00006   ROS_DEBUG_STREAM(#prefix"/"#name": " << name);
00007 
00008 #define GET_PARAM_DETECTOR(type_t, name, default) GET_PARAM(feature_detector, type_t, name, default)
00009 #define GET_PARAM_EXTRACTOR(type_t, name, default) GET_PARAM(descriptor_extractor, type_t, name, default)
00010 #define GET_PARAM_MATCHER(type_t, name, default) GET_PARAM(descriptor_matcher, type_t, name, default)
00011 
00012 namespace anj_featurenav
00013 {
00014 
00015 Jockey::Jockey(const std::string& name) :
00016   feature_detector_type_("FAST"),
00017   descriptor_extractor_type_("BRIEF"),
00018   descriptor_matcher_type_("FlannBased"),
00019   private_nh_("~"),
00020   base_name_(name)
00021 {
00022   // Debug log level
00023   if(ros::console::set_logger_level(ROSCONSOLE_DEFAULT_NAME, ros::console::levels::Debug))
00024   {
00025     ros::console::notifyLoggerLevelsChanged();
00026   }
00027 
00028   // Initialize the feature detector.
00029   private_nh_.getParam("feature_detector/type", feature_detector_type_);
00030   ROS_DEBUG_STREAM("Feature detector type: " << feature_detector_type_);
00031 
00032   if (feature_detector_type_ == "FAST")
00033   {
00034     initDetectorFast();
00035   }
00036   else if (feature_detector_type_ == "STAR")
00037   {
00038     initDetectorStar();
00039   }
00040   else if (feature_detector_type_ == "SIFT")
00041   {
00042     throw ros::InvalidParameterException("SIFT algorithm is nonfree, cf. anj_featurenav_nonfree package");
00043   }
00044   else if (feature_detector_type_ == "SURF")
00045   {
00046     throw ros::InvalidParameterException("SURF algorithm is nonfree, cf. anj_featurenav_nonfree package");
00047   }
00048   else if (feature_detector_type_ == "ORB")
00049   {
00050     initDetectorOrb();
00051   }
00052   else if (feature_detector_type_ == "MSER")
00053   {
00054     initDetectorMser();
00055   }
00056   else if (feature_detector_type_ == "GFTT")
00057   {
00058     initDetectorGftt();
00059   }
00060   else if (feature_detector_type_ == "Dense")
00061   {
00062     initDetectorDense();
00063   }
00064   else if (feature_detector_type_ == "SimpleBlob")
00065   {
00066     initDetectorSimpleblob();
00067   }
00068   else
00069   {
00070     throw ros::InvalidParameterException(std::string("Unkown feature detection algorithm (") +
00071         feature_detector_type_ + std::string(")"));
00072   }
00073 
00074   // Initialize the descriptor (feature) extractor.
00075   private_nh_.getParam("descriptor_extractor/type", descriptor_extractor_type_);
00076   ROS_DEBUG_STREAM("Descriptor extractor type: " << descriptor_extractor_type_);
00077 
00078   if (descriptor_extractor_type_ == "SIFT")
00079   {
00080     throw ros::InvalidParameterException("SIFT algorithm is nonfree, cf. anj_featurenav_nonfree package");
00081   }
00082   else if (descriptor_extractor_type_ == "SURF")
00083   {
00084     throw ros::InvalidParameterException("SURF algorithm is nonfree, cf. anj_featurenav_nonfree package");
00085   }
00086   else if (descriptor_extractor_type_ == "ORB")
00087   {
00088     initExtractorOrb();
00089   }
00090   else if (descriptor_extractor_type_ == "BRIEF")
00091   {
00092     initExtractorBrief();
00093   }
00094   else
00095   {
00096     throw ros::InvalidParameterException(std::string("Unkown descriptor extraction algorithm (") +
00097         descriptor_extractor_type_ + std::string(")"));
00098   }
00099 
00100   // Initialize the descriptor matcher.
00101   private_nh_.getParam("descriptor_matcher/type", descriptor_matcher_type_);
00102   ROS_DEBUG_STREAM("Descriptor matcher type: " << descriptor_matcher_type_);
00103 
00104   if (descriptor_matcher_type_ == "BruteForce")
00105   {
00106     initMatcherBruteforce();
00107   }
00108   else if (descriptor_matcher_type_ == "FlannBased")
00109   {
00110     initMatcherFlannbased();
00111   }
00112   else
00113   {
00114     throw ros::InvalidParameterException(std::string("Unkown descriptor matcher algorithm (") +
00115         descriptor_matcher_type_ + std::string(")"));
00116   }
00117   
00118   map_interface_name_ = base_name_ + "_" + feature_detector_code_ + "_" + descriptor_extractor_code_;
00119   anjockey_ptr_.reset(new featurenav_base::ANJockey(base_name_, map_interface_name_));
00120   anjockey_ptr_->setExtractFeaturesFunction(boost::bind(&Jockey::extractFeatures, this, _1, _2, _3));
00121   anjockey_ptr_->setDescriptorMatcherFunction(boost::bind(&Jockey::matchDescriptors, this, _1, _2, _3));
00122 }
00123 
00124 std::string Jockey::getLearningJockeyName() const
00125 {
00126   if (anjockey_ptr_ == NULL)
00127   {
00128     return "";
00129   }
00130   return anjockey_ptr_->getLearningJockeyName();
00131 }
00132 
00133 std::string Jockey::getNavigatingJockeyName() const
00134 {
00135   if (anjockey_ptr_ == NULL)
00136   {
00137     return "";
00138   }
00139   return anjockey_ptr_->getNavigatingJockeyName();
00140 }
00141 
00142 /* Initialize feature detector with FAST algorithm
00143 */
00144 void Jockey::initDetectorFast()
00145 {
00146   // Initialize feature detector.
00147   GET_PARAM_DETECTOR(int, threshold, 1);
00148   GET_PARAM_DETECTOR(bool, nonmax_suppression, true);
00149 
00150   feature_detector_.reset(new cv::FastFeatureDetector(threshold, nonmax_suppression));
00151   feature_detector_code_ = "fast";
00152 }
00153 
00154 /* Initialize feature detector with STAR algorithm
00155 */
00156 void Jockey::initDetectorStar()
00157 {
00158   GET_PARAM_DETECTOR(int, max_size, 16);
00159   GET_PARAM_DETECTOR(int, response_threshold, 30);
00160   GET_PARAM_DETECTOR(int, line_threshold_projected, 10);
00161   GET_PARAM_DETECTOR(int, line_threshold_binarized, 8);
00162   GET_PARAM_DETECTOR(int, suppress_nonmax_size, 5);
00163 
00164   feature_detector_.reset(new cv::StarFeatureDetector(max_size,
00165         response_threshold, line_threshold_projected, line_threshold_binarized, suppress_nonmax_size));
00166   feature_detector_code_ = "star";
00167 }
00168 
00169 /* Initialize feature detector with Orb algorithm
00170 */
00171 void Jockey::initDetectorOrb()
00172 {
00173   enum
00174   {
00175     HARRIS_SCORE = 0,
00176     FAST_SCORE = 1
00177   };
00178 
00179   GET_PARAM_DETECTOR(double, scale_factor, 1.2);
00180   GET_PARAM_DETECTOR(int, n_features, 500);
00181   GET_PARAM_DETECTOR(int, n_levels, 8);
00182   GET_PARAM_DETECTOR(int, edge_threshold, 31);
00183   GET_PARAM_DETECTOR(int, first_level, 0);
00184   GET_PARAM_DETECTOR(int, wta_k, 2);
00185   GET_PARAM_DETECTOR(int, score_type, HARRIS_SCORE);
00186   GET_PARAM_DETECTOR(int, patch_size, 31);
00187 
00188   feature_detector_.reset(new cv::OrbFeatureDetector(n_features, scale_factor, n_levels, edge_threshold,
00189         first_level, wta_k, score_type, patch_size));
00190   feature_detector_code_ = "orb";
00191 }
00192 
00193 /* Initialize feature detector with MSER algorithm
00194 */
00195 void Jockey::initDetectorMser()
00196 {
00197   GET_PARAM_DETECTOR(int, delta, 5);
00198   GET_PARAM_DETECTOR(int, min_area, 60);
00199   GET_PARAM_DETECTOR(int, max_area, 14400);
00200   GET_PARAM_DETECTOR(double, max_variation, 0.25);
00201   GET_PARAM_DETECTOR(double, min_diversity, 0.2);
00202   GET_PARAM_DETECTOR(int, max_evolution, 200);
00203   GET_PARAM_DETECTOR(double, area_threshold, 1.01);
00204   GET_PARAM_DETECTOR(double, min_margin, 0.003);
00205   GET_PARAM_DETECTOR(int, edge_blur_size, 5);
00206 
00207   feature_detector_.reset(new cv::MserFeatureDetector(delta, min_area,
00208         max_area, max_variation, min_diversity, max_evolution, area_threshold,
00209         min_margin, edge_blur_size));
00210   feature_detector_code_ = "mser";
00211 }
00212 
00213 /* Initialize feature detector with GFTT algorithm (Good Features To Track)
00214 */
00215 void Jockey::initDetectorGftt()
00216 {
00217   GET_PARAM_DETECTOR(int, max_corners, 1000);
00218   GET_PARAM_DETECTOR(int, block_size, 3);
00219   GET_PARAM_DETECTOR(double, quality_level, 0.01);
00220   GET_PARAM_DETECTOR(double, min_distance, 1);
00221   GET_PARAM_DETECTOR(double, k, 0.04);
00222   GET_PARAM_DETECTOR(bool, use_harris_detector, false);
00223 
00224   feature_detector_.reset(new cv::GoodFeaturesToTrackDetector(max_corners,
00225         quality_level, min_distance, block_size, use_harris_detector, k));
00226   feature_detector_code_ = "gfft";
00227 }
00228 
00229 /* Initialize feature detector with Dense algorithm
00230 */
00231 void Jockey::initDetectorDense()
00232 {
00233   GET_PARAM_DETECTOR(int, feature_scale_levels, 1);
00234   GET_PARAM_DETECTOR(int, init_xy_step, 6);
00235   GET_PARAM_DETECTOR(int, init_img_bound, 0);
00236   GET_PARAM_DETECTOR(double, init_feature_scale, 1);
00237   GET_PARAM_DETECTOR(double, feature_scale_mul, 0.1);
00238   GET_PARAM_DETECTOR(bool, vary_xy_step_with_scale, true);
00239   GET_PARAM_DETECTOR(bool, vary_img_bound_with_scale, false);
00240 
00241   feature_detector_.reset(new cv::DenseFeatureDetector(init_feature_scale,
00242         feature_scale_levels, feature_scale_mul, init_xy_step, init_img_bound,
00243         vary_xy_step_with_scale, vary_img_bound_with_scale));
00244   feature_detector_code_ = "dense";
00245 }
00246 
00247 /* Initialize feature detector with SimpleBlob algorithm
00248 */
00249 void Jockey::initDetectorSimpleblob()
00250 {
00251   feature_detector_.reset(new cv::SimpleBlobDetector);
00252   feature_detector_code_ = "blob";
00253 }
00254 
00255 /* Initialize feature extractor with ORB algorithm
00256 */
00257 void Jockey::initExtractorOrb()
00258 {
00259   enum
00260   {
00261     HARRIS_SCORE = 0,
00262     FAST_SCORE = 1
00263   };
00264 
00265   GET_PARAM_EXTRACTOR(double, scale_factor, 1.2);
00266   GET_PARAM_EXTRACTOR(int, n_features, 500);
00267   GET_PARAM_EXTRACTOR(int, n_levels, 8);
00268   GET_PARAM_EXTRACTOR(int, edge_threshold, 31);
00269   GET_PARAM_EXTRACTOR(int, first_level, 0);
00270   GET_PARAM_EXTRACTOR(int, wta_k, 2);
00271   GET_PARAM_EXTRACTOR(int, score_type, HARRIS_SCORE);
00272   GET_PARAM_EXTRACTOR(int, patch_size, 31);
00273 
00274   descriptor_extractor_.reset(new cv::OrbDescriptorExtractor(n_features, scale_factor,
00275       n_levels, edge_threshold, first_level, wta_k, score_type, patch_size));
00276   descriptor_extractor_code_ = "orb";
00277 }
00278 
00279 /* Initialize feature extractor with Brief algorithm
00280 */
00281 void Jockey::initExtractorBrief()
00282 {
00283   GET_PARAM_EXTRACTOR(int, bytes, 32);
00284 
00285   descriptor_extractor_.reset(new cv::BriefDescriptorExtractor(bytes));
00286   descriptor_extractor_code_ = "brief";
00287 }
00288 
00289 void Jockey::initMatcherBruteforce()
00290 {
00291   int norm_type = cv::NORM_L1;
00292 
00293   GET_PARAM_MATCHER(std::string, norm, "NORM_L2");
00294   GET_PARAM_MATCHER(bool, cross_check, false);
00295 
00296   if ((norm == "NORM_L1") || (norm == "L1"))
00297   {
00298     norm_type = cv::NORM_L1;
00299   }
00300   else if ((norm == "NORM_L2") || (norm == "L2"))
00301   {
00302     norm_type = cv::NORM_L2;
00303   }
00304   else if ((norm == "NORM_HAMMING") || (norm == "HAMMING"))
00305   {
00306     norm_type = cv::NORM_HAMMING;
00307   }
00308   else if ((norm == "NORM_HAMMING2") || (norm == "HAMMING2"))
00309   {
00310     norm_type = cv::NORM_HAMMING2;
00311   }
00312   else
00313   {
00314     ROS_WARN_STREAM(ros::this_node::getName() << ": unknown norm type, defaulting to L2");
00315   }
00316 
00317   descriptor_matcher_.reset(new cv::BFMatcher(norm_type, cross_check));
00318   descriptor_matcher_code_ = "bf";
00319 }
00320 
00321 void Jockey::initMatcherFlannbased()
00322 {
00323   descriptor_matcher_.reset(new cv::FlannBasedMatcher());
00324   descriptor_matcher_code_ = "flann";
00325 }
00326 
00327 void Jockey::extractFeatures(const sensor_msgs::ImageConstPtr& image, vector<KeyPoint>& keypoints, vector<Feature>& descriptors) const
00328 {
00329   cv_bridge::CvImageConstPtr cv_ptr;
00330   try
00331   {
00332     cv_ptr = cv_bridge::toCvShare(image, sensor_msgs::image_encodings::BGR8);
00333   }
00334   catch (cv_bridge::Exception& e)
00335   {
00336     ROS_ERROR("cv_bridge exception: %s, doing nothing...", e.what());
00337     return;
00338   }
00339 
00340   feature_detector_->detect(cv_ptr->image, keypoints);
00341   cv::Mat cv_descriptors;
00342   descriptor_extractor_->compute(cv_ptr->image, keypoints, cv_descriptors);
00343 
00344   rosFromCv(cv_descriptors, descriptors);
00345 }
00346 
00347 void Jockey::matchDescriptors(const vector<Feature>& query_descriptors, const vector<Feature>& train_descriptors, vector<vector<DMatch> >& matches) const
00348 {
00349   int type = -1;
00350   if ((descriptor_extractor_code_ == "orb") || (descriptor_extractor_code_ == "brief"))
00351   {
00352     type = CV_8U;
00353   }
00354 
00355   cv::Mat cv_query_descriptors;
00356   cvFromRos(query_descriptors, cv_query_descriptors, type);
00357 
00358   cv::Mat cv_train_descriptors;
00359   cvFromRos(train_descriptors, cv_train_descriptors, type);
00360 
00361   // FlannBasedMatcher requires CV_32F descriptor type.
00362   if (descriptor_matcher_code_ == "flann")
00363   {
00364     cv::Mat cv_query_descriptors_copy;
00365     if(cv_query_descriptors.type() != CV_32F)
00366     {
00367       cv_query_descriptors.convertTo(cv_query_descriptors_copy, CV_32F);
00368     }
00369     else
00370     {
00371       cv_query_descriptors_copy = cv_query_descriptors;
00372     }
00373     cv::Mat cv_train_descriptors_copy;
00374     if(cv_train_descriptors.type() != CV_32F)
00375     {
00376       cv_train_descriptors.convertTo(cv_train_descriptors_copy, CV_32F);
00377     }
00378     else
00379     {
00380       cv_train_descriptors_copy = cv_train_descriptors;
00381     }
00382     descriptor_matcher_->knnMatch(cv_query_descriptors_copy, cv_train_descriptors_copy, matches, 2);
00383   }
00384   else
00385   {
00386     descriptor_matcher_->knnMatch(cv_query_descriptors, cv_train_descriptors, matches, 2);
00387   }
00388 }
00389 
00390 } /* anj_featurenav */ 
00391 


anj_featurenav
Author(s): Gaël Ecorchard , Karel Košnar , Vladimír Petrík
autogenerated on Sat Jun 8 2019 19:52:27