Commit e2dfa357 authored by GilLevi's avatar GilLevi

added description of LATCH and fixed indentation

parent 292cee60
......@@ -152,6 +152,19 @@ public:
/** latch Class for computing the LATCH descriptor.
If you find this code useful, please add a reference to the following paper in your work:
Gil Levi and Tal Hassner, "LATCH: Learned Arrangements of Three Patch Codes", arXiv preprint arXiv:1501.03719, 15 Jan. 2015
LATCH is a binary descriptor based on learned comparisons of triplets of image patches.
* bytes is the size of the descriptor - can be 64, 32, 16, 8, 4, 2 or 1
* rotationInvariance - whether or not the descriptor should compansate for orientation changes.
* half_ssd_size - the size of half of the mini-patches size. For example, if we would like to compare triplets of patches of size 7x7x
then the half_ssd_size should be (7-1)/2 = 3.
Note: the descriptor can be coupled with any keypoint extractor. The only demand is that if you use set rotationInvariance = True then
you will have to use an extractor which estimates the patch orientation (in degrees). Examples for such extractors are ORB and SIFT.
Note: a complete example can be found under /samples/cpp/tutorial_code/xfeatures2D/latch_match.cpp
*/
class CV_EXPORTS LATCHDescriptorExtractor : public DescriptorExtractor
{
......
......@@ -52,15 +52,15 @@
namespace cv
{
namespace xfeatures2d
{
namespace xfeatures2d
{
/*
/*
* LATCH Descriptor
*/
class LATCHDescriptorExtractorImpl : public LATCHDescriptorExtractor
{
public:
{
public:
enum { PATCH_SIZE = 48 };
LATCHDescriptorExtractorImpl(int bytes = 32, bool rotationInvariance = true, int half_ssd_size = 3);
......@@ -74,7 +74,7 @@ public:
virtual void compute(InputArray image, std::vector<KeyPoint>& keypoints, OutputArray descriptors);
protected:
protected:
typedef void(*PixelTestFn)(const Mat& input_image, const std::vector<KeyPoint>& keypoints, OutputArray, const std::vector<int> &points, bool rotationInvariance, int half_ssd_size);
int bytes_;
......@@ -84,17 +84,17 @@ protected:
std::vector<int> sampling_points_ ;
};
};
Ptr<LATCHDescriptorExtractor> LATCHDescriptorExtractor::create(int bytes, bool rotationInvariance, int half_ssd_size)
{
{
return makePtr<LATCHDescriptorExtractorImpl>(bytes, rotationInvariance, half_ssd_size);
}
void CacluateSums(int count, const std::vector<int> &points, bool rotationInvariance, const Mat &grayImage, const KeyPoint &pt, int &suma, int &sumc, float cos_theta, float sin_theta, int half_ssd_size);
}
void CalcuateSums(int count, const std::vector<int> &points, bool rotationInvariance, const Mat &grayImage, const KeyPoint &pt, int &suma, int &sumc, float cos_theta, float sin_theta, int half_ssd_size);
static void pixelTests1(const Mat& grayImage, const std::vector<KeyPoint>& keypoints, OutputArray _descriptors, const std::vector<int> &points, bool rotationInvariance, int half_ssd_size)
{
static void pixelTests1(const Mat& grayImage, const std::vector<KeyPoint>& keypoints, OutputArray _descriptors, const std::vector<int> &points, bool rotationInvariance, int half_ssd_size)
{
Mat descriptors = _descriptors.getMat();
for (int i = 0; i < (int)keypoints.size(); ++i)
{
......@@ -114,18 +114,18 @@ static void pixelTests1(const Mat& grayImage, const std::vector<KeyPoint>& keypo
int suma = 0;
int sumc = 0;
CacluateSums(count, points, rotationInvariance, grayImage, pt, suma, sumc, cos_theta, sin_theta, half_ssd_size);
CalcuateSums(count, points, rotationInvariance, grayImage, pt, suma, sumc, cos_theta, sin_theta, half_ssd_size);
desc[ix] += (uchar)((suma < sumc) << j);
count += 6;
}
}
}
}
}
static void pixelTests2(const Mat& grayImage, const std::vector<KeyPoint>& keypoints, OutputArray _descriptors, const std::vector<int> &points, bool rotationInvariance, int half_ssd_size)
{
static void pixelTests2(const Mat& grayImage, const std::vector<KeyPoint>& keypoints, OutputArray _descriptors, const std::vector<int> &points, bool rotationInvariance, int half_ssd_size)
{
Mat descriptors = _descriptors.getMat();
for (int i = 0; i < (int)keypoints.size(); ++i)
{
......@@ -145,18 +145,18 @@ static void pixelTests2(const Mat& grayImage, const std::vector<KeyPoint>& keypo
int suma = 0;
int sumc = 0;
CacluateSums(count, points, rotationInvariance, grayImage, pt, suma, sumc, cos_theta, sin_theta, half_ssd_size);
CalcuateSums(count, points, rotationInvariance, grayImage, pt, suma, sumc, cos_theta, sin_theta, half_ssd_size);
desc[ix] += (uchar)((suma < sumc) << j);
count += 6;
}
}
}
}
}
static void pixelTests4(const Mat& grayImage, const std::vector<KeyPoint>& keypoints, OutputArray _descriptors, const std::vector<int> &points, bool rotationInvariance, int half_ssd_size)
{
static void pixelTests4(const Mat& grayImage, const std::vector<KeyPoint>& keypoints, OutputArray _descriptors, const std::vector<int> &points, bool rotationInvariance, int half_ssd_size)
{
Mat descriptors = _descriptors.getMat();
for (int i = 0; i < (int)keypoints.size(); ++i)
{
......@@ -176,19 +176,19 @@ static void pixelTests4(const Mat& grayImage, const std::vector<KeyPoint>& keypo
int suma = 0;
int sumc = 0;
CacluateSums(count, points, rotationInvariance, grayImage, pt, suma, sumc, cos_theta, sin_theta, half_ssd_size);
CalcuateSums(count, points, rotationInvariance, grayImage, pt, suma, sumc, cos_theta, sin_theta, half_ssd_size);
desc[ix] += (uchar)((suma < sumc) << j);
count += 6;
}
}
}
}
}
static void pixelTests8(const Mat& grayImage, const std::vector<KeyPoint>& keypoints, OutputArray _descriptors, const std::vector<int> &points, bool rotationInvariance, int half_ssd_size)
{
static void pixelTests8(const Mat& grayImage, const std::vector<KeyPoint>& keypoints, OutputArray _descriptors, const std::vector<int> &points, bool rotationInvariance, int half_ssd_size)
{
Mat descriptors = _descriptors.getMat();
for (int i = 0; i < (int)keypoints.size(); ++i)
{
......@@ -208,18 +208,18 @@ static void pixelTests8(const Mat& grayImage, const std::vector<KeyPoint>& keypo
int suma = 0;
int sumc = 0;
CacluateSums(count, points, rotationInvariance, grayImage, pt, suma, sumc, cos_theta, sin_theta, half_ssd_size);
CalcuateSums(count, points, rotationInvariance, grayImage, pt, suma, sumc, cos_theta, sin_theta, half_ssd_size);
desc[ix] += (uchar)((suma < sumc) << j);
count += 6;
}
}
}
}
}
static void pixelTests16(const Mat& grayImage, const std::vector<KeyPoint>& keypoints, OutputArray _descriptors, const std::vector<int> &points, bool rotationInvariance, int half_ssd_size)
{
static void pixelTests16(const Mat& grayImage, const std::vector<KeyPoint>& keypoints, OutputArray _descriptors, const std::vector<int> &points, bool rotationInvariance, int half_ssd_size)
{
Mat descriptors = _descriptors.getMat();
for (int i = 0; i < (int)keypoints.size(); ++i)
{
......@@ -239,18 +239,18 @@ static void pixelTests16(const Mat& grayImage, const std::vector<KeyPoint>& keyp
int suma = 0;
int sumc = 0;
CacluateSums(count, points, rotationInvariance, grayImage, pt, suma, sumc, cos_theta, sin_theta, half_ssd_size);
CalcuateSums(count, points, rotationInvariance, grayImage, pt, suma, sumc, cos_theta, sin_theta, half_ssd_size);
desc[ix] += (uchar)((suma < sumc) << j);
count += 6;
}
}
}
}
}
static void pixelTests32(const Mat& grayImage, const std::vector<KeyPoint>& keypoints, OutputArray _descriptors, const std::vector<int> &points, bool rotationInvariance, int half_ssd_size)
{
static void pixelTests32(const Mat& grayImage, const std::vector<KeyPoint>& keypoints, OutputArray _descriptors, const std::vector<int> &points, bool rotationInvariance, int half_ssd_size)
{
Mat descriptors = _descriptors.getMat();
for (int i = 0; i < (int)keypoints.size(); ++i)
{
......@@ -269,18 +269,18 @@ static void pixelTests32(const Mat& grayImage, const std::vector<KeyPoint>& keyp
int suma = 0;
int sumc = 0;
CacluateSums(count, points, rotationInvariance, grayImage, pt, suma, sumc, cos_theta, sin_theta, half_ssd_size);
CalcuateSums(count, points, rotationInvariance, grayImage, pt, suma, sumc, cos_theta, sin_theta, half_ssd_size);
desc[ix] += (uchar)((suma < sumc) << j);
count += 6;
}
}
}
}
}
static void pixelTests64(const Mat& grayImage, const std::vector<KeyPoint>& keypoints, OutputArray _descriptors, const std::vector<int> &points, bool rotationInvariance, int half_ssd_size)
{
static void pixelTests64(const Mat& grayImage, const std::vector<KeyPoint>& keypoints, OutputArray _descriptors, const std::vector<int> &points, bool rotationInvariance, int half_ssd_size)
{
Mat descriptors = _descriptors.getMat();
for (int i = 0; i < (int)keypoints.size(); ++i)
{
......@@ -300,18 +300,18 @@ static void pixelTests64(const Mat& grayImage, const std::vector<KeyPoint>& keyp
int suma = 0;
int sumc = 0;
CacluateSums(count, points, rotationInvariance, grayImage, pt, suma, sumc, cos_theta, sin_theta, half_ssd_size);
CalcuateSums(count, points, rotationInvariance, grayImage, pt, suma, sumc, cos_theta, sin_theta, half_ssd_size);
desc[ix] += (uchar)((suma < sumc) << j);
count += 6;
}
}
}
}
}
void CacluateSums(int count, const std::vector<int> &points, bool rotationInvariance, const Mat &grayImage, const KeyPoint &pt, int &suma, int &sumc, float cos_theta, float sin_theta, int half_ssd_size)
void CalcuateSums(int count, const std::vector<int> &points, bool rotationInvariance, const Mat &grayImage, const KeyPoint &pt, int &suma, int &sumc, float cos_theta, float sin_theta, int half_ssd_size)
{
{
int ax = points[count];
int ay = points[count + 1];
......@@ -399,13 +399,13 @@ void CacluateSums(int count, const std::vector<int> &points, bool rotationInvari
}
}
}
}
LATCHDescriptorExtractorImpl::LATCHDescriptorExtractorImpl(int bytes, bool rotationInvariance, int half_ssd_size) :
bytes_(bytes), test_fn_(NULL), rotationInvariance_(rotationInvariance), half_ssd_size_(half_ssd_size)
{
LATCHDescriptorExtractorImpl::LATCHDescriptorExtractorImpl(int bytes, bool rotationInvariance, int half_ssd_size) :
bytes_(bytes), test_fn_(NULL), rotationInvariance_(rotationInvariance), half_ssd_size_(half_ssd_size)
{
switch (bytes)
{
case 1:
......@@ -946,25 +946,25 @@ bytes_(bytes), test_fn_(NULL), rotationInvariance_(rotationInvariance), half_ssd
11, -12, 5, -21, -2, -13};
sampling_points_.assign(&sampling_points_arr[0],&sampling_points_arr[0]+3072);
}
}
int LATCHDescriptorExtractorImpl::descriptorSize() const
{
int LATCHDescriptorExtractorImpl::descriptorSize() const
{
return bytes_;
}
}
int LATCHDescriptorExtractorImpl::descriptorType() const
{
int LATCHDescriptorExtractorImpl::descriptorType() const
{
return CV_8UC1;
}
}
int LATCHDescriptorExtractorImpl::defaultNorm() const
{
int LATCHDescriptorExtractorImpl::defaultNorm() const
{
return NORM_HAMMING;
}
}
void LATCHDescriptorExtractorImpl::read(const FileNode& fn)
{
void LATCHDescriptorExtractorImpl::read(const FileNode& fn)
{
int dSize = fn["descriptorSize"];
switch (dSize)
{
......@@ -993,17 +993,17 @@ void LATCHDescriptorExtractorImpl::read(const FileNode& fn)
CV_Error(Error::StsBadArg, "descriptorSize must be 1,2, 4, 8, 16, 32, or 64");
}
bytes_ = dSize;
}
}
void LATCHDescriptorExtractorImpl::write(FileStorage& fs) const
{
void LATCHDescriptorExtractorImpl::write(FileStorage& fs) const
{
fs << "descriptorSize" << bytes_;
}
}
void LATCHDescriptorExtractorImpl::compute(InputArray image,
void LATCHDescriptorExtractorImpl::compute(InputArray image,
std::vector<KeyPoint>& keypoints,
OutputArray descriptors)
{
{
Mat grayImage;
GaussianBlur(image, grayImage, cv::Size(3, 3), 2, 2);
......@@ -1019,8 +1019,8 @@ void LATCHDescriptorExtractorImpl::compute(InputArray image,
descriptors.create((int)keypoints.size(), bytes_, CV_8U);
test_fn_(grayImage, keypoints, descriptors, sampling_points_, rotationInvariance_, half_ssd_size_);
}
}
}
}
} // namespace cv
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment