Commit 922ac1a1 authored by Alexander Alekhin's avatar Alexander Alekhin Committed by GitHub

Merge pull request #9303 from alalek:akaze_update

parents c95a9738 2a8322dd
...@@ -444,6 +444,23 @@ static inline size_t alignSize(size_t sz, int n) ...@@ -444,6 +444,23 @@ static inline size_t alignSize(size_t sz, int n)
return (sz + n-1) & -n; return (sz + n-1) & -n;
} }
/** @brief Integer division with result round up.
Use this function instead of `ceil((float)a / b)` expressions.
@sa alignSize
*/
static inline int divUp(int a, unsigned int b)
{
CV_DbgAssert(a >= 0);
return (a + b - 1) / b;
}
/** @overload */
static inline size_t divUp(size_t a, unsigned int b)
{
return (a + b - 1) / b;
}
/** @brief Enables or disables the optimized code. /** @brief Enables or disables the optimized code.
The function can be used to dynamically turn on and off optimized code (code that uses SSE2, AVX, The function can be used to dynamically turn on and off optimized code (code that uses SSE2, AVX,
......
...@@ -3406,11 +3406,6 @@ static TransposeInplaceFunc transposeInplaceTab[] = ...@@ -3406,11 +3406,6 @@ static TransposeInplaceFunc transposeInplaceTab[] =
#ifdef HAVE_OPENCL #ifdef HAVE_OPENCL
static inline int divUp(int a, int b)
{
return (a + b - 1) / b;
}
static bool ocl_transpose( InputArray _src, OutputArray _dst ) static bool ocl_transpose( InputArray _src, OutputArray _dst )
{ {
const ocl::Device & dev = ocl::Device::getDefault(); const ocl::Device & dev = ocl::Device::getDefault();
......
...@@ -113,12 +113,12 @@ namespace cv ...@@ -113,12 +113,12 @@ namespace cv
if (descriptor_size == 0) if (descriptor_size == 0)
{ {
int t = (6 + 36 + 120) * descriptor_channels; int t = (6 + 36 + 120) * descriptor_channels;
return (int)ceil(t / 8.); return divUp(t, 8);
} }
else else
{ {
// We use the random bit selection length binary descriptor // We use the random bit selection length binary descriptor
return (int)ceil(descriptor_size / 8.); return divUp(descriptor_size, 8);
} }
default: default:
......
...@@ -25,6 +25,8 @@ struct Evolution ...@@ -25,6 +25,8 @@ struct Evolution
octave = 0; octave = 0;
sublevel = 0; sublevel = 0;
sigma_size = 0; sigma_size = 0;
octave_ratio = 0.0f;
border = 0;
} }
UMat Lx, Ly; ///< First order spatial derivatives UMat Lx, Ly; ///< First order spatial derivatives
......
...@@ -68,7 +68,7 @@ void KAZEFeatures::Allocate_Memory_Evolution(void) { ...@@ -68,7 +68,7 @@ void KAZEFeatures::Allocate_Memory_Evolution(void) {
aux.Ldet = Mat::zeros(options_.img_height, options_.img_width, CV_32F); aux.Ldet = Mat::zeros(options_.img_height, options_.img_width, CV_32F);
aux.esigma = options_.soffset*pow((float)2.0f, (float)(j) / (float)(options_.nsublevels)+i); aux.esigma = options_.soffset*pow((float)2.0f, (float)(j) / (float)(options_.nsublevels)+i);
aux.etime = 0.5f*(aux.esigma*aux.esigma); aux.etime = 0.5f*(aux.esigma*aux.esigma);
aux.sigma_size = fRound(aux.esigma); aux.sigma_size = cvRound(aux.esigma);
aux.octave = i; aux.octave = i;
aux.sublevel = j; aux.sublevel = j;
evolution_.push_back(aux); evolution_.push_back(aux);
...@@ -363,10 +363,10 @@ void KAZEFeatures::Determinant_Hessian(std::vector<KeyPoint>& kpts) ...@@ -363,10 +363,10 @@ void KAZEFeatures::Determinant_Hessian(std::vector<KeyPoint>& kpts)
if (is_extremum == true) { if (is_extremum == true) {
// Check that the point is under the image limits for the descriptor computation // Check that the point is under the image limits for the descriptor computation
left_x = fRound(kpts_par_[i][j].pt.x - smax*kpts_par_[i][j].size); left_x = cvRound(kpts_par_[i][j].pt.x - smax*kpts_par_[i][j].size);
right_x = fRound(kpts_par_[i][j].pt.x + smax*kpts_par_[i][j].size); right_x = cvRound(kpts_par_[i][j].pt.x + smax*kpts_par_[i][j].size);
up_y = fRound(kpts_par_[i][j].pt.y - smax*kpts_par_[i][j].size); up_y = cvRound(kpts_par_[i][j].pt.y - smax*kpts_par_[i][j].size);
down_y = fRound(kpts_par_[i][j].pt.y + smax*kpts_par_[i][j].size); down_y = cvRound(kpts_par_[i][j].pt.y + smax*kpts_par_[i][j].size);
if (left_x < 0 || right_x >= evolution_[level].Ldet.cols || if (left_x < 0 || right_x >= evolution_[level].Ldet.cols ||
up_y < 0 || down_y >= evolution_[level].Ldet.rows) { up_y < 0 || down_y >= evolution_[level].Ldet.rows) {
...@@ -587,14 +587,14 @@ void KAZEFeatures::Compute_Main_Orientation(KeyPoint &kpt, const std::vector<TEv ...@@ -587,14 +587,14 @@ void KAZEFeatures::Compute_Main_Orientation(KeyPoint &kpt, const std::vector<TEv
xf = kpt.pt.x; xf = kpt.pt.x;
yf = kpt.pt.y; yf = kpt.pt.y;
level = kpt.class_id; level = kpt.class_id;
s = fRound(kpt.size / 2.0f); s = cvRound(kpt.size / 2.0f);
// Calculate derivatives responses for points within radius of 6*scale // Calculate derivatives responses for points within radius of 6*scale
for (int i = -6; i <= 6; ++i) { for (int i = -6; i <= 6; ++i) {
for (int j = -6; j <= 6; ++j) { for (int j = -6; j <= 6; ++j) {
if (i*i + j*j < 36) { if (i*i + j*j < 36) {
iy = fRound(yf + j*s); iy = cvRound(yf + j*s);
ix = fRound(xf + i*s); ix = cvRound(xf + i*s);
if (iy >= 0 && iy < options.img_height && ix >= 0 && ix < options.img_width) { if (iy >= 0 && iy < options.img_height && ix >= 0 && ix < options.img_width) {
gweight = gaussian(iy - yf, ix - xf, 2.5f*s); gweight = gaussian(iy - yf, ix - xf, 2.5f*s);
...@@ -606,7 +606,7 @@ void KAZEFeatures::Compute_Main_Orientation(KeyPoint &kpt, const std::vector<TEv ...@@ -606,7 +606,7 @@ void KAZEFeatures::Compute_Main_Orientation(KeyPoint &kpt, const std::vector<TEv
resY[idx] = 0.0; resY[idx] = 0.0;
} }
Ang[idx] = getAngle(resX[idx], resY[idx]); Ang[idx] = fastAtan2(resX[idx], resY[idx]) * (float)(CV_PI / 180.0f);
++idx; ++idx;
} }
} }
...@@ -638,7 +638,7 @@ void KAZEFeatures::Compute_Main_Orientation(KeyPoint &kpt, const std::vector<TEv ...@@ -638,7 +638,7 @@ void KAZEFeatures::Compute_Main_Orientation(KeyPoint &kpt, const std::vector<TEv
if (sumX*sumX + sumY*sumY > max) { if (sumX*sumX + sumY*sumY > max) {
// store largest orientation // store largest orientation
max = sumX*sumX + sumY*sumY; max = sumX*sumX + sumY*sumY;
kpt.angle = getAngle(sumX, sumY) * 180.f / static_cast<float>(CV_PI); kpt.angle = fastAtan2(sumX, sumY);
} }
} }
} }
...@@ -676,7 +676,7 @@ void KAZE_Descriptor_Invoker::Get_KAZE_Upright_Descriptor_64(const KeyPoint &kpt ...@@ -676,7 +676,7 @@ void KAZE_Descriptor_Invoker::Get_KAZE_Upright_Descriptor_64(const KeyPoint &kpt
// Get the information from the keypoint // Get the information from the keypoint
yf = kpt.pt.y; yf = kpt.pt.y;
xf = kpt.pt.x; xf = kpt.pt.x;
scale = fRound(kpt.size / 2.0f); scale = cvRound(kpt.size / 2.0f);
level = kpt.class_id; level = kpt.class_id;
i = -8; i = -8;
...@@ -804,8 +804,8 @@ void KAZE_Descriptor_Invoker::Get_KAZE_Descriptor_64(const KeyPoint &kpt, float ...@@ -804,8 +804,8 @@ void KAZE_Descriptor_Invoker::Get_KAZE_Descriptor_64(const KeyPoint &kpt, float
// Get the information from the keypoint // Get the information from the keypoint
yf = kpt.pt.y; yf = kpt.pt.y;
xf = kpt.pt.x; xf = kpt.pt.x;
scale = fRound(kpt.size / 2.0f); scale = cvRound(kpt.size / 2.0f);
angle = (kpt.angle * static_cast<float>(CV_PI)) / 180.f; angle = kpt.angle * static_cast<float>(CV_PI / 180.f);
level = kpt.class_id; level = kpt.class_id;
co = cos(angle); co = cos(angle);
si = sin(angle); si = sin(angle);
...@@ -843,13 +843,13 @@ void KAZE_Descriptor_Invoker::Get_KAZE_Descriptor_64(const KeyPoint &kpt, float ...@@ -843,13 +843,13 @@ void KAZE_Descriptor_Invoker::Get_KAZE_Descriptor_64(const KeyPoint &kpt, float
// Get the gaussian weighted x and y responses // Get the gaussian weighted x and y responses
gauss_s1 = gaussian(xs - sample_x, ys - sample_y, 2.5f*scale); gauss_s1 = gaussian(xs - sample_x, ys - sample_y, 2.5f*scale);
y1 = fRound(sample_y - 0.5f); y1 = cvFloor(sample_y);
x1 = fRound(sample_x - 0.5f); x1 = cvFloor(sample_x);
checkDescriptorLimits(x1, y1, options_.img_width, options_.img_height); checkDescriptorLimits(x1, y1, options_.img_width, options_.img_height);
y2 = (int)(sample_y + 0.5f); y2 = y1 + 1;
x2 = (int)(sample_x + 0.5f); x2 = x1 + 1;
checkDescriptorLimits(x2, y2, options_.img_width, options_.img_height); checkDescriptorLimits(x2, y2, options_.img_width, options_.img_height);
...@@ -935,7 +935,7 @@ void KAZE_Descriptor_Invoker::Get_KAZE_Upright_Descriptor_128(const KeyPoint &kp ...@@ -935,7 +935,7 @@ void KAZE_Descriptor_Invoker::Get_KAZE_Upright_Descriptor_128(const KeyPoint &kp
// Get the information from the keypoint // Get the information from the keypoint
yf = kpt.pt.y; yf = kpt.pt.y;
xf = kpt.pt.x; xf = kpt.pt.x;
scale = fRound(kpt.size / 2.0f); scale = cvRound(kpt.size / 2.0f);
level = kpt.class_id; level = kpt.class_id;
i = -8; i = -8;
...@@ -1087,8 +1087,8 @@ void KAZE_Descriptor_Invoker::Get_KAZE_Descriptor_128(const KeyPoint &kpt, float ...@@ -1087,8 +1087,8 @@ void KAZE_Descriptor_Invoker::Get_KAZE_Descriptor_128(const KeyPoint &kpt, float
// Get the information from the keypoint // Get the information from the keypoint
yf = kpt.pt.y; yf = kpt.pt.y;
xf = kpt.pt.x; xf = kpt.pt.x;
scale = fRound(kpt.size / 2.0f); scale = cvRound(kpt.size / 2.0f);
angle = (kpt.angle * static_cast<float>(CV_PI)) / 180.f; angle = kpt.angle * static_cast<float>(CV_PI / 180.f);
level = kpt.class_id; level = kpt.class_id;
co = cos(angle); co = cos(angle);
si = sin(angle); si = sin(angle);
...@@ -1129,13 +1129,13 @@ void KAZE_Descriptor_Invoker::Get_KAZE_Descriptor_128(const KeyPoint &kpt, float ...@@ -1129,13 +1129,13 @@ void KAZE_Descriptor_Invoker::Get_KAZE_Descriptor_128(const KeyPoint &kpt, float
// Get the gaussian weighted x and y responses // Get the gaussian weighted x and y responses
gauss_s1 = gaussian(xs - sample_x, ys - sample_y, 2.5f*scale); gauss_s1 = gaussian(xs - sample_x, ys - sample_y, 2.5f*scale);
y1 = fRound(sample_y - 0.5f); y1 = cvFloor(sample_y);
x1 = fRound(sample_x - 0.5f); x1 = cvFloor(sample_x);
checkDescriptorLimits(x1, y1, options_.img_width, options_.img_height); checkDescriptorLimits(x1, y1, options_.img_width, options_.img_height);
y2 = (int)(sample_y + 0.5f); y2 = y1 + 1;
x2 = (int)(sample_x + 0.5f); x2 = x1 + 1;
checkDescriptorLimits(x2, y2, options_.img_width, options_.img_height); checkDescriptorLimits(x2, y2, options_.img_width, options_.img_height);
......
...@@ -72,7 +72,7 @@ int fed_tau_by_cycle_time(const float& t, const float& tau_max, ...@@ -72,7 +72,7 @@ int fed_tau_by_cycle_time(const float& t, const float& tau_max,
float scale = 0.0; // Ratio of t we search to maximal t float scale = 0.0; // Ratio of t we search to maximal t
// Compute necessary number of time steps // Compute necessary number of time steps
n = (int)(ceilf(sqrtf(3.0f*t/tau_max+0.25f)-0.5f-1.0e-8f)+ 0.5f); n = cvCeil(sqrtf(3.0f*t/tau_max+0.25f)-0.5f-1.0e-8f);
scale = 3.0f*t/(tau_max*(float)(n*(n+1))); scale = 3.0f*t/(tau_max*(float)(n*(n+1)));
// Call internal FED time step creation routine // Call internal FED time step creation routine
......
...@@ -49,7 +49,7 @@ void gaussian_2D_convolution(const cv::Mat& src, cv::Mat& dst, int ksize_x, int ...@@ -49,7 +49,7 @@ void gaussian_2D_convolution(const cv::Mat& src, cv::Mat& dst, int ksize_x, int
// Compute an appropriate kernel size according to the specified sigma // Compute an appropriate kernel size according to the specified sigma
if (sigma > ksize_x || sigma > ksize_y || ksize_x == 0 || ksize_y == 0) { if (sigma > ksize_x || sigma > ksize_y || ksize_x == 0 || ksize_y == 0) {
ksize_x_ = (int)ceil(2.0f*(1.0f + (sigma - 0.8f) / (0.3f))); ksize_x_ = cvCeil(2.0f*(1.0f + (sigma - 0.8f) / (0.3f)));
ksize_y_ = ksize_x_; ksize_y_ = ksize_x_;
} }
......
#ifndef __OPENCV_FEATURES_2D_KAZE_UTILS_H__ #ifndef __OPENCV_FEATURES_2D_KAZE_UTILS_H__
#define __OPENCV_FEATURES_2D_KAZE_UTILS_H__ #define __OPENCV_FEATURES_2D_KAZE_UTILS_H__
/* ************************************************************************* */
/**
* @brief This function computes the angle from the vector given by (X Y). From 0 to 2*Pi
*/
inline float getAngle(float x, float y) {
if (x >= 0 && y >= 0) {
return atanf(y / x);
}
if (x < 0 && y >= 0) {
return static_cast<float>(CV_PI)-atanf(-y / x);
}
if (x < 0 && y < 0) {
return static_cast<float>(CV_PI)+atanf(y / x);
}
if (x >= 0 && y < 0) {
return static_cast<float>(2.0 * CV_PI) - atanf(-y / x);
}
return 0;
}
/* ************************************************************************* */ /* ************************************************************************* */
/** /**
* @brief This function computes the value of a 2D Gaussian function * @brief This function computes the value of a 2D Gaussian function
...@@ -64,34 +39,4 @@ inline void checkDescriptorLimits(int &x, int &y, int width, int height) { ...@@ -64,34 +39,4 @@ inline void checkDescriptorLimits(int &x, int &y, int width, int height) {
} }
} }
/* ************************************************************************* */
/**
* @brief This funtion rounds float to nearest integer
* @param flt Input float
* @return dst Nearest integer
*/
inline int fRound(float flt) {
return (int)(flt + 0.5f);
}
/* ************************************************************************* */
/**
* @brief Exponentiation by squaring
* @param flt Exponentiation base
* @return dst Exponentiation value
*/
inline int fastpow(int base, int exp) {
int res = 1;
while(exp > 0) {
if(exp & 1) {
exp--;
res *= base;
} else {
exp /= 2;
base *= base;
}
}
return res;
}
#endif #endif
...@@ -11,7 +11,7 @@ using std::tr1::make_tuple; ...@@ -11,7 +11,7 @@ using std::tr1::make_tuple;
using std::tr1::get; using std::tr1::get;
using namespace testing; using namespace testing;
#define SHOW_DEBUG_LOG 0 #define SHOW_DEBUG_LOG 1
typedef std::tr1::tuple<std::string, Ptr<FeatureDetector>, Ptr<DescriptorExtractor>, float> typedef std::tr1::tuple<std::string, Ptr<FeatureDetector>, Ptr<DescriptorExtractor>, float>
String_FeatureDetector_DescriptorExtractor_Float_t; String_FeatureDetector_DescriptorExtractor_Float_t;
...@@ -72,7 +72,7 @@ TEST_P(DescriptorRotationInvariance, rotation) ...@@ -72,7 +72,7 @@ TEST_P(DescriptorRotationInvariance, rotation)
vector<KeyPoint> keypoints0; vector<KeyPoint> keypoints0;
Mat descriptors0; Mat descriptors0;
featureDetector->detect(image0, keypoints0, mask0); featureDetector->detect(image0, keypoints0, mask0);
std::cout << "Intial keypoints: " << keypoints0.size() << std::endl; std::cout << "Keypoints: " << keypoints0.size() << std::endl;
EXPECT_GE(keypoints0.size(), 15u); EXPECT_GE(keypoints0.size(), 15u);
descriptorExtractor->compute(image0, keypoints0, descriptors0); descriptorExtractor->compute(image0, keypoints0, descriptors0);
...@@ -109,7 +109,7 @@ TEST_P(DescriptorRotationInvariance, rotation) ...@@ -109,7 +109,7 @@ TEST_P(DescriptorRotationInvariance, rotation)
#if SHOW_DEBUG_LOG #if SHOW_DEBUG_LOG
std::cout std::cout
<< "angle = " << angle << "angle = " << angle
<< ", keypoints = " << keypoints1.size() << ", inliers = " << descInliersCount
<< ", descInliersRatio = " << static_cast<float>(descInliersCount) / keypoints0.size() << ", descInliersRatio = " << static_cast<float>(descInliersCount) / keypoints0.size()
<< std::endl; << std::endl;
#endif #endif
...@@ -121,6 +121,7 @@ TEST_P(DescriptorScaleInvariance, scale) ...@@ -121,6 +121,7 @@ TEST_P(DescriptorScaleInvariance, scale)
{ {
vector<KeyPoint> keypoints0; vector<KeyPoint> keypoints0;
featureDetector->detect(image0, keypoints0); featureDetector->detect(image0, keypoints0);
std::cout << "Keypoints: " << keypoints0.size() << std::endl;
EXPECT_GE(keypoints0.size(), 15u); EXPECT_GE(keypoints0.size(), 15u);
Mat descriptors0; Mat descriptors0;
descriptorExtractor->compute(image0, keypoints0, descriptors0); descriptorExtractor->compute(image0, keypoints0, descriptors0);
...@@ -159,6 +160,7 @@ TEST_P(DescriptorScaleInvariance, scale) ...@@ -159,6 +160,7 @@ TEST_P(DescriptorScaleInvariance, scale)
#if SHOW_DEBUG_LOG #if SHOW_DEBUG_LOG
std::cout std::cout
<< "scale = " << scale << "scale = " << scale
<< ", inliers = " << descInliersCount
<< ", descInliersRatio = " << static_cast<float>(descInliersCount) / keypoints0.size() << ", descInliersRatio = " << static_cast<float>(descInliersCount) / keypoints0.size()
<< std::endl; << std::endl;
#endif #endif
......
...@@ -56,6 +56,7 @@ static void writeMatInBin( const Mat& mat, const string& filename ) ...@@ -56,6 +56,7 @@ static void writeMatInBin( const Mat& mat, const string& filename )
FILE* f = fopen( filename.c_str(), "wb"); FILE* f = fopen( filename.c_str(), "wb");
if( f ) if( f )
{ {
CV_Assert(4 == sizeof(int));
int type = mat.type(); int type = mat.type();
fwrite( (void*)&mat.rows, sizeof(int), 1, f ); fwrite( (void*)&mat.rows, sizeof(int), 1, f );
fwrite( (void*)&mat.cols, sizeof(int), 1, f ); fwrite( (void*)&mat.cols, sizeof(int), 1, f );
...@@ -72,6 +73,7 @@ static Mat readMatFromBin( const string& filename ) ...@@ -72,6 +73,7 @@ static Mat readMatFromBin( const string& filename )
FILE* f = fopen( filename.c_str(), "rb" ); FILE* f = fopen( filename.c_str(), "rb" );
if( f ) if( f )
{ {
CV_Assert(4 == sizeof(int));
int rows, cols, type, dataSize; int rows, cols, type, dataSize;
size_t elements_read1 = fread( (void*)&rows, sizeof(int), 1, f ); size_t elements_read1 = fread( (void*)&rows, sizeof(int), 1, f );
size_t elements_read2 = fread( (void*)&cols, sizeof(int), 1, f ); size_t elements_read2 = fread( (void*)&cols, sizeof(int), 1, f );
...@@ -123,24 +125,37 @@ protected: ...@@ -123,24 +125,37 @@ protected:
CV_Assert( DataType<ValueType>::type == validDescriptors.type() ); CV_Assert( DataType<ValueType>::type == validDescriptors.type() );
int dimension = validDescriptors.cols; int dimension = validDescriptors.cols;
DistanceType curMaxDist = std::numeric_limits<DistanceType>::min(); DistanceType curMaxDist = 0;
size_t exact_count = 0, failed_count = 0;
for( int y = 0; y < validDescriptors.rows; y++ ) for( int y = 0; y < validDescriptors.rows; y++ )
{ {
DistanceType dist = distance( validDescriptors.ptr<ValueType>(y), calcDescriptors.ptr<ValueType>(y), dimension ); DistanceType dist = distance( validDescriptors.ptr<ValueType>(y), calcDescriptors.ptr<ValueType>(y), dimension );
if (dist == 0)
exact_count++;
if( dist > curMaxDist ) if( dist > curMaxDist )
{
if (dist > maxDist)
failed_count++;
curMaxDist = dist; curMaxDist = dist;
}
#if 0
if (dist > 0)
{
std::cout << "i=" << y << " fail_count=" << failed_count << " dist=" << dist << std::endl;
std::cout << "valid: " << validDescriptors.row(y) << std::endl;
std::cout << " calc: " << calcDescriptors.row(y) << std::endl;
}
#endif
} }
float exact_percents = (100 * (float)exact_count / validDescriptors.rows);
float failed_percents = (100 * (float)failed_count / validDescriptors.rows);
stringstream ss; stringstream ss;
ss << "Max distance between valid and computed descriptors " << curMaxDist; ss << "Exact count (dist == 0): " << exact_count << " (" << (int)exact_percents << "%)" << std::endl
if( curMaxDist <= maxDist ) << "Failed count (dist > " << maxDist << "): " << failed_count << " (" << (int)failed_percents << "%)" << std::endl
ss << "." << endl; << "Max distance between valid and computed descriptors (" << validDescriptors.size() << "): " << curMaxDist;
else EXPECT_LE(failed_percents, 20.0f);
{ std::cout << ss.str() << std::endl;
ss << ">" << maxDist << " - bad accuracy!"<< endl;
ts->set_failed_test_info( cvtest::TS::FAIL_BAD_ACCURACY );
}
ts->printf(cvtest::TS::LOG, ss.str().c_str() );
} }
void emptyDataTest() void emptyDataTest()
...@@ -202,22 +217,57 @@ protected: ...@@ -202,22 +217,57 @@ protected:
ts->set_failed_test_info( cvtest::TS::FAIL_INVALID_TEST_DATA ); ts->set_failed_test_info( cvtest::TS::FAIL_INVALID_TEST_DATA );
return; return;
} }
const std::string keypoints_filename = string(ts->get_data_path()) +
(detector.empty()
? (FEATURES2D_DIR + "/" + std::string("keypoints.xml.gz"))
: (DESCRIPTOR_DIR + "/" + name + "_keypoints.xml.gz"));
FileStorage fs(keypoints_filename, FileStorage::READ);
vector<KeyPoint> keypoints; vector<KeyPoint> keypoints;
FileStorage fs( string(ts->get_data_path()) + FEATURES2D_DIR + "/keypoints.xml.gz", FileStorage::READ ); EXPECT_TRUE(fs.isOpened()) << "Keypoint testdata is missing. Re-computing and re-writing keypoints testdata...";
if(!detector.empty()) { if (!fs.isOpened())
detector->detect(img, keypoints); {
} else { fs.open(keypoints_filename, FileStorage::WRITE);
read( fs.getFirstTopLevelNode(), keypoints ); ASSERT_TRUE(fs.isOpened()) << "File for writting keypoints can not be opened.";
if (detector.empty())
{
Ptr<ORB> fd = ORB::create();
fd->detect(img, keypoints);
}
else
{
detector->detect(img, keypoints);
}
write(fs, "keypoints", keypoints);
fs.release();
} }
if(!keypoints.empty()) else
{
read(fs.getFirstTopLevelNode(), keypoints);
fs.release();
}
if(!detector.empty())
{
vector<KeyPoint> calcKeypoints;
detector->detect(img, calcKeypoints);
// TODO validate received keypoints
int diff = abs((int)calcKeypoints.size() - (int)keypoints.size());
if (diff > 0)
{
std::cout << "Keypoints difference: " << diff << std::endl;
EXPECT_LE(diff, (int)(keypoints.size() * 0.03f));
}
}
ASSERT_FALSE(keypoints.empty());
{ {
Mat calcDescriptors; Mat calcDescriptors;
double t = (double)getTickCount(); double t = (double)getTickCount();
dextractor->compute( img, keypoints, calcDescriptors ); dextractor->compute(img, keypoints, calcDescriptors);
t = getTickCount() - t; t = getTickCount() - t;
ts->printf(cvtest::TS::LOG, "\nAverage time of computing one descriptor = %g ms.\n", t/((double)getTickFrequency()*1000.)/calcDescriptors.rows); ts->printf(cvtest::TS::LOG, "\nAverage time of computing one descriptor = %g ms.\n", t/((double)getTickFrequency()*1000.)/calcDescriptors.rows);
if( calcDescriptors.rows != (int)keypoints.size() ) if (calcDescriptors.rows != (int)keypoints.size())
{ {
ts->printf( cvtest::TS::LOG, "Count of computed descriptors and keypoints count must be equal.\n" ); ts->printf( cvtest::TS::LOG, "Count of computed descriptors and keypoints count must be equal.\n" );
ts->printf( cvtest::TS::LOG, "Count of keypoints is %d.\n", (int)keypoints.size() ); ts->printf( cvtest::TS::LOG, "Count of keypoints is %d.\n", (int)keypoints.size() );
...@@ -226,7 +276,7 @@ protected: ...@@ -226,7 +276,7 @@ protected:
return; return;
} }
if( calcDescriptors.cols != dextractor->descriptorSize() || calcDescriptors.type() != dextractor->descriptorType() ) if (calcDescriptors.cols != dextractor->descriptorSize() || calcDescriptors.type() != dextractor->descriptorType())
{ {
ts->printf( cvtest::TS::LOG, "Incorrect descriptor size or descriptor type.\n" ); ts->printf( cvtest::TS::LOG, "Incorrect descriptor size or descriptor type.\n" );
ts->printf( cvtest::TS::LOG, "Expected size is %d.\n", dextractor->descriptorSize() ); ts->printf( cvtest::TS::LOG, "Expected size is %d.\n", dextractor->descriptorSize() );
...@@ -239,33 +289,14 @@ protected: ...@@ -239,33 +289,14 @@ protected:
// TODO read and write descriptor extractor parameters and check them // TODO read and write descriptor extractor parameters and check them
Mat validDescriptors = readDescriptors(); Mat validDescriptors = readDescriptors();
if( !validDescriptors.empty() ) EXPECT_FALSE(validDescriptors.empty()) << "Descriptors testdata is missing. Re-writing descriptors testdata...";
compareDescriptors( validDescriptors, calcDescriptors ); if (!validDescriptors.empty())
else
{ {
if( !writeDescriptors( calcDescriptors ) ) compareDescriptors(validDescriptors, calcDescriptors);
{
ts->printf( cvtest::TS::LOG, "Descriptors can not be written.\n" );
ts->set_failed_test_info( cvtest::TS::FAIL_INVALID_TEST_DATA );
return;
}
}
}
if(!fs.isOpened())
{
ts->printf( cvtest::TS::LOG, "Compute and write keypoints.\n" );
fs.open( string(ts->get_data_path()) + FEATURES2D_DIR + "/keypoints.xml.gz", FileStorage::WRITE );
if( fs.isOpened() )
{
Ptr<ORB> fd = ORB::create();
fd->detect(img, keypoints);
write( fs, "keypoints", keypoints );
} }
else else
{ {
ts->printf(cvtest::TS::LOG, "File for writting keypoints can not be opened.\n"); ASSERT_TRUE(writeDescriptors(calcDescriptors)) << "Descriptors can not be written.";
ts->set_failed_test_info( cvtest::TS::FAIL_INVALID_TEST_DATA );
return;
} }
} }
} }
...@@ -344,7 +375,7 @@ TEST( Features2d_DescriptorExtractor_KAZE, regression ) ...@@ -344,7 +375,7 @@ TEST( Features2d_DescriptorExtractor_KAZE, regression )
TEST( Features2d_DescriptorExtractor_AKAZE, regression ) TEST( Features2d_DescriptorExtractor_AKAZE, regression )
{ {
CV_DescriptorExtractorTest<Hamming> test( "descriptor-akaze", CV_DescriptorExtractorTest<Hamming> test( "descriptor-akaze",
(CV_DescriptorExtractorTest<Hamming>::DistanceType)12.f, (CV_DescriptorExtractorTest<Hamming>::DistanceType)(486*0.05f),
AKAZE::create(), AKAZE::create(),
Hamming(), AKAZE::create()); Hamming(), AKAZE::create());
test.safe_run(); test.safe_run();
......
...@@ -11,7 +11,7 @@ using std::tr1::make_tuple; ...@@ -11,7 +11,7 @@ using std::tr1::make_tuple;
using std::tr1::get; using std::tr1::get;
using namespace testing; using namespace testing;
#define SHOW_DEBUG_LOG 0 #define SHOW_DEBUG_LOG 1
typedef std::tr1::tuple<std::string, Ptr<FeatureDetector>, float, float> String_FeatureDetector_Float_Float_t; typedef std::tr1::tuple<std::string, Ptr<FeatureDetector>, float, float> String_FeatureDetector_Float_Float_t;
const static std::string IMAGE_TSUKUBA = "features2d/tsukuba.png"; const static std::string IMAGE_TSUKUBA = "features2d/tsukuba.png";
......
...@@ -23,11 +23,6 @@ enum ...@@ -23,11 +23,6 @@ enum
CTA_SIZE_DEFAULT = 256 CTA_SIZE_DEFAULT = 256
}; };
static int divUp(int a, int b)
{
return (a + b - 1) / b;
}
template <typename FT, typename ST, typename WT> template <typename FT, typename ST, typename WT>
static bool ocl_calcAlmostDist2Weight(UMat & almostDist2Weight, static bool ocl_calcAlmostDist2Weight(UMat & almostDist2Weight,
int searchWindowSize, int templateWindowSize, int searchWindowSize, int templateWindowSize,
......
...@@ -102,7 +102,7 @@ PERF_TEST_P(stitchDatasets, affine, testing::Combine(AFFINE_DATASETS, TEST_DETEC ...@@ -102,7 +102,7 @@ PERF_TEST_P(stitchDatasets, affine, testing::Combine(AFFINE_DATASETS, TEST_DETEC
Mat pano; Mat pano;
vector<Mat> imgs; vector<Mat> imgs;
int width, height, allowed_diff = 10; int width, height, allowed_diff = 20;
Ptr<detail::FeaturesFinder> featuresFinder = getFeatureFinder(detector); Ptr<detail::FeaturesFinder> featuresFinder = getFeatureFinder(detector);
if(dataset == "budapest") if(dataset == "budapest")
...@@ -117,7 +117,7 @@ PERF_TEST_P(stitchDatasets, affine, testing::Combine(AFFINE_DATASETS, TEST_DETEC ...@@ -117,7 +117,7 @@ PERF_TEST_P(stitchDatasets, affine, testing::Combine(AFFINE_DATASETS, TEST_DETEC
height = 1158; height = 1158;
// this dataset is big, the results between surf and orb differ slightly, // this dataset is big, the results between surf and orb differ slightly,
// but both are still good // but both are still good
allowed_diff = 27; allowed_diff = 50;
} }
else if (dataset == "newspaper") else if (dataset == "newspaper")
{ {
......
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