diff --git a/modules/features2d/include/opencv2/features2d/features2d.hpp b/modules/features2d/include/opencv2/features2d/features2d.hpp index 36ad80078..47ccf9ffc 100644 --- a/modules/features2d/include/opencv2/features2d/features2d.hpp +++ b/modules/features2d/include/opencv2/features2d/features2d.hpp @@ -1433,6 +1433,7 @@ CV_EXPORTS Mat windowedMatchingMask( const vector& keypoints1, const v float maxDeltaX, float maxDeltaY ); CV_EXPORTS Ptr createFeatureDetector( const string& detectorType ); + /****************************************************************************************\ * DescriptorExtractor * \****************************************************************************************/ @@ -1483,6 +1484,9 @@ protected: Size imageSize, int borderPixels ); }; +/* + * SiftDescriptorExtractor + */ class CV_EXPORTS SiftDescriptorExtractor : public DescriptorExtractor { public: @@ -1504,6 +1508,9 @@ protected: SIFT sift; }; +/* + * SurfDescriptorExtractor + */ class CV_EXPORTS SurfDescriptorExtractor : public DescriptorExtractor { public: @@ -1521,6 +1528,9 @@ protected: SURF surf; }; +/* + * CalonderDescriptorExtractor + */ template class CV_EXPORTS CalonderDescriptorExtractor : public DescriptorExtractor { @@ -1574,6 +1584,8 @@ void CalonderDescriptorExtractor::write( FileStorage& ) const {} /* + * OpponentColorDescriptorExtractor + * * Adapts a descriptor extractor to compute descripors in Opponent Color Space * (refer to van de Sande et al., CGIV 2008 "Color Descriptors for Object Category Recognition"). * Input RGB image is transformed in Opponent Color Space. Then unadapted descriptor extractor @@ -1597,6 +1609,105 @@ protected: Ptr dextractor; }; +/* + * BRIEF Descriptor + */ +class CV_EXPORTS BriefDescriptorExtractor : public DescriptorExtractor +{ +public: + BriefDescriptorExtractor(int bytes = 32); + + virtual void compute(const Mat& image, std::vector& keypoints, Mat& descriptors) const; + + virtual int descriptorSize() const + { + return bytes_; + } + virtual int descriptorType() const + { + return CV_8UC1; + } + + /// @todo read and write for brief + //virtual void read(const FileNode& fn); + //virtual void write(FileStorage& fs) const; + +protected: + static const int PATCH_SIZE = 48; + static const int KERNEL_SIZE = 9; + + int bytes_; + typedef void(*PixelTestFn)(const Mat&, const std::vector&, Mat&); + PixelTestFn test_fn_; + + static int smoothedSum(const Mat& sum, const KeyPoint& pt, int y, int x); + static void pixelTests16(const Mat& sum, const std::vector& keypoints, Mat& descriptors); + static void pixelTests32(const Mat& sum, const std::vector& keypoints, Mat& descriptors); + static void pixelTests64(const Mat& sum, const std::vector& keypoints, Mat& descriptors); + +}; + +inline int BriefDescriptorExtractor::smoothedSum(const Mat& sum, const KeyPoint& pt, int y, int x) +{ + static const int HALF_KERNEL = KERNEL_SIZE / 2; + + int img_y = (int)(pt.pt.y + 0.5) + y; + int img_x = (int)(pt.pt.x + 0.5) + x; + return sum.at (img_y + HALF_KERNEL + 1, img_x + HALF_KERNEL + 1) - sum.at (img_y + HALF_KERNEL + 1, + img_x - HALF_KERNEL) + - sum.at (img_y - HALF_KERNEL, img_x + HALF_KERNEL + 1) + sum.at (img_y - HALF_KERNEL, img_x + - HALF_KERNEL); +} + +struct CV_EXPORTS HammingLUT +{ + typedef unsigned char ValueType; + typedef int ResultType; + + ResultType operator()(const unsigned char* a, const unsigned char* b, int size) const + { + ResultType result = 0; + for (int i = 0; i < size; i++) + { + result += byteBitsLookUp(a[i] ^ b[i]); + } + return result; + } + /** \brief given a byte, count the bits using a compile time generated look up table + * \param b the byte to count bits. The look up table has an entry for all + * values of b, where that entry is the number of bits. + * \return the number of bits in byte b + */ + static unsigned char byteBitsLookUp(unsigned char b); +}; + +#if __GNUC__ +/// Hamming distance functor +/// @todo Variable-length version, maybe default size=0 and specialize +/// @todo Need to choose C/SSE4 at runtime, but amortize this at matcher level for efficiency... +//template +struct Hamming +{ + typedef unsigned char ValueType; + typedef int ResultType; + + ResultType operator()(const unsigned char* a, const unsigned char* b, int size) const + { + /// @todo Non-GCC-specific version + ResultType result = 0; + for (int i = 0; i < size; i += sizeof(unsigned long)) + { + unsigned long a2 = *reinterpret_cast (a + i); + unsigned long b2 = *reinterpret_cast (b + i); + result += __builtin_popcountl(a2 ^ b2); + } + return result; + } +}; +#else +typedef HammingLUT Hamming; +#endif + CV_EXPORTS Ptr createDescriptorExtractor( const string& descriptorExtractorType ); /****************************************************************************************\ @@ -2478,106 +2589,6 @@ protected: Ptr dmatcher; }; -/****************************************************************************************\ -* BRIEF Descriptor * -\****************************************************************************************/ - -class CV_EXPORTS BriefDescriptorExtractor : public DescriptorExtractor -{ -public: - BriefDescriptorExtractor(int bytes = 32); - - virtual void compute(const Mat& image, std::vector& keypoints, Mat& descriptors) const; - - virtual int descriptorSize() const - { - return bytes_; - } - virtual int descriptorType() const - { - return CV_8UC1; - } - - /// @todo read and write for brief - //virtual void read(const FileNode& fn); - //virtual void write(FileStorage& fs) const; - -protected: - static const int PATCH_SIZE = 48; - static const int KERNEL_SIZE = 9; - - int bytes_; - typedef void(*PixelTestFn)(const Mat&, const std::vector&, Mat&); - PixelTestFn test_fn_; - - static int32_t smoothedSum(const Mat& sum, const KeyPoint& pt, int y, int x); - static void pixelTests16(const Mat& sum, const std::vector& keypoints, Mat& descriptors); - static void pixelTests32(const Mat& sum, const std::vector& keypoints, Mat& descriptors); - static void pixelTests64(const Mat& sum, const std::vector& keypoints, Mat& descriptors); - -}; - -inline int32_t BriefDescriptorExtractor::smoothedSum(const Mat& sum, const KeyPoint& pt, int y, int x) -{ - static const int HALF_KERNEL = KERNEL_SIZE / 2; - - int img_y = (int)(pt.pt.y + 0.5) + y; - int img_x = (int)(pt.pt.x + 0.5) + x; - return sum.at (img_y + HALF_KERNEL + 1, img_x + HALF_KERNEL + 1) - sum.at (img_y + HALF_KERNEL + 1, - img_x - HALF_KERNEL) - - sum.at (img_y - HALF_KERNEL, img_x + HALF_KERNEL + 1) + sum.at (img_y - HALF_KERNEL, img_x - - HALF_KERNEL); -} - -struct CV_EXPORTS HammingLUT -{ - typedef unsigned char ValueType; - typedef int ResultType; - - ResultType operator()(const unsigned char* a, const unsigned char* b, int size) const - { - ResultType result = 0; - for (int i = 0; i < size; i++) - { - result += byteBitsLookUp(a[i] ^ b[i]); - } - return result; - } - /** \brief given a byte, count the bits using a compile time generated look up table - * \param b the byte to count bits. The look up table has an entry for all - * values of b, where that entry is the number of bits. - * \return the number of bits in byte b - */ - static unsigned char byteBitsLookUp(unsigned char b); -}; - -#if __GNUC__ -/// Hamming distance functor -/// @todo Variable-length version, maybe default size=0 and specialize -/// @todo Need to choose C/SSE4 at runtime, but amortize this at matcher level for efficiency... -//template -struct Hamming -{ - typedef unsigned char ValueType; - typedef int ResultType; - - ResultType operator()(const unsigned char* a, const unsigned char* b, int size) const - { - /// @todo Non-GCC-specific version - ResultType result = 0; - for (int i = 0; i < size; i += sizeof(unsigned long)) - { - unsigned long a2 = *reinterpret_cast (a + i); - unsigned long b2 = *reinterpret_cast (b + i); - result += __builtin_popcountl(a2 ^ b2); - } - return result; - } -}; -#else -typedef HammingLUT Hamming; -#endif - } /* namespace cv */ #endif /* __cplusplus */