|
|
@ -52,15 +52,15 @@ |
|
|
|
|
|
|
|
|
|
|
|
namespace cv |
|
|
|
namespace cv |
|
|
|
{ |
|
|
|
{ |
|
|
|
namespace xfeatures2d |
|
|
|
namespace xfeatures2d |
|
|
|
{ |
|
|
|
{ |
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
/*
|
|
|
|
* LATCH Descriptor |
|
|
|
* LATCH Descriptor |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
class LATCHDescriptorExtractorImpl : public LATCHDescriptorExtractor |
|
|
|
class LATCHDescriptorExtractorImpl : public LATCHDescriptorExtractor |
|
|
|
{ |
|
|
|
{ |
|
|
|
public: |
|
|
|
public: |
|
|
|
enum { PATCH_SIZE = 48 }; |
|
|
|
enum { PATCH_SIZE = 48 }; |
|
|
|
|
|
|
|
|
|
|
|
LATCHDescriptorExtractorImpl(int bytes = 32, bool rotationInvariance = true, int half_ssd_size = 3); |
|
|
|
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); |
|
|
|
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); |
|
|
|
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_; |
|
|
|
int bytes_; |
|
|
@ -84,17 +84,17 @@ protected: |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
std::vector<int> sampling_points_ ; |
|
|
|
std::vector<int> sampling_points_ ; |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
Ptr<LATCHDescriptorExtractor> LATCHDescriptorExtractor::create(int bytes, bool rotationInvariance, int half_ssd_size) |
|
|
|
Ptr<LATCHDescriptorExtractor> LATCHDescriptorExtractor::create(int bytes, bool rotationInvariance, int half_ssd_size) |
|
|
|
{ |
|
|
|
{ |
|
|
|
return makePtr<LATCHDescriptorExtractorImpl>(bytes, rotationInvariance, 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(); |
|
|
|
Mat descriptors = _descriptors.getMat(); |
|
|
|
for (int i = 0; i < (int)keypoints.size(); ++i) |
|
|
|
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 suma = 0; |
|
|
|
int sumc = 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); |
|
|
|
desc[ix] += (uchar)((suma < sumc) << j); |
|
|
|
|
|
|
|
|
|
|
|
count += 6; |
|
|
|
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(); |
|
|
|
Mat descriptors = _descriptors.getMat(); |
|
|
|
for (int i = 0; i < (int)keypoints.size(); ++i) |
|
|
|
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 suma = 0; |
|
|
|
int sumc = 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); |
|
|
|
desc[ix] += (uchar)((suma < sumc) << j); |
|
|
|
|
|
|
|
|
|
|
|
count += 6; |
|
|
|
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(); |
|
|
|
Mat descriptors = _descriptors.getMat(); |
|
|
|
for (int i = 0; i < (int)keypoints.size(); ++i) |
|
|
|
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 suma = 0; |
|
|
|
int sumc = 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); |
|
|
|
desc[ix] += (uchar)((suma < sumc) << j); |
|
|
|
|
|
|
|
|
|
|
|
count += 6; |
|
|
|
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(); |
|
|
|
Mat descriptors = _descriptors.getMat(); |
|
|
|
for (int i = 0; i < (int)keypoints.size(); ++i) |
|
|
|
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 suma = 0; |
|
|
|
int sumc = 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); |
|
|
|
desc[ix] += (uchar)((suma < sumc) << j); |
|
|
|
|
|
|
|
|
|
|
|
count += 6; |
|
|
|
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(); |
|
|
|
Mat descriptors = _descriptors.getMat(); |
|
|
|
for (int i = 0; i < (int)keypoints.size(); ++i) |
|
|
|
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 suma = 0; |
|
|
|
int sumc = 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); |
|
|
|
desc[ix] += (uchar)((suma < sumc) << j); |
|
|
|
|
|
|
|
|
|
|
|
count += 6; |
|
|
|
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(); |
|
|
|
Mat descriptors = _descriptors.getMat(); |
|
|
|
for (int i = 0; i < (int)keypoints.size(); ++i) |
|
|
|
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 suma = 0; |
|
|
|
int sumc = 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); |
|
|
|
desc[ix] += (uchar)((suma < sumc) << j); |
|
|
|
|
|
|
|
|
|
|
|
count += 6; |
|
|
|
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(); |
|
|
|
Mat descriptors = _descriptors.getMat(); |
|
|
|
for (int i = 0; i < (int)keypoints.size(); ++i) |
|
|
|
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 suma = 0; |
|
|
|
int sumc = 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); |
|
|
|
desc[ix] += (uchar)((suma < sumc) << j); |
|
|
|
|
|
|
|
|
|
|
|
count += 6; |
|
|
|
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 ax = points[count]; |
|
|
|
int ay = points[count + 1]; |
|
|
|
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) : |
|
|
|
LATCHDescriptorExtractorImpl::LATCHDescriptorExtractorImpl(int bytes, bool rotationInvariance, int half_ssd_size) : |
|
|
|
bytes_(bytes), test_fn_(NULL), rotationInvariance_(rotationInvariance), half_ssd_size_(half_ssd_size) |
|
|
|
bytes_(bytes), test_fn_(NULL), rotationInvariance_(rotationInvariance), half_ssd_size_(half_ssd_size) |
|
|
|
{ |
|
|
|
{ |
|
|
|
switch (bytes) |
|
|
|
switch (bytes) |
|
|
|
{ |
|
|
|
{ |
|
|
|
case 1: |
|
|
|
case 1: |
|
|
@ -946,25 +946,25 @@ bytes_(bytes), test_fn_(NULL), rotationInvariance_(rotationInvariance), half_ssd |
|
|
|
11, -12, 5, -21, -2, -13}; |
|
|
|
11, -12, 5, -21, -2, -13}; |
|
|
|
|
|
|
|
|
|
|
|
sampling_points_.assign(&sampling_points_arr[0],&sampling_points_arr[0]+3072);
|
|
|
|
sampling_points_.assign(&sampling_points_arr[0],&sampling_points_arr[0]+3072);
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
int LATCHDescriptorExtractorImpl::descriptorSize() const |
|
|
|
int LATCHDescriptorExtractorImpl::descriptorSize() const |
|
|
|
{ |
|
|
|
{ |
|
|
|
return bytes_; |
|
|
|
return bytes_; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
int LATCHDescriptorExtractorImpl::descriptorType() const |
|
|
|
int LATCHDescriptorExtractorImpl::descriptorType() const |
|
|
|
{ |
|
|
|
{ |
|
|
|
return CV_8UC1; |
|
|
|
return CV_8UC1; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
int LATCHDescriptorExtractorImpl::defaultNorm() const |
|
|
|
int LATCHDescriptorExtractorImpl::defaultNorm() const |
|
|
|
{ |
|
|
|
{ |
|
|
|
return NORM_HAMMING; |
|
|
|
return NORM_HAMMING; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void LATCHDescriptorExtractorImpl::read(const FileNode& fn) |
|
|
|
void LATCHDescriptorExtractorImpl::read(const FileNode& fn) |
|
|
|
{ |
|
|
|
{ |
|
|
|
int dSize = fn["descriptorSize"]; |
|
|
|
int dSize = fn["descriptorSize"]; |
|
|
|
switch (dSize) |
|
|
|
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"); |
|
|
|
CV_Error(Error::StsBadArg, "descriptorSize must be 1,2, 4, 8, 16, 32, or 64"); |
|
|
|
} |
|
|
|
} |
|
|
|
bytes_ = dSize; |
|
|
|
bytes_ = dSize; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void LATCHDescriptorExtractorImpl::write(FileStorage& fs) const |
|
|
|
void LATCHDescriptorExtractorImpl::write(FileStorage& fs) const |
|
|
|
{ |
|
|
|
{ |
|
|
|
fs << "descriptorSize" << bytes_; |
|
|
|
fs << "descriptorSize" << bytes_; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void LATCHDescriptorExtractorImpl::compute(InputArray image, |
|
|
|
void LATCHDescriptorExtractorImpl::compute(InputArray image, |
|
|
|
std::vector<KeyPoint>& keypoints, |
|
|
|
std::vector<KeyPoint>& keypoints, |
|
|
|
OutputArray descriptors) |
|
|
|
OutputArray descriptors) |
|
|
|
{ |
|
|
|
{ |
|
|
|
|
|
|
|
|
|
|
|
Mat grayImage; |
|
|
|
Mat grayImage; |
|
|
|
GaussianBlur(image, grayImage, cv::Size(3, 3), 2, 2); |
|
|
|
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); |
|
|
|
descriptors.create((int)keypoints.size(), bytes_, CV_8U); |
|
|
|
|
|
|
|
|
|
|
|
test_fn_(grayImage, keypoints, descriptors, sampling_points_, rotationInvariance_, half_ssd_size_); |
|
|
|
test_fn_(grayImage, keypoints, descriptors, sampling_points_, rotationInvariance_, half_ssd_size_); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
} // namespace cv
|
|
|
|
} // namespace cv
|
|
|
|