diff --git a/modules/xfeatures2d/src/latch.cpp b/modules/xfeatures2d/src/latch.cpp index 3e5bdbfb9..7485d3c61 100644 --- a/modules/xfeatures2d/src/latch.cpp +++ b/modules/xfeatures2d/src/latch.cpp @@ -81,435 +81,7 @@ protected: PixelTestFn test_fn_; int half_ssd_size_; bool rotationInvariance_; - //std::vector sampling_points_; - void setTriplets(); -}; - - Ptr LATCHDescriptorExtractor::create(int bytes, bool rotationInvariance, int half_ssd_size) -{ - return makePtr(bytes, rotationInvariance, half_ssd_size); -} -void CacluateSums(int count, const std::vector &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& keypoints, OutputArray& _descriptors, const std::vector &points, bool rotationInvariance, int half_ssd_size) -{ - Mat descriptors = _descriptors.getMat(); - for (int i = 0; i < (int)keypoints.size(); ++i) - { - uchar* desc = descriptors.ptr(i); - const KeyPoint& pt = keypoints[i]; - int count = 0; - - //handling keypoint orientation - float angle = pt.angle; - angle *= (float)(CV_PI / 180.f); - float cos_theta = cos(angle); - float sin_theta = sin(angle); - for (int ix = 0; ix < 1; ix++){ - desc[ix] = 0; - for (int j = 7; j >= 0; j--){ - - int suma = 0; - int sumc = 0; - - CacluateSums(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& keypoints, OutputArray& _descriptors, const std::vector &points, bool rotationInvariance, int half_ssd_size) -{ - Mat descriptors = _descriptors.getMat(); - for (int i = 0; i < (int)keypoints.size(); ++i) - { - uchar* desc = descriptors.ptr(i); - const KeyPoint& pt = keypoints[i]; - int count = 0; - - //handling keypoint orientation - float angle = pt.angle; - angle *= (float)(CV_PI / 180.f); - float cos_theta = cos(angle); - float sin_theta = sin(angle); - for (int ix = 0; ix < 2; ix++){ - desc[ix] = 0; - for (int j = 7; j >= 0; j--){ - - int suma = 0; - int sumc = 0; - - CacluateSums(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& keypoints, OutputArray& _descriptors, const std::vector &points, bool rotationInvariance, int half_ssd_size) -{ - Mat descriptors = _descriptors.getMat(); - for (int i = 0; i < (int)keypoints.size(); ++i) - { - uchar* desc = descriptors.ptr(i); - const KeyPoint& pt = keypoints[i]; - int count = 0; - - //handling keypoint orientation - float angle = pt.angle; - angle *= (float)(CV_PI / 180.f); - float cos_theta = cos(angle); - float sin_theta = sin(angle); - for (int ix = 0; ix < 4; ix++){ - desc[ix] = 0; - for (int j = 7; j >= 0; j--){ - - int suma = 0; - int sumc = 0; - - CacluateSums(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& keypoints, OutputArray& _descriptors, const std::vector &points, bool rotationInvariance, int half_ssd_size) -{ - Mat descriptors = _descriptors.getMat(); - for (int i = 0; i < (int)keypoints.size(); ++i) - { - uchar* desc = descriptors.ptr(i); - const KeyPoint& pt = keypoints[i]; - int count = 0; - - //handling keypoint orientation - float angle = pt.angle; - angle *= (float)(CV_PI / 180.f); - float cos_theta = cos(angle); - float sin_theta = sin(angle); - for (int ix = 0; ix < 8; ix++){ - desc[ix] = 0; - for (int j = 7; j >= 0; j--){ - - int suma = 0; - int sumc = 0; - - CacluateSums(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& keypoints, OutputArray& _descriptors, const std::vector &points, bool rotationInvariance, int half_ssd_size) -{ - Mat descriptors = _descriptors.getMat(); - for (int i = 0; i < (int)keypoints.size(); ++i) - { - uchar* desc = descriptors.ptr(i); - const KeyPoint& pt = keypoints[i]; - int count = 0; - - //handling keypoint orientation - float angle = pt.angle; - angle *= (float)(CV_PI / 180.f); - float cos_theta = cos(angle); - float sin_theta = sin(angle); - for (int ix = 0; ix < 16; ix++){ - desc[ix] = 0; - for (int j = 7; j >= 0; j--){ - - int suma = 0; - int sumc = 0; - - CacluateSums(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& keypoints, OutputArray& _descriptors, const std::vector &points, bool rotationInvariance, int half_ssd_size) -{ - Mat descriptors = _descriptors.getMat(); - for (int i = 0; i < (int)keypoints.size(); ++i) - { - uchar* desc = descriptors.ptr(i); - const KeyPoint& pt = keypoints[i]; - int count = 0; - - float angle = pt.angle; - angle *= (float)(CV_PI / 180.f); - float cos_theta = cos(angle); - float sin_theta = sin(angle); - for (int ix = 0; ix < 32; ix++){ - desc[ix] = 0; - for (int j = 7; j >= 0; j--){ - - int suma = 0; - int sumc = 0; - - CacluateSums(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& keypoints, OutputArray& _descriptors, const std::vector &points, bool rotationInvariance, int half_ssd_size) -{ - Mat descriptors = _descriptors.getMat(); - for (int i = 0; i < (int)keypoints.size(); ++i) - { - uchar* desc = descriptors.ptr(i); - const KeyPoint& pt = keypoints[i]; - int count = 0; - - //handling keypoint orientation - float angle = pt.angle; - angle *= (float)(CV_PI / 180.f); - float cos_theta = cos(angle); - float sin_theta = sin(angle); - for (int ix = 0; ix < 64; ix++){ - desc[ix] = 0; - for (int j = 7; j >= 0; j--){ - - int suma = 0; - int sumc = 0; - - CacluateSums(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 &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]; - - int bx = points[count + 2]; - int by = points[count + 3]; - - int cx = points[count + 4]; - int cy = points[count + 5]; - - int ax2 = ax; - int ay2 = ay; - int bx2 = bx; - int by2 = by; - int cx2 = cx; - int cy2 = cy; - - if (rotationInvariance){ - - - ax2 =(int)(((float)ax)*cos_theta - ((float)ay)*sin_theta); - ay2 = (int)(((float)ax)*sin_theta + ((float)ay)*cos_theta); - bx2 = (int)(((float)bx)*cos_theta - ((float)by)*sin_theta); - by2 = (int)(((float)bx)*sin_theta + ((float)by)*cos_theta); - cx2 = (int)(((float)cx)*cos_theta - ((float)cy)*sin_theta); - cy2 = (int)(((float)cx)*sin_theta + ((float)cy)*cos_theta); - - - if (ax2 > 24) - ax2 = 24; - if (ax2<-24) - ax2 = -24; - - if (ay2>24) - ay2 = 24; - if (ay2<-24) - ay2 = -24; - - if (bx2>24) - bx2 = 24; - if (bx2<-24) - bx2 = -24; - - if (by2>24) - by2 = 24; - if (by2<-24) - by2 = -24; - - if (cx2>24) - cx2 = 24; - if (cx2<-24) - cx2 = -24; - - if (cy2>24) - cy2 = 24; - if (cy2 < -24) - cy2 = -24; - - } - - - ax2 += (int)(pt.pt.x + 0.5); - ay2 += (int)(pt.pt.y + 0.5); - - bx2 += (int)(pt.pt.x + 0.5); - by2 += (int)(pt.pt.y + 0.5); - - cx2 += (int)(pt.pt.x + 0.5); - cy2 += (int)(pt.pt.y + 0.5); - - - int K = half_ssd_size; - for (int iy = -K; iy <= K; iy++) - { - const uchar * Mi_a = grayImage.ptr(ay2 + iy); - const uchar * Mi_b = grayImage.ptr(by2 + iy); - const uchar * Mi_c = grayImage.ptr(cy2 + iy); - - for (int ix = -K; ix <= K; ix++) - { - double difa = Mi_a[ax2 + ix] - Mi_b[bx2 + ix]; - suma += (int)((difa)*(difa)); - - double difc = Mi_c[cx2 + ix] - Mi_b[bx2 + ix]; - sumc += (int)((difc)*(difc)); - } - } - -} - - - -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: - test_fn_ = pixelTests1; - break; - case 2: - test_fn_ = pixelTests2; - break; - case 4: - test_fn_ = pixelTests4; - break; - case 8: - test_fn_ = pixelTests8; - break; - case 16: - test_fn_ = pixelTests16; - break; - case 32: - test_fn_ = pixelTests32; - break; - case 64: - test_fn_ = pixelTests64; - break; - default: - CV_Error(Error::StsBadArg, "descriptorSize must be 1,2, 4, 8, 16, 32, or 64"); - } - - setTriplets(); -} - -int LATCHDescriptorExtractorImpl::descriptorSize() const -{ - return bytes_; -} - -int LATCHDescriptorExtractorImpl::descriptorType() const -{ - return CV_8UC1; -} - -int LATCHDescriptorExtractorImpl::defaultNorm() const -{ - return NORM_HAMMING; -} - -void LATCHDescriptorExtractorImpl::read(const FileNode& fn) -{ - int dSize = fn["descriptorSize"]; - switch (dSize) - { - case 1: - test_fn_ = pixelTests1; - break; - case 2: - test_fn_ = pixelTests2; - break; - case 4: - test_fn_ = pixelTests4; - break; - case 8: - test_fn_ = pixelTests8; - break; - case 16: - test_fn_ = pixelTests16; - break; - case 32: - test_fn_ = pixelTests32; - break; - case 64: - test_fn_ = pixelTests64; - break; - default: - CV_Error(Error::StsBadArg, "descriptorSize must be 1,2, 4, 8, 16, 32, or 64"); - } - bytes_ = dSize; -} - -void LATCHDescriptorExtractorImpl::write(FileStorage& fs) const -{ - fs << "descriptorSize" << bytes_; -} - -void LATCHDescriptorExtractorImpl::compute(InputArray image, - std::vector& keypoints, - OutputArray descriptors) -{ - - Mat grayImage; - GaussianBlur(image, grayImage, cv::Size(3, 3), 2, 2); - - if (image.type() != CV_8U) cvtColor(image, grayImage, COLOR_BGR2GRAY); - - - - //Remove keypoints very close to the border - KeyPointsFilter::runByImageBorder(keypoints, image.size(), PATCH_SIZE / 2 + half_ssd_size_); - - - descriptors.create((int)keypoints.size(), bytes_, CV_8U); - - test_fn_(grayImage, keypoints, descriptors, sampling_points_, rotationInvariance_, half_ssd_size_); -} - - -static std::vector sampling_points_ { 13, -6, 19, 19, 23, -4, + std::vector sampling_points_ { 13, -6, 19, 19, 23, -4, 4, 16, 24, -11, 4, -21, 22, -14, -2, -20, 23, 5, 17, -10, 2, 10, 14, -18, @@ -1022,8 +594,432 @@ static std::vector sampling_points_ { 13, -6, 19, 19, 23, -4, -19, 20, -11, -2, -20, -24, 11, -12, 5, -21, -2, -13 }; +}; + + Ptr LATCHDescriptorExtractor::create(int bytes, bool rotationInvariance, int half_ssd_size) +{ + return makePtr(bytes, rotationInvariance, half_ssd_size); +} +void CacluateSums(int count, const std::vector &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& keypoints, OutputArray& _descriptors, const std::vector &points, bool rotationInvariance, int half_ssd_size) +{ + Mat descriptors = _descriptors.getMat(); + for (int i = 0; i < (int)keypoints.size(); ++i) + { + uchar* desc = descriptors.ptr(i); + const KeyPoint& pt = keypoints[i]; + int count = 0; + + //handling keypoint orientation + float angle = pt.angle; + angle *= (float)(CV_PI / 180.f); + float cos_theta = cos(angle); + float sin_theta = sin(angle); + for (int ix = 0; ix < 1; ix++){ + desc[ix] = 0; + for (int j = 7; j >= 0; j--){ + + int suma = 0; + int sumc = 0; + + CacluateSums(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& keypoints, OutputArray& _descriptors, const std::vector &points, bool rotationInvariance, int half_ssd_size) +{ + Mat descriptors = _descriptors.getMat(); + for (int i = 0; i < (int)keypoints.size(); ++i) + { + uchar* desc = descriptors.ptr(i); + const KeyPoint& pt = keypoints[i]; + int count = 0; + + //handling keypoint orientation + float angle = pt.angle; + angle *= (float)(CV_PI / 180.f); + float cos_theta = cos(angle); + float sin_theta = sin(angle); + for (int ix = 0; ix < 2; ix++){ + desc[ix] = 0; + for (int j = 7; j >= 0; j--){ + + int suma = 0; + int sumc = 0; + + CacluateSums(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& keypoints, OutputArray& _descriptors, const std::vector &points, bool rotationInvariance, int half_ssd_size) +{ + Mat descriptors = _descriptors.getMat(); + for (int i = 0; i < (int)keypoints.size(); ++i) + { + uchar* desc = descriptors.ptr(i); + const KeyPoint& pt = keypoints[i]; + int count = 0; + + //handling keypoint orientation + float angle = pt.angle; + angle *= (float)(CV_PI / 180.f); + float cos_theta = cos(angle); + float sin_theta = sin(angle); + for (int ix = 0; ix < 4; ix++){ + desc[ix] = 0; + for (int j = 7; j >= 0; j--){ + + int suma = 0; + int sumc = 0; + + CacluateSums(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& keypoints, OutputArray& _descriptors, const std::vector &points, bool rotationInvariance, int half_ssd_size) +{ + Mat descriptors = _descriptors.getMat(); + for (int i = 0; i < (int)keypoints.size(); ++i) + { + uchar* desc = descriptors.ptr(i); + const KeyPoint& pt = keypoints[i]; + int count = 0; + + //handling keypoint orientation + float angle = pt.angle; + angle *= (float)(CV_PI / 180.f); + float cos_theta = cos(angle); + float sin_theta = sin(angle); + for (int ix = 0; ix < 8; ix++){ + desc[ix] = 0; + for (int j = 7; j >= 0; j--){ + + int suma = 0; + int sumc = 0; + + CacluateSums(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& keypoints, OutputArray& _descriptors, const std::vector &points, bool rotationInvariance, int half_ssd_size) +{ + Mat descriptors = _descriptors.getMat(); + for (int i = 0; i < (int)keypoints.size(); ++i) + { + uchar* desc = descriptors.ptr(i); + const KeyPoint& pt = keypoints[i]; + int count = 0; + + //handling keypoint orientation + float angle = pt.angle; + angle *= (float)(CV_PI / 180.f); + float cos_theta = cos(angle); + float sin_theta = sin(angle); + for (int ix = 0; ix < 16; ix++){ + desc[ix] = 0; + for (int j = 7; j >= 0; j--){ + + int suma = 0; + int sumc = 0; + + CacluateSums(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& keypoints, OutputArray& _descriptors, const std::vector &points, bool rotationInvariance, int half_ssd_size) +{ + Mat descriptors = _descriptors.getMat(); + for (int i = 0; i < (int)keypoints.size(); ++i) + { + uchar* desc = descriptors.ptr(i); + const KeyPoint& pt = keypoints[i]; + int count = 0; + + float angle = pt.angle; + angle *= (float)(CV_PI / 180.f); + float cos_theta = cos(angle); + float sin_theta = sin(angle); + for (int ix = 0; ix < 32; ix++){ + desc[ix] = 0; + for (int j = 7; j >= 0; j--){ + + int suma = 0; + int sumc = 0; + + CacluateSums(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& keypoints, OutputArray& _descriptors, const std::vector &points, bool rotationInvariance, int half_ssd_size) +{ + Mat descriptors = _descriptors.getMat(); + for (int i = 0; i < (int)keypoints.size(); ++i) + { + uchar* desc = descriptors.ptr(i); + const KeyPoint& pt = keypoints[i]; + int count = 0; + + //handling keypoint orientation + float angle = pt.angle; + angle *= (float)(CV_PI / 180.f); + float cos_theta = cos(angle); + float sin_theta = sin(angle); + for (int ix = 0; ix < 64; ix++){ + desc[ix] = 0; + for (int j = 7; j >= 0; j--){ + + int suma = 0; + int sumc = 0; + + CacluateSums(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 &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]; + + int bx = points[count + 2]; + int by = points[count + 3]; + + int cx = points[count + 4]; + int cy = points[count + 5]; + + int ax2 = ax; + int ay2 = ay; + int bx2 = bx; + int by2 = by; + int cx2 = cx; + int cy2 = cy; + + if (rotationInvariance){ + + + ax2 =(int)(((float)ax)*cos_theta - ((float)ay)*sin_theta); + ay2 = (int)(((float)ax)*sin_theta + ((float)ay)*cos_theta); + bx2 = (int)(((float)bx)*cos_theta - ((float)by)*sin_theta); + by2 = (int)(((float)bx)*sin_theta + ((float)by)*cos_theta); + cx2 = (int)(((float)cx)*cos_theta - ((float)cy)*sin_theta); + cy2 = (int)(((float)cx)*sin_theta + ((float)cy)*cos_theta); + + + if (ax2 > 24) + ax2 = 24; + if (ax2<-24) + ax2 = -24; + + if (ay2>24) + ay2 = 24; + if (ay2<-24) + ay2 = -24; + + if (bx2>24) + bx2 = 24; + if (bx2<-24) + bx2 = -24; + + if (by2>24) + by2 = 24; + if (by2<-24) + by2 = -24; + + if (cx2>24) + cx2 = 24; + if (cx2<-24) + cx2 = -24; + + if (cy2>24) + cy2 = 24; + if (cy2 < -24) + cy2 = -24; + + } + + + ax2 += (int)(pt.pt.x + 0.5); + ay2 += (int)(pt.pt.y + 0.5); + + bx2 += (int)(pt.pt.x + 0.5); + by2 += (int)(pt.pt.y + 0.5); + + cx2 += (int)(pt.pt.x + 0.5); + cy2 += (int)(pt.pt.y + 0.5); + + int K = half_ssd_size; + for (int iy = -K; iy <= K; iy++) + { + const uchar * Mi_a = grayImage.ptr(ay2 + iy); + const uchar * Mi_b = grayImage.ptr(by2 + iy); + const uchar * Mi_c = grayImage.ptr(cy2 + iy); + + for (int ix = -K; ix <= K; ix++) + { + double difa = Mi_a[ax2 + ix] - Mi_b[bx2 + ix]; + suma += (int)((difa)*(difa)); + + double difc = Mi_c[cx2 + ix] - Mi_b[bx2 + ix]; + sumc += (int)((difc)*(difc)); + } + } + +} + + + +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: + test_fn_ = pixelTests1; + break; + case 2: + test_fn_ = pixelTests2; + break; + case 4: + test_fn_ = pixelTests4; + break; + case 8: + test_fn_ = pixelTests8; + break; + case 16: + test_fn_ = pixelTests16; + break; + case 32: + test_fn_ = pixelTests32; + break; + case 64: + test_fn_ = pixelTests64; + break; + default: + CV_Error(Error::StsBadArg, "descriptorSize must be 1,2, 4, 8, 16, 32, or 64"); + } + + setTriplets(); +} + +int LATCHDescriptorExtractorImpl::descriptorSize() const +{ + return bytes_; +} + +int LATCHDescriptorExtractorImpl::descriptorType() const +{ + return CV_8UC1; +} + +int LATCHDescriptorExtractorImpl::defaultNorm() const +{ + return NORM_HAMMING; +} + +void LATCHDescriptorExtractorImpl::read(const FileNode& fn) +{ + int dSize = fn["descriptorSize"]; + switch (dSize) + { + case 1: + test_fn_ = pixelTests1; + break; + case 2: + test_fn_ = pixelTests2; + break; + case 4: + test_fn_ = pixelTests4; + break; + case 8: + test_fn_ = pixelTests8; + break; + case 16: + test_fn_ = pixelTests16; + break; + case 32: + test_fn_ = pixelTests32; + break; + case 64: + test_fn_ = pixelTests64; + break; + default: + CV_Error(Error::StsBadArg, "descriptorSize must be 1,2, 4, 8, 16, 32, or 64"); + } + bytes_ = dSize; +} + +void LATCHDescriptorExtractorImpl::write(FileStorage& fs) const +{ + fs << "descriptorSize" << bytes_; +} + +void LATCHDescriptorExtractorImpl::compute(InputArray image, + std::vector& keypoints, + OutputArray descriptors) +{ + + Mat grayImage; + GaussianBlur(image, grayImage, cv::Size(3, 3), 2, 2); + + if (image.type() != CV_8U) cvtColor(image, grayImage, COLOR_BGR2GRAY); + + + + //Remove keypoints very close to the border + KeyPointsFilter::runByImageBorder(keypoints, image.size(), PATCH_SIZE / 2 + half_ssd_size_); + + + descriptors.create((int)keypoints.size(), bytes_, CV_8U); + + test_fn_(grayImage, keypoints, descriptors, sampling_points_, rotationInvariance_, half_ssd_size_); } +} + } } // namespace cv