adding the Brief descriptor, associated hamming distance functors for bruteforce matching. Also adding cout << cv::Mat functions in core.

This commit is contained in:
Ethan Rublee
2010-11-14 06:27:48 +00:00
parent 4065f17aa0
commit d84b970bf2
11 changed files with 1354 additions and 20 deletions

View File

@@ -2456,7 +2456,7 @@ protected:
};
/*
* Class to compute image descriptor using bad of visual words.
* Class to compute image descriptor using bag of visual words.
*/
class CV_EXPORTS BOWImgDescriptorExtractor
{
@@ -2478,6 +2478,106 @@ protected:
Ptr<DescriptorMatcher> dmatcher;
};
/****************************************************************************************\
* BRIEF Descriptor *
\****************************************************************************************/
class CV_EXPORTS BriefDescriptorExtractor : public DescriptorExtractor
{
public:
BriefDescriptorExtractor(int bytes = 32);
virtual void compute(const Mat& image, std::vector<KeyPoint>& 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<KeyPoint>&, 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<KeyPoint>& keypoints, Mat& descriptors);
static void pixelTests32(const Mat& sum, const std::vector<KeyPoint>& keypoints, Mat& descriptors);
static void pixelTests64(const Mat& sum, const std::vector<KeyPoint>& 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<int32_t> (img_y + HALF_KERNEL + 1, img_x + HALF_KERNEL + 1) - sum.at<int32_t> (img_y + HALF_KERNEL + 1,
img_x - HALF_KERNEL)
- sum.at<int32_t> (img_y - HALF_KERNEL, img_x + HALF_KERNEL + 1) + sum.at<int32_t> (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<int size>
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<const unsigned long*> (a + i);
unsigned long b2 = *reinterpret_cast<const unsigned long*> (b + i);
result += __builtin_popcountl(a2 ^ b2);
}
return result;
}
};
#else
typedef HammingLUT Hamming;
#endif
} /* namespace cv */
#endif /* __cplusplus */