jockey.h
Go to the documentation of this file.
00001 /* Implements a feature-based learning and navigating jockey based on free
00002  * OpenCV feature descriptor and matcher.
00003  * 
00004  * The package defines the feature extractor and the feature matcher
00005  * functions required by the featurenav_base package to obtain a working couple
00006  * learning/navigating jockeys. The words feature and descriptor are used as
00007  * synonymous.
00008  *
00009  * Parameters:
00010  * - name, type, default value, description
00011  * - ~feature_detector/type, String, "FAST", algorithm for feature detection.
00012  *     Can be one of "FAST", "STAR", "ORB", "MSER", "GFTT", "Dense",
00013  *     "SimpleBlob". They make use of their corresponding algorithm in the
00014  *     OpenCV library (for example "FAST" implies the use of
00015  *     "cv::FastFeatureDetector").
00016  * - ~descriptor_extractor/type, String, "BRIEF", algorithm for feature
00017  *     extraction. Can be one of "ORB", "BRIEF". They make use of their
00018  *     corresponding algorithm in the OpenCV library (for example, "BRIEF"
00019  *     implies the use of "cv::BriefDescriptorExtractor").
00020  * - ~descriptor_matcher/type, String, "FlannBased", algorithm for feature
00021  *     matching. Can be one of "BruteForce", "FlannBased". They make use of
00022  *     their corresponding algorithm in the OpenCV library (for example,
00023  *     "FlannBased" implies the use of "cv::FlannBasedMatcher").
00024  *
00025  * Parameters for "FAST":
00026  * cf. http://docs.opencv.org/modules/features2d/doc/feature_detection_and_description.html#fast
00027  * - ~feature_detector/threshold, Int, 1, cf. OpenCV documentation.
00028  * - ~feature_detector/nonmax_suppression, Bool, true, cf. OpenCV documentation.
00029  *
00030  * Parameters for "STAR":
00031  * cf. http://docs.opencv.org/modules/features2d/doc/common_interfaces_of_feature_detectors.html?highlight=star#starfeaturedetector
00032  * - ~feature_detector/max_size, Int, 16, cf. OpenCV documentation.
00033  * - ~feature_detector/response_threshold, Int, 30, cf. OpenCV documentation.
00034  * - ~feature_detector/line_threshold_projected, Int, 10, cf. OpenCV documentation.
00035  * - ~feature_detector/line_threshold_binarized, Int, 8, cf. OpenCV documentation.
00036  * - ~feature_detector/suppress_nonmax_size, Int, 5, cf. OpenCV documentation.
00037  *
00038  * Parameters for "ORB" (as feature detector):
00039  * cf. http://docs.opencv.org/modules/features2d/doc/feature_detection_and_description.html#orb
00040  * - ~feature_detector/scale_factor, Float, 1.2, cf. OpenCV documentation.
00041  * - ~feature_detector/n_features, Int, 500, cf. OpenCV documentation.
00042  * - ~feature_detector/n_levels, Int, 8, cf. OpenCV documentation.
00043  * - ~feature_detector/edge_threshold, Int, 31, cf. OpenCV documentation.
00044  * - ~feature_detector/first_level, Int, 0, cf. OpenCV documentation.
00045  * - ~feature_detector/wta_k, Int, 2, cf. OpenCV documentation.
00046  * - ~feature_detector/score_type, Int, 0 (for HARRIS_SCORE), 0 for Harris
00047  *     score, 1 for FAST score, cf. OpenCV documentation.
00048  * - ~feature_detector/patch_size, Int, 31, cf. OpenCV documentation.
00049  *
00050  * Parameters for "MSER":
00051  * cf. http://docs.opencv.org/modules/features2d/doc/feature_detection_and_description.html#mser
00052  * - ~feature_detector/delta, Int, 5, cf. OpenCV documentation.
00053  * - ~feature_detector/min_area, Int, 60, cf. OpenCV documentation.
00054  * - ~feature_detector/max_area, Int, 14400, cf. OpenCV documentation.
00055  * - ~feature_detector/max_variation, Float, 0.25, cf. OpenCV documentation.
00056  * - ~feature_detector/min_diversity, Float, 0.2, cf. OpenCV documentation.
00057  * - ~feature_detector/max_evolution, Int, 200, cf. OpenCV documentation.
00058  * - ~feature_detector/area_threshold, Float, 1.01, cf. OpenCV documentation.
00059  * - ~feature_detector/min_margin, Float, 0.003, cf. OpenCV documentation.
00060  * - ~feature_detector/edge_blur_size, Int, 5, cf. OpenCV documentation.
00061  *
00062  * Parameters for "GFTT":
00063  * cf. http://docs.opencv.org/modules/features2d/doc/common_interfaces_of_feature_detectors.html?highlight=gftt#goodfeaturestotrackdetector
00064  * - ~feature_detector/max_corners, 1000, Int, cf. OpenCV documentation.
00065  * - ~feature_detector/block_size, 3, Int, cf. OpenCV documentation.
00066  * - ~feature_detector/quality_level, Float, 0.01, cf. OpenCV documentation.
00067  * - ~feature_detector/min_distance, Float, 1, cf. OpenCV documentation.
00068  * - ~feature_detector/k, Float, 0.04, cf. OpenCV documentation.
00069  * - ~feature_detector/use_harris_detector, Bool, false, cf. OpenCV documentation.
00070  *
00071  * Parameters for "Dense":
00072  * cf. http://docs.opencv.org/modules/features2d/doc/common_interfaces_of_feature_detectors.html?highlight=gftt#densefeaturedetector
00073  * - ~feature_detector/feature_scale_levels, Int, 1, cf. OpenCV documentation.
00074  * - ~feature_detector/init_xy_step, Int, 6, cf. OpenCV documentation.
00075  * - ~feature_detector/init_img_bound, Int, 0, cf. OpenCV documentation.
00076  * - ~feature_detector/init_feature_scale, Float, 1, cf. OpenCV documentation.
00077  * - ~feature_detector/feature_scale_mul, Float, 0.1, cf. OpenCV documentation.
00078  * - ~feature_detector/vary_xy_step_with_scale, Bool, true, cf. OpenCV documentation.
00079  * - ~feature_detector/vary_img_bound_with_scale, Bool, false, cf. OpenCV documentation.
00080  *
00081  * Parameters for "ORB" (as feature extractor):
00082  * cf. http://docs.opencv.org/modules/features2d/doc/feature_detection_and_description.html#orb
00083  * same parameters as "ORB" above but replacing "feature_detector" with "descriptor_extractor"
00084  *
00085  * Parameters for "BRIEF":
00086  * cf. http://docs.opencv.org/modules/features2d/doc/common_interfaces_of_descriptor_extractors.html?highlight=brief#briefdescriptorextractor
00087  * - ~descriptor_extractor/bytes, Int, 32, cf. OpenCV documentation.
00088  *
00089  * Parameters for "FlannBased":
00090  * cf. http://docs.opencv.org/modules/features2d/doc/common_interfaces_of_descriptor_matchers.html?highlight=flannbasedmatcher#flannbasedmatcher
00091  * none
00092  * 
00093  * Parameters for "BruteForce":
00094  * cf. http://docs.opencv.org/modules/features2d/doc/common_interfaces_of_descriptor_matchers.html#bfmatcher
00095  * - ~descriptor_matcher/norm, String, "L2", one of "L1", "L2", "HAMMING", "HAMMING2", cf. OpenCV documentation.
00096  * - ~descriptor_matcher/cross_check, Bool, false, cf. OpenCV documentation.
00097  */
00098 
00099 #ifndef ALJ_FEATURENAV_JOCKEY_H
00100 #define ALJ_FEATURENAV_JOCKEY_H
00101 
00102 #include <algorithm>
00103 #include <cassert>
00104 #include <vector>
00105 
00106 #include <boost/scoped_ptr.hpp>
00107 #include <opencv2/opencv.hpp>
00108 #include <opencv2/core/types_c.h>
00109 #include <opencv2/features2d/features2d.hpp>
00110 
00111 #include <ros/ros.h>
00112 #include <ros/console.h>
00113 #include <cv_bridge/cv_bridge.h>
00114 
00115 #include <featurenav_base/anjockey.h>
00116 #include <featurenav_base/Feature.h>
00117 
00118 namespace anj_featurenav
00119 {
00120 
00121 using std::vector;
00122 using cv::KeyPoint;
00123 using cv::DMatch;
00124 using featurenav_base::Feature;
00125 
00126 class Jockey
00127 {
00128   public:
00129 
00130     Jockey(const std::string& name);
00131 
00132     std::string getLearningJockeyName() const;
00133     std::string getNavigatingJockeyName() const;
00134 
00135   private:
00136 
00137     void initDetectorFast();
00138     void initDetectorStar();
00139     void initDetectorOrb();
00140     void initDetectorMser();
00141     void initDetectorGftt();
00142     void initDetectorDense();
00143     void initDetectorSimpleblob();
00144     void initExtractorOrb();
00145     void initExtractorBrief();
00146     void initMatcherBruteforce();
00147     void initMatcherFlannbased();
00148 
00149     void extractFeatures(const sensor_msgs::ImageConstPtr& image, vector<KeyPoint>& keypoints, vector<Feature>& descriptors) const;
00150     void matchDescriptors(const vector<Feature>& query_descriptors, const vector<Feature>& train_descriptors, vector<vector<DMatch> >& matches) const;
00151 
00152     // ROS parameters, shown outside.
00153     std::string feature_detector_type_;
00154     std::string descriptor_extractor_type_;
00155     std::string descriptor_matcher_type_;
00156 
00157     // Internals.
00158     ros::NodeHandle private_nh_;
00159     std::string base_name_;  
00160     boost::scoped_ptr<featurenav_base::ANJockey> anjockey_ptr_;
00161     boost::scoped_ptr<cv::FeatureDetector> feature_detector_;
00162     boost::scoped_ptr<cv::DescriptorExtractor> descriptor_extractor_;
00163     boost::scoped_ptr<cv::DescriptorMatcher> descriptor_matcher_;
00164     std::string feature_detector_code_;
00165     std::string descriptor_extractor_code_;
00166     std::string descriptor_matcher_code_;
00167     std::string map_interface_name_;  
00168 };
00169   
00170 inline Feature rosFromCv(const cv::Mat& descriptor)
00171 {
00172   Feature ros_descriptor;
00173   if (descriptor.type() == CV_8U)
00174   {
00175     std::copy(descriptor.begin<uint8_t>(), descriptor.end<uint8_t>(), std::back_inserter(ros_descriptor.udata));
00176   }
00177   else if (descriptor.type() == CV_16U)
00178   {
00179     std::copy(descriptor.begin<uint16_t>(), descriptor.end<uint16_t>(), std::back_inserter(ros_descriptor.udata));
00180   }
00181   else if (descriptor.type() == CV_8S)
00182   {
00183     std::copy(descriptor.begin<int8_t>(), descriptor.end<int8_t>(), std::back_inserter(ros_descriptor.idata));
00184   }
00185   else if (descriptor.type() == CV_16S)
00186   {
00187     std::copy(descriptor.begin<int16_t>(), descriptor.end<int16_t>(), std::back_inserter(ros_descriptor.idata));
00188   }
00189   else if (descriptor.type() == CV_32S)
00190   {
00191     std::copy(descriptor.begin<int32_t>(), descriptor.end<int32_t>(), std::back_inserter(ros_descriptor.idata));
00192   }
00193   else if ((descriptor.type() == CV_32F) ||
00194       (descriptor.type() == CV_64F))
00195   {
00196     // TODO: check that this works.
00197     std::copy(descriptor.begin<double>(), descriptor.end<double>(), std::back_inserter(ros_descriptor.fdata));
00198   }
00199   else
00200   {
00201     ROS_ERROR("Unrecognized data type: %d", descriptor.type());
00202     throw ros::Exception("Unrecognized data type");
00203   }
00204   return ros_descriptor;
00205 }
00206 
00207 /* Copy the data from a ROS Feature to an OpenCV feature (1 x n matrix).
00208  */
00209 inline void cvFromRos(const Feature& ros_descriptor, cv::Mat& cv_descriptor, const int type)
00210 {
00211   if (type == CV_8U)
00212   {
00213     assert(ros_descriptor.udata.size() == cv_descriptor.cols);
00214     for (size_t j = 0; j < ros_descriptor.udata.size(); ++j)
00215     {
00216       cv_descriptor.at<uint8_t>(0, j) = (uint8_t)ros_descriptor.udata[j];
00217     }
00218   }
00219   else if (type == CV_16U)
00220   {
00221     assert(ros_descriptor.udata.size() == cv_descriptor.cols);
00222     for (size_t j = 0; j < ros_descriptor.udata.size(); ++j)
00223     {
00224       cv_descriptor.at<uint16_t>(0, j) = (uint16_t)ros_descriptor.udata[j];
00225     }
00226   }
00227   else if (type == CV_8S)
00228   {
00229     assert(ros_descriptor.idata.size() == cv_descriptor.cols);
00230     for (size_t j = 0; j < ros_descriptor.idata.size(); ++j)
00231     {
00232       cv_descriptor.at<int8_t>(0, j) = (int8_t)ros_descriptor.idata[j];
00233     }
00234   }
00235   else if (type == CV_16S)
00236   {
00237     assert(ros_descriptor.idata.size() == cv_descriptor.cols);
00238     for (size_t j = 0; j < ros_descriptor.idata.size(); ++j)
00239     {
00240       cv_descriptor.at<int16_t>(0, j) = (int16_t)ros_descriptor.idata[j];
00241     }
00242   }
00243   else if (type == CV_32S)
00244   {
00245     assert(ros_descriptor.idata.size() == cv_descriptor.cols);
00246     for (size_t j = 0; j < ros_descriptor.idata.size(); ++j)
00247     {
00248       cv_descriptor.at<int32_t>(0, j) = (int32_t)ros_descriptor.idata[j];
00249     }
00250   }
00251   else if (type == CV_32F)
00252   {
00253     // TODO: check this.
00254     assert(ros_descriptor.fdata.size() == cv_descriptor.cols);
00255     for (size_t j = 0; j < ros_descriptor.fdata.size(); ++j)
00256     {
00257       cv_descriptor.at<float>(0, j) = ros_descriptor.fdata[j];
00258     }
00259   }
00260   else if (type == CV_64F)
00261   {
00262     // TODO: check this.
00263     assert(ros_descriptor.fdata.size() == cv_descriptor.cols);
00264     for (size_t j = 0; j < ros_descriptor.fdata.size(); ++j)
00265     {
00266       cv_descriptor.at<double>(0, j) = ros_descriptor.fdata[j];
00267     }
00268   }
00269   else
00270   {
00271     ROS_ERROR("Unrecognized data type: %d", type);
00272     throw ros::Exception("Unrecognized data type");
00273   }
00274 }
00275 
00276 inline void rosFromCv(const cv::Mat& cv_descriptors, vector<Feature>& ros_descriptors)
00277 {
00278   ros_descriptors.clear();
00279   ros_descriptors.reserve(cv_descriptors.rows);
00280   for (int i = 0; i < cv_descriptors.rows; ++i)
00281   {
00282     const Feature ros_descriptor = rosFromCv(cv_descriptors.row(i));
00283     ros_descriptors.push_back(ros_descriptor);
00284   }
00285 }
00286 
00287 inline void cvFromRos(const vector<Feature>& ros_descriptors, cv::Mat& cv_descriptors, const int type)
00288 {
00289   if (ros_descriptors.empty())
00290   {
00291     cv_descriptors.create(0, 0, type);
00292     return;
00293   }
00294 
00295   int size = std::max(ros_descriptors[0].udata.size(), std::max(ros_descriptors[0].idata.size(), ros_descriptors[0].fdata.size()));
00296   cv_descriptors.create(ros_descriptors.size(), size, type);
00297 
00298   for (size_t i = 0; i < ros_descriptors.size(); ++i)
00299   {
00300     cv::Mat cv_descriptor = cv_descriptors.row(i);
00301     cvFromRos(ros_descriptors[i], cv_descriptor, type);
00302   }
00303 }
00304 
00305 } /* namespace anj_featurenav */  
00306 
00307 
00308 #endif /* end of include guard: ALJ_FEATURENAV_JOCKEY_H */


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