mirror of
https://github.com/opencv/opencv.git
synced 2025-06-18 08:05:23 +08:00
Merge pull request #9303 from alalek:akaze_update
This commit is contained in:
commit
922ac1a1ec
@ -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[] =
|
|||||||
|
|
||||||
#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
|
|||||||
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:
|
||||||
|
@ -74,12 +74,12 @@ void AKAZEFeatures::Allocate_Memory_Evolution(void) {
|
|||||||
Evolution step;
|
Evolution step;
|
||||||
step.size = Size(level_width, level_height);
|
step.size = Size(level_width, level_height);
|
||||||
step.esigma = options_.soffset*pow(2.f, (float)(j) / (float)(options_.nsublevels) + i);
|
step.esigma = options_.soffset*pow(2.f, (float)(j) / (float)(options_.nsublevels) + i);
|
||||||
step.sigma_size = fRound(step.esigma * options_.derivative_factor / power); // In fact sigma_size only depends on j
|
step.sigma_size = cvRound(step.esigma * options_.derivative_factor / power); // In fact sigma_size only depends on j
|
||||||
step.etime = 0.5f * (step.esigma * step.esigma);
|
step.etime = 0.5f * (step.esigma * step.esigma);
|
||||||
step.octave = i;
|
step.octave = i;
|
||||||
step.sublevel = j;
|
step.sublevel = j;
|
||||||
step.octave_ratio = (float)power;
|
step.octave_ratio = (float)power;
|
||||||
step.border = fRound(smax * step.sigma_size) + 1;
|
step.border = cvRound(smax * step.sigma_size) + 1;
|
||||||
|
|
||||||
evolution_.push_back(step);
|
evolution_.push_back(step);
|
||||||
}
|
}
|
||||||
@ -106,7 +106,7 @@ void AKAZEFeatures::Allocate_Memory_Evolution(void) {
|
|||||||
*/
|
*/
|
||||||
static inline int getGaussianKernelSize(float sigma) {
|
static inline int getGaussianKernelSize(float sigma) {
|
||||||
// Compute an appropriate kernel size according to the specified sigma
|
// Compute an appropriate kernel size according to the specified sigma
|
||||||
int ksize = (int)ceil(2.0f*(1.0f + (sigma - 0.8f) / (0.3f)));
|
int ksize = (int)cvCeil(2.0f*(1.0f + (sigma - 0.8f) / (0.3f)));
|
||||||
ksize |= 1; // kernel should be odd
|
ksize |= 1; // kernel should be odd
|
||||||
return ksize;
|
return ksize;
|
||||||
}
|
}
|
||||||
@ -890,11 +890,11 @@ public:
|
|||||||
{
|
{
|
||||||
for (int i = range.start; i < range.end; i++)
|
for (int i = range.start; i < range.end; i++)
|
||||||
{
|
{
|
||||||
Get_SURF_Descriptor_Upright_64((*keypoints_)[i], descriptors_->ptr<float>(i));
|
Get_SURF_Descriptor_Upright_64((*keypoints_)[i], descriptors_->ptr<float>(i), descriptors_->cols);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Get_SURF_Descriptor_Upright_64(const KeyPoint& kpt, float* desc) const;
|
void Get_SURF_Descriptor_Upright_64(const KeyPoint& kpt, float* desc, int desc_size) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<KeyPoint>* keypoints_;
|
std::vector<KeyPoint>* keypoints_;
|
||||||
@ -916,11 +916,11 @@ public:
|
|||||||
{
|
{
|
||||||
for (int i = range.start; i < range.end; i++)
|
for (int i = range.start; i < range.end; i++)
|
||||||
{
|
{
|
||||||
Get_SURF_Descriptor_64((*keypoints_)[i], descriptors_->ptr<float>(i));
|
Get_SURF_Descriptor_64((*keypoints_)[i], descriptors_->ptr<float>(i), descriptors_->cols);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Get_SURF_Descriptor_64(const KeyPoint& kpt, float* desc) const;
|
void Get_SURF_Descriptor_64(const KeyPoint& kpt, float* desc, int desc_size) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<KeyPoint>* keypoints_;
|
std::vector<KeyPoint>* keypoints_;
|
||||||
@ -942,11 +942,11 @@ public:
|
|||||||
{
|
{
|
||||||
for (int i = range.start; i < range.end; i++)
|
for (int i = range.start; i < range.end; i++)
|
||||||
{
|
{
|
||||||
Get_MSURF_Upright_Descriptor_64((*keypoints_)[i], descriptors_->ptr<float>(i));
|
Get_MSURF_Upright_Descriptor_64((*keypoints_)[i], descriptors_->ptr<float>(i), descriptors_->cols);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Get_MSURF_Upright_Descriptor_64(const KeyPoint& kpt, float* desc) const;
|
void Get_MSURF_Upright_Descriptor_64(const KeyPoint& kpt, float* desc, int desc_size) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<KeyPoint>* keypoints_;
|
std::vector<KeyPoint>* keypoints_;
|
||||||
@ -968,11 +968,11 @@ public:
|
|||||||
{
|
{
|
||||||
for (int i = range.start; i < range.end; i++)
|
for (int i = range.start; i < range.end; i++)
|
||||||
{
|
{
|
||||||
Get_MSURF_Descriptor_64((*keypoints_)[i], descriptors_->ptr<float>(i));
|
Get_MSURF_Descriptor_64((*keypoints_)[i], descriptors_->ptr<float>(i), descriptors_->cols);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Get_MSURF_Descriptor_64(const KeyPoint& kpt, float* desc) const;
|
void Get_MSURF_Descriptor_64(const KeyPoint& kpt, float* desc, int desc_size) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<KeyPoint>* keypoints_;
|
std::vector<KeyPoint>* keypoints_;
|
||||||
@ -995,11 +995,11 @@ public:
|
|||||||
{
|
{
|
||||||
for (int i = range.start; i < range.end; i++)
|
for (int i = range.start; i < range.end; i++)
|
||||||
{
|
{
|
||||||
Get_Upright_MLDB_Full_Descriptor((*keypoints_)[i], descriptors_->ptr<unsigned char>(i));
|
Get_Upright_MLDB_Full_Descriptor((*keypoints_)[i], descriptors_->ptr<unsigned char>(i), descriptors_->cols);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Get_Upright_MLDB_Full_Descriptor(const KeyPoint& kpt, unsigned char* desc) const;
|
void Get_Upright_MLDB_Full_Descriptor(const KeyPoint& kpt, unsigned char* desc, int desc_size) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<KeyPoint>* keypoints_;
|
std::vector<KeyPoint>* keypoints_;
|
||||||
@ -1030,11 +1030,11 @@ public:
|
|||||||
{
|
{
|
||||||
for (int i = range.start; i < range.end; i++)
|
for (int i = range.start; i < range.end; i++)
|
||||||
{
|
{
|
||||||
Get_Upright_MLDB_Descriptor_Subset((*keypoints_)[i], descriptors_->ptr<unsigned char>(i));
|
Get_Upright_MLDB_Descriptor_Subset((*keypoints_)[i], descriptors_->ptr<unsigned char>(i), descriptors_->cols);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Get_Upright_MLDB_Descriptor_Subset(const KeyPoint& kpt, unsigned char* desc) const;
|
void Get_Upright_MLDB_Descriptor_Subset(const KeyPoint& kpt, unsigned char* desc, int desc_size) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<KeyPoint>* keypoints_;
|
std::vector<KeyPoint>* keypoints_;
|
||||||
@ -1061,11 +1061,11 @@ public:
|
|||||||
{
|
{
|
||||||
for (int i = range.start; i < range.end; i++)
|
for (int i = range.start; i < range.end; i++)
|
||||||
{
|
{
|
||||||
Get_MLDB_Full_Descriptor((*keypoints_)[i], descriptors_->ptr<unsigned char>(i));
|
Get_MLDB_Full_Descriptor((*keypoints_)[i], descriptors_->ptr<unsigned char>(i), descriptors_->cols);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Get_MLDB_Full_Descriptor(const KeyPoint& kpt, unsigned char* desc) const;
|
void Get_MLDB_Full_Descriptor(const KeyPoint& kpt, unsigned char* desc, int desc_size) const;
|
||||||
void MLDB_Fill_Values(float* values, int sample_step, int level,
|
void MLDB_Fill_Values(float* values, int sample_step, int level,
|
||||||
float xf, float yf, float co, float si, float scale) const;
|
float xf, float yf, float co, float si, float scale) const;
|
||||||
void MLDB_Binary_Comparisons(float* values, unsigned char* desc,
|
void MLDB_Binary_Comparisons(float* values, unsigned char* desc,
|
||||||
@ -1100,11 +1100,11 @@ public:
|
|||||||
{
|
{
|
||||||
for (int i = range.start; i < range.end; i++)
|
for (int i = range.start; i < range.end; i++)
|
||||||
{
|
{
|
||||||
Get_MLDB_Descriptor_Subset((*keypoints_)[i], descriptors_->ptr<unsigned char>(i));
|
Get_MLDB_Descriptor_Subset((*keypoints_)[i], descriptors_->ptr<unsigned char>(i), descriptors_->cols);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Get_MLDB_Descriptor_Subset(const KeyPoint& kpt, unsigned char* desc) const;
|
void Get_MLDB_Descriptor_Subset(const KeyPoint& kpt, unsigned char* desc, int desc_size) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<KeyPoint>* keypoints_;
|
std::vector<KeyPoint>* keypoints_;
|
||||||
@ -1131,20 +1131,17 @@ void AKAZEFeatures::Compute_Descriptors(std::vector<KeyPoint>& kpts, OutputArray
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Allocate memory for the matrix with the descriptors
|
// Allocate memory for the matrix with the descriptors
|
||||||
if (options_.descriptor < AKAZE::DESCRIPTOR_MLDB_UPRIGHT) {
|
int descriptor_size = 64;
|
||||||
descriptors.create((int)kpts.size(), 64, CV_32FC1);
|
int descriptor_type = CV_32FC1;
|
||||||
}
|
if (options_.descriptor >= AKAZE::DESCRIPTOR_MLDB_UPRIGHT)
|
||||||
else {
|
{
|
||||||
// We use the full length binary descriptor -> 486 bits
|
int descriptor_bits = (options_.descriptor_size == 0)
|
||||||
if (options_.descriptor_size == 0) {
|
? (6 + 36 + 120)*options_.descriptor_channels // the full length binary descriptor -> 486 bits
|
||||||
int t = (6 + 36 + 120)*options_.descriptor_channels;
|
: options_.descriptor_size; // the random bit selection length binary descriptor
|
||||||
descriptors.create((int)kpts.size(), (int)ceil(t / 8.), CV_8UC1);
|
descriptor_size = divUp(descriptor_bits, 8);
|
||||||
}
|
descriptor_type = CV_8UC1;
|
||||||
else {
|
|
||||||
// We use the random bit selection length binary descriptor
|
|
||||||
descriptors.create((int)kpts.size(), (int)ceil(options_.descriptor_size / 8.), CV_8UC1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
descriptors.create((int)kpts.size(), descriptor_size, descriptor_type);
|
||||||
|
|
||||||
Mat desc = descriptors.getMat();
|
Mat desc = descriptors.getMat();
|
||||||
|
|
||||||
@ -1208,12 +1205,11 @@ void Sample_Derivative_Response_Radius6(const Mat &Lx, const Mat &Ly,
|
|||||||
{ 0.00344629f, 0.00318132f, 0.00250252f, 0.00167749f, 0.00095820f, 0.00046640f, 0.00019346f },
|
{ 0.00344629f, 0.00318132f, 0.00250252f, 0.00167749f, 0.00095820f, 0.00046640f, 0.00019346f },
|
||||||
{ 0.00142946f, 0.00131956f, 0.00103800f, 0.00069579f, 0.00039744f, 0.00019346f, 0.00008024f }
|
{ 0.00142946f, 0.00131956f, 0.00103800f, 0.00069579f, 0.00039744f, 0.00019346f, 0.00008024f }
|
||||||
};
|
};
|
||||||
static const int id[] = { 6, 5, 4, 3, 2, 1, 0, 1, 2, 3, 4, 5, 6 };
|
|
||||||
static const struct gtable
|
static const struct gtable
|
||||||
{
|
{
|
||||||
float weight[109];
|
float weight[109];
|
||||||
int8_t xidx[109];
|
int xidx[109];
|
||||||
int8_t yidx[109];
|
int yidx[109];
|
||||||
|
|
||||||
explicit gtable(void)
|
explicit gtable(void)
|
||||||
{
|
{
|
||||||
@ -1222,29 +1218,28 @@ void Sample_Derivative_Response_Radius6(const Mat &Lx, const Mat &Ly,
|
|||||||
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) {
|
||||||
weight[k] = gauss25[id[i + 6]][id[j + 6]];
|
CV_Assert(k < 109);
|
||||||
yidx[k] = static_cast<int8_t>(i);
|
weight[k] = gauss25[abs(i)][abs(j)];
|
||||||
xidx[k] = static_cast<int8_t>(j);
|
yidx[k] = i;
|
||||||
|
xidx[k] = j;
|
||||||
++k;
|
++k;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
CV_DbgAssert(k == 109);
|
|
||||||
}
|
}
|
||||||
} g;
|
} g;
|
||||||
|
|
||||||
const float * lx = Lx.ptr<float>(0);
|
CV_Assert(x0 - 6 * scale >= 0 && x0 + 6 * scale < Lx.cols);
|
||||||
const float * ly = Ly.ptr<float>(0);
|
CV_Assert(y0 - 6 * scale >= 0 && y0 + 6 * scale < Lx.rows);
|
||||||
int cols = Lx.cols;
|
|
||||||
|
|
||||||
for (int i = 0; i < 109; i++) {
|
for (int i = 0; i < 109; i++)
|
||||||
int j = (y0 + g.yidx[i] * scale) * cols + (x0 + g.xidx[i] * scale);
|
{
|
||||||
|
int y = y0 + g.yidx[i] * scale;
|
||||||
|
int x = x0 + g.xidx[i] * scale;
|
||||||
|
|
||||||
resX[i] = g.weight[i] * lx[j];
|
float w = g.weight[i];
|
||||||
resY[i] = g.weight[i] * ly[j];
|
resX[i] = w * Lx.at<float>(y, x);
|
||||||
|
resY[i] = w * Ly.at<float>(y, x);
|
||||||
CV_DbgAssert(isfinite(resX[i]));
|
|
||||||
CV_DbgAssert(isfinite(resY[i]));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1253,7 +1248,7 @@ void Sample_Derivative_Response_Radius6(const Mat &Lx, const Mat &Ly,
|
|||||||
* @param a[] Input floating point array to sort
|
* @param a[] Input floating point array to sort
|
||||||
* @param n The length of a[]
|
* @param n The length of a[]
|
||||||
* @param quantum The interval to convert a[i]'s float values to integers
|
* @param quantum The interval to convert a[i]'s float values to integers
|
||||||
* @param max The upper bound of a[], meaning a[i] must be in [0, max]
|
* @param nkeys a[i] < nkeys * quantum
|
||||||
* @param idx[] Output array of the indices: a[idx[i]] forms a sorted array
|
* @param idx[] Output array of the indices: a[idx[i]] forms a sorted array
|
||||||
* @param cum[] Output array of the starting indices of quantized floats
|
* @param cum[] Output array of the starting indices of quantized floats
|
||||||
* @note The values of a[] in [k*quantum, (k + 1)*quantum) is labeled by
|
* @note The values of a[] in [k*quantum, (k + 1)*quantum) is labeled by
|
||||||
@ -1263,25 +1258,35 @@ void Sample_Derivative_Response_Radius6(const Mat &Lx, const Mat &Ly,
|
|||||||
*/
|
*/
|
||||||
static inline
|
static inline
|
||||||
void quantized_counting_sort(const float a[], const int n,
|
void quantized_counting_sort(const float a[], const int n,
|
||||||
const float quantum, const float max,
|
const float quantum, const int nkeys,
|
||||||
uint8_t idx[], uint8_t cum[])
|
int idx[/*n*/], int cum[/*nkeys + 1*/])
|
||||||
{
|
{
|
||||||
const int nkeys = (int)(max / quantum);
|
memset(cum, 0, sizeof(cum[0]) * (nkeys + 1));
|
||||||
|
|
||||||
// The size of cum[] must be nkeys + 1
|
|
||||||
memset(cum, 0, nkeys + 1);
|
|
||||||
|
|
||||||
// Count up the quantized values
|
// Count up the quantized values
|
||||||
for (int i = 0; i < n; i++)
|
for (int i = 0; i < n; i++)
|
||||||
cum[(int)(a[i] / quantum)]++;
|
{
|
||||||
|
int b = (int)(a[i] / quantum);
|
||||||
|
if (b < 0 || b >= nkeys)
|
||||||
|
b = 0;
|
||||||
|
cum[b]++;
|
||||||
|
}
|
||||||
|
|
||||||
// Compute the inclusive prefix sum i.e. the end indices; cum[nkeys] is the total
|
// Compute the inclusive prefix sum i.e. the end indices; cum[nkeys] is the total
|
||||||
for (int i = 1; i <= nkeys; i++)
|
for (int i = 1; i <= nkeys; i++)
|
||||||
|
{
|
||||||
cum[i] += cum[i - 1];
|
cum[i] += cum[i - 1];
|
||||||
|
}
|
||||||
|
CV_Assert(cum[nkeys] == n);
|
||||||
|
|
||||||
// Generate the sorted indices; cum[] becomes the exclusive prefix sum i.e. the start indices of keys
|
// Generate the sorted indices; cum[] becomes the exclusive prefix sum i.e. the start indices of keys
|
||||||
for (int i = 0; i < n; i++)
|
for (int i = 0; i < n; i++)
|
||||||
idx[--cum[(int)(a[i] / quantum)]] = static_cast<uint8_t>(i);
|
{
|
||||||
|
int b = (int)(a[i] / quantum);
|
||||||
|
if (b < 0 || b >= nkeys)
|
||||||
|
b = 0;
|
||||||
|
idx[--cum[b]] = i;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1296,9 +1301,9 @@ void Compute_Main_Orientation(KeyPoint& kpt, const std::vector<Evolution>& evolu
|
|||||||
// get the right evolution level for this keypoint
|
// get the right evolution level for this keypoint
|
||||||
const Evolution& e = evolution[kpt.class_id];
|
const Evolution& e = evolution[kpt.class_id];
|
||||||
// Get the information from the keypoint
|
// Get the information from the keypoint
|
||||||
int scale = fRound(0.5f * kpt.size / e.octave_ratio);
|
int scale = cvRound(0.5f * kpt.size / e.octave_ratio);
|
||||||
int x0 = fRound(kpt.pt.x / e.octave_ratio);
|
int x0 = cvRound(kpt.pt.x / e.octave_ratio);
|
||||||
int y0 = fRound(kpt.pt.y / e.octave_ratio);
|
int y0 = cvRound(kpt.pt.y / e.octave_ratio);
|
||||||
|
|
||||||
// Sample derivatives responses for the points within radius of 6*scale
|
// Sample derivatives responses for the points within radius of 6*scale
|
||||||
const int ang_size = 109;
|
const int ang_size = 109;
|
||||||
@ -1312,17 +1317,18 @@ void Compute_Main_Orientation(KeyPoint& kpt, const std::vector<Evolution>& evolu
|
|||||||
// Sort by the angles; angles are labeled by slices of 0.15 radian
|
// Sort by the angles; angles are labeled by slices of 0.15 radian
|
||||||
const int slices = 42;
|
const int slices = 42;
|
||||||
const float ang_step = (float)(2.0 * CV_PI / slices);
|
const float ang_step = (float)(2.0 * CV_PI / slices);
|
||||||
uint8_t slice[slices + 1];
|
int slice[slices + 1];
|
||||||
uint8_t sorted_idx[ang_size];
|
int sorted_idx[ang_size];
|
||||||
quantized_counting_sort(Ang, ang_size, ang_step, (float)(2.0 * CV_PI), sorted_idx, slice);
|
quantized_counting_sort(Ang, ang_size, ang_step, slices, sorted_idx, slice);
|
||||||
|
|
||||||
// Find the main angle by sliding a window of 7-slice size(=PI/3) around the keypoint
|
// Find the main angle by sliding a window of 7-slice size(=PI/3) around the keypoint
|
||||||
const int win = 7;
|
const int win = 7;
|
||||||
|
|
||||||
float maxX = 0.0f, maxY = 0.0f;
|
float maxX = 0.0f, maxY = 0.0f;
|
||||||
for (int i = slice[0]; i < slice[win]; i++) {
|
for (int i = slice[0]; i < slice[win]; i++) {
|
||||||
maxX += resX[sorted_idx[i]];
|
const int idx = sorted_idx[i];
|
||||||
maxY += resY[sorted_idx[i]];
|
maxX += resX[idx];
|
||||||
|
maxY += resY[idx];
|
||||||
}
|
}
|
||||||
float maxNorm = maxX * maxX + maxY * maxY;
|
float maxNorm = maxX * maxX + maxY * maxY;
|
||||||
|
|
||||||
@ -1333,8 +1339,9 @@ void Compute_Main_Orientation(KeyPoint& kpt, const std::vector<Evolution>& evolu
|
|||||||
|
|
||||||
float sumX = 0.0f, sumY = 0.0f;
|
float sumX = 0.0f, sumY = 0.0f;
|
||||||
for (int i = slice[sn]; i < slice[sn + win]; i++) {
|
for (int i = slice[sn]; i < slice[sn + win]; i++) {
|
||||||
sumX += resX[sorted_idx[i]];
|
const int idx = sorted_idx[i];
|
||||||
sumY += resY[sorted_idx[i]];
|
sumX += resX[idx];
|
||||||
|
sumY += resY[idx];
|
||||||
}
|
}
|
||||||
|
|
||||||
float norm = sumX * sumX + sumY * sumY;
|
float norm = sumX * sumX + sumY * sumY;
|
||||||
@ -1350,12 +1357,14 @@ void Compute_Main_Orientation(KeyPoint& kpt, const std::vector<Evolution>& evolu
|
|||||||
|
|
||||||
float sumX = 0.0f, sumY = 0.0f;
|
float sumX = 0.0f, sumY = 0.0f;
|
||||||
for (int i = slice[sn]; i < slice[slices]; i++) {
|
for (int i = slice[sn]; i < slice[slices]; i++) {
|
||||||
sumX += resX[sorted_idx[i]];
|
const int idx = sorted_idx[i];
|
||||||
sumY += resY[sorted_idx[i]];
|
sumX += resX[idx];
|
||||||
|
sumY += resY[idx];
|
||||||
}
|
}
|
||||||
for (int i = slice[0]; i < slice[remain]; i++) {
|
for (int i = slice[0]; i < slice[remain]; i++) {
|
||||||
sumX += resX[sorted_idx[i]];
|
const int idx = sorted_idx[i];
|
||||||
sumY += resY[sorted_idx[i]];
|
sumX += resX[idx];
|
||||||
|
sumY += resY[idx];
|
||||||
}
|
}
|
||||||
|
|
||||||
float norm = sumX * sumX + sumY * sumY;
|
float norm = sumX * sumX + sumY * sumY;
|
||||||
@ -1410,7 +1419,10 @@ void AKAZEFeatures::Compute_Keypoints_Orientation(std::vector<KeyPoint>& kpts) c
|
|||||||
* from Agrawal et al., CenSurE: Center Surround Extremas for Realtime Feature Detection and Matching,
|
* from Agrawal et al., CenSurE: Center Surround Extremas for Realtime Feature Detection and Matching,
|
||||||
* ECCV 2008
|
* ECCV 2008
|
||||||
*/
|
*/
|
||||||
void MSURF_Upright_Descriptor_64_Invoker::Get_MSURF_Upright_Descriptor_64(const KeyPoint& kpt, float *desc) const {
|
void MSURF_Upright_Descriptor_64_Invoker::Get_MSURF_Upright_Descriptor_64(const KeyPoint& kpt, float *desc, int desc_size) const {
|
||||||
|
|
||||||
|
const int dsize = 64;
|
||||||
|
CV_Assert(desc_size == dsize);
|
||||||
|
|
||||||
float dx = 0.0, dy = 0.0, mdx = 0.0, mdy = 0.0, gauss_s1 = 0.0, gauss_s2 = 0.0;
|
float dx = 0.0, dy = 0.0, mdx = 0.0, mdy = 0.0, gauss_s1 = 0.0, gauss_s2 = 0.0;
|
||||||
float rx = 0.0, ry = 0.0, len = 0.0, xf = 0.0, yf = 0.0, ys = 0.0, xs = 0.0;
|
float rx = 0.0, ry = 0.0, len = 0.0, xf = 0.0, yf = 0.0, ys = 0.0, xs = 0.0;
|
||||||
@ -1418,7 +1430,7 @@ void MSURF_Upright_Descriptor_64_Invoker::Get_MSURF_Upright_Descriptor_64(const
|
|||||||
int x1 = 0, y1 = 0, sample_step = 0, pattern_size = 0;
|
int x1 = 0, y1 = 0, sample_step = 0, pattern_size = 0;
|
||||||
int x2 = 0, y2 = 0, kx = 0, ky = 0, i = 0, j = 0, dcount = 0;
|
int x2 = 0, y2 = 0, kx = 0, ky = 0, i = 0, j = 0, dcount = 0;
|
||||||
float fx = 0.0, fy = 0.0, ratio = 0.0, res1 = 0.0, res2 = 0.0, res3 = 0.0, res4 = 0.0;
|
float fx = 0.0, fy = 0.0, ratio = 0.0, res1 = 0.0, res2 = 0.0, res3 = 0.0, res4 = 0.0;
|
||||||
int scale = 0, dsize = 0;
|
int scale = 0;
|
||||||
|
|
||||||
// Subregion centers for the 4x4 gaussian weighting
|
// Subregion centers for the 4x4 gaussian weighting
|
||||||
float cx = -0.5f, cy = 0.5f;
|
float cx = -0.5f, cy = 0.5f;
|
||||||
@ -1426,13 +1438,12 @@ void MSURF_Upright_Descriptor_64_Invoker::Get_MSURF_Upright_Descriptor_64(const
|
|||||||
const std::vector<Evolution>& evolution = *evolution_;
|
const std::vector<Evolution>& evolution = *evolution_;
|
||||||
|
|
||||||
// Set the descriptor size and the sample and pattern sizes
|
// Set the descriptor size and the sample and pattern sizes
|
||||||
dsize = 64;
|
|
||||||
sample_step = 5;
|
sample_step = 5;
|
||||||
pattern_size = 12;
|
pattern_size = 12;
|
||||||
|
|
||||||
// Get the information from the keypoint
|
// Get the information from the keypoint
|
||||||
ratio = (float)(1 << kpt.octave);
|
ratio = (float)(1 << kpt.octave);
|
||||||
scale = fRound(0.5f*kpt.size / ratio);
|
scale = cvRound(0.5f*kpt.size / ratio);
|
||||||
const int level = kpt.class_id;
|
const int level = kpt.class_id;
|
||||||
Mat Lx = evolution[level].Mx;
|
Mat Lx = evolution[level].Mx;
|
||||||
Mat Ly = evolution[level].My;
|
Mat Ly = evolution[level].My;
|
||||||
@ -1469,11 +1480,11 @@ void MSURF_Upright_Descriptor_64_Invoker::Get_MSURF_Upright_Descriptor_64(const
|
|||||||
//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.50f*scale);
|
gauss_s1 = gaussian(xs - sample_x, ys - sample_y, 2.50f*scale);
|
||||||
|
|
||||||
y1 = (int)(sample_y - .5);
|
y1 = (int)(sample_y - .5f);
|
||||||
x1 = (int)(sample_x - .5);
|
x1 = (int)(sample_x - .5f);
|
||||||
|
|
||||||
y2 = (int)(sample_y + .5);
|
y2 = (int)(sample_y + .5f);
|
||||||
x2 = (int)(sample_x + .5);
|
x2 = (int)(sample_x + .5f);
|
||||||
|
|
||||||
fx = sample_x - x1;
|
fx = sample_x - x1;
|
||||||
fy = sample_y - y1;
|
fy = sample_y - y1;
|
||||||
@ -1517,6 +1528,8 @@ void MSURF_Upright_Descriptor_64_Invoker::Get_MSURF_Upright_Descriptor_64(const
|
|||||||
i += 9;
|
i += 9;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CV_Assert(dcount == desc_size);
|
||||||
|
|
||||||
// convert to unit vector
|
// convert to unit vector
|
||||||
len = sqrt(len);
|
len = sqrt(len);
|
||||||
|
|
||||||
@ -1535,7 +1548,10 @@ void MSURF_Upright_Descriptor_64_Invoker::Get_MSURF_Upright_Descriptor_64(const
|
|||||||
* from Agrawal et al., CenSurE: Center Surround Extremas for Realtime Feature Detection and Matching,
|
* from Agrawal et al., CenSurE: Center Surround Extremas for Realtime Feature Detection and Matching,
|
||||||
* ECCV 2008
|
* ECCV 2008
|
||||||
*/
|
*/
|
||||||
void MSURF_Descriptor_64_Invoker::Get_MSURF_Descriptor_64(const KeyPoint& kpt, float *desc) const {
|
void MSURF_Descriptor_64_Invoker::Get_MSURF_Descriptor_64(const KeyPoint& kpt, float *desc, int desc_size) const {
|
||||||
|
|
||||||
|
const int dsize = 64;
|
||||||
|
CV_Assert(desc_size == dsize);
|
||||||
|
|
||||||
float dx = 0.0, dy = 0.0, mdx = 0.0, mdy = 0.0, gauss_s1 = 0.0, gauss_s2 = 0.0;
|
float dx = 0.0, dy = 0.0, mdx = 0.0, mdy = 0.0, gauss_s1 = 0.0, gauss_s2 = 0.0;
|
||||||
float rx = 0.0, ry = 0.0, rrx = 0.0, rry = 0.0, len = 0.0, xf = 0.0, yf = 0.0, ys = 0.0, xs = 0.0;
|
float rx = 0.0, ry = 0.0, rrx = 0.0, rry = 0.0, len = 0.0, xf = 0.0, yf = 0.0, ys = 0.0, xs = 0.0;
|
||||||
@ -1543,7 +1559,7 @@ void MSURF_Descriptor_64_Invoker::Get_MSURF_Descriptor_64(const KeyPoint& kpt, f
|
|||||||
float fx = 0.0, fy = 0.0, ratio = 0.0, res1 = 0.0, res2 = 0.0, res3 = 0.0, res4 = 0.0;
|
float fx = 0.0, fy = 0.0, ratio = 0.0, res1 = 0.0, res2 = 0.0, res3 = 0.0, res4 = 0.0;
|
||||||
int x1 = 0, y1 = 0, x2 = 0, y2 = 0, sample_step = 0, pattern_size = 0;
|
int x1 = 0, y1 = 0, x2 = 0, y2 = 0, sample_step = 0, pattern_size = 0;
|
||||||
int kx = 0, ky = 0, i = 0, j = 0, dcount = 0;
|
int kx = 0, ky = 0, i = 0, j = 0, dcount = 0;
|
||||||
int scale = 0, dsize = 0;
|
int scale = 0;
|
||||||
|
|
||||||
// Subregion centers for the 4x4 gaussian weighting
|
// Subregion centers for the 4x4 gaussian weighting
|
||||||
float cx = -0.5f, cy = 0.5f;
|
float cx = -0.5f, cy = 0.5f;
|
||||||
@ -1551,14 +1567,13 @@ void MSURF_Descriptor_64_Invoker::Get_MSURF_Descriptor_64(const KeyPoint& kpt, f
|
|||||||
const std::vector<Evolution>& evolution = *evolution_;
|
const std::vector<Evolution>& evolution = *evolution_;
|
||||||
|
|
||||||
// Set the descriptor size and the sample and pattern sizes
|
// Set the descriptor size and the sample and pattern sizes
|
||||||
dsize = 64;
|
|
||||||
sample_step = 5;
|
sample_step = 5;
|
||||||
pattern_size = 12;
|
pattern_size = 12;
|
||||||
|
|
||||||
// Get the information from the keypoint
|
// Get the information from the keypoint
|
||||||
ratio = (float)(1 << kpt.octave);
|
ratio = (float)(1 << kpt.octave);
|
||||||
scale = fRound(0.5f*kpt.size / ratio);
|
scale = cvRound(0.5f*kpt.size / ratio);
|
||||||
angle = (kpt.angle * static_cast<float>(CV_PI)) / 180.f;
|
angle = kpt.angle * static_cast<float>(CV_PI / 180.f);
|
||||||
const int level = kpt.class_id;
|
const int level = kpt.class_id;
|
||||||
Mat Lx = evolution[level].Mx;
|
Mat Lx = evolution[level].Mx;
|
||||||
Mat Ly = evolution[level].My;
|
Mat Ly = evolution[level].My;
|
||||||
@ -1598,11 +1613,11 @@ void MSURF_Descriptor_64_Invoker::Get_MSURF_Descriptor_64(const KeyPoint& kpt, f
|
|||||||
// 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 = cvRound(sample_y - 0.5f);
|
||||||
x1 = fRound(sample_x - 0.5f);
|
x1 = cvRound(sample_x - 0.5f);
|
||||||
|
|
||||||
y2 = fRound(sample_y + 0.5f);
|
y2 = cvRound(sample_y + 0.5f);
|
||||||
x2 = fRound(sample_x + 0.5f);
|
x2 = cvRound(sample_x + 0.5f);
|
||||||
|
|
||||||
// fix crash: indexing with out-of-bounds index, this might happen near the edges of image
|
// fix crash: indexing with out-of-bounds index, this might happen near the edges of image
|
||||||
// clip values so they fit into the image
|
// clip values so they fit into the image
|
||||||
@ -1655,6 +1670,8 @@ void MSURF_Descriptor_64_Invoker::Get_MSURF_Descriptor_64(const KeyPoint& kpt, f
|
|||||||
i += 9;
|
i += 9;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CV_Assert(dcount == desc_size);
|
||||||
|
|
||||||
// convert to unit vector
|
// convert to unit vector
|
||||||
len = sqrt(len);
|
len = sqrt(len);
|
||||||
|
|
||||||
@ -1670,7 +1687,7 @@ void MSURF_Descriptor_64_Invoker::Get_MSURF_Descriptor_64(const KeyPoint& kpt, f
|
|||||||
* @param kpt Input keypoint
|
* @param kpt Input keypoint
|
||||||
* @param desc Descriptor vector
|
* @param desc Descriptor vector
|
||||||
*/
|
*/
|
||||||
void Upright_MLDB_Full_Descriptor_Invoker::Get_Upright_MLDB_Full_Descriptor(const KeyPoint& kpt, unsigned char *desc) const {
|
void Upright_MLDB_Full_Descriptor_Invoker::Get_Upright_MLDB_Full_Descriptor(const KeyPoint& kpt, unsigned char *desc, int desc_size) const {
|
||||||
|
|
||||||
float di = 0.0, dx = 0.0, dy = 0.0;
|
float di = 0.0, dx = 0.0, dy = 0.0;
|
||||||
float ri = 0.0, rx = 0.0, ry = 0.0, xf = 0.0, yf = 0.0;
|
float ri = 0.0, rx = 0.0, ry = 0.0, xf = 0.0, yf = 0.0;
|
||||||
@ -1682,16 +1699,14 @@ void Upright_MLDB_Full_Descriptor_Invoker::Get_Upright_MLDB_Full_Descriptor(cons
|
|||||||
const AKAZEOptions & options = *options_;
|
const AKAZEOptions & options = *options_;
|
||||||
const std::vector<Evolution>& evolution = *evolution_;
|
const std::vector<Evolution>& evolution = *evolution_;
|
||||||
|
|
||||||
// Matrices for the M-LDB descriptor
|
// Buffer for the M-LDB descriptor
|
||||||
Mat values[3] = {
|
const int max_channels = 3;
|
||||||
Mat(4, options.descriptor_channels, CV_32FC1),
|
CV_Assert(options.descriptor_channels <= max_channels);
|
||||||
Mat(9, options.descriptor_channels, CV_32FC1),
|
float values[16*max_channels];
|
||||||
Mat(16, options.descriptor_channels, CV_32FC1)
|
|
||||||
};
|
|
||||||
|
|
||||||
// Get the information from the keypoint
|
// Get the information from the keypoint
|
||||||
ratio = (float)(1 << kpt.octave);
|
ratio = (float)(1 << kpt.octave);
|
||||||
scale = fRound(0.5f*kpt.size / ratio);
|
scale = cvRound(0.5f*kpt.size / ratio);
|
||||||
const int level = kpt.class_id;
|
const int level = kpt.class_id;
|
||||||
Mat Lx = evolution[level].Mx;
|
Mat Lx = evolution[level].Mx;
|
||||||
Mat Ly = evolution[level].My;
|
Mat Ly = evolution[level].My;
|
||||||
@ -1701,12 +1716,15 @@ void Upright_MLDB_Full_Descriptor_Invoker::Get_Upright_MLDB_Full_Descriptor(cons
|
|||||||
|
|
||||||
// For 2x2 grid, 3x3 grid and 4x4 grid
|
// For 2x2 grid, 3x3 grid and 4x4 grid
|
||||||
const int pattern_size = options_->descriptor_pattern_size;
|
const int pattern_size = options_->descriptor_pattern_size;
|
||||||
int sample_step[3] = {
|
CV_Assert((pattern_size & 1) == 0);
|
||||||
|
const int sample_step[3] = {
|
||||||
pattern_size,
|
pattern_size,
|
||||||
static_cast<int>(ceil(pattern_size*2./3.)),
|
divUp(pattern_size * 2, 3),
|
||||||
pattern_size / 2
|
divUp(pattern_size, 2)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
memset(desc, 0, desc_size);
|
||||||
|
|
||||||
// For the three grids
|
// For the three grids
|
||||||
for (int z = 0; z < 3; z++) {
|
for (int z = 0; z < 3; z++) {
|
||||||
dcount2 = 0;
|
dcount2 = 0;
|
||||||
@ -1723,8 +1741,8 @@ void Upright_MLDB_Full_Descriptor_Invoker::Get_Upright_MLDB_Full_Descriptor(cons
|
|||||||
sample_y = yf + l*scale;
|
sample_y = yf + l*scale;
|
||||||
sample_x = xf + k*scale;
|
sample_x = xf + k*scale;
|
||||||
|
|
||||||
y1 = fRound(sample_y);
|
y1 = cvRound(sample_y);
|
||||||
x1 = fRound(sample_x);
|
x1 = cvRound(sample_x);
|
||||||
|
|
||||||
ri = *(Lt.ptr<float>(y1)+x1);
|
ri = *(Lt.ptr<float>(y1)+x1);
|
||||||
rx = *(Lx.ptr<float>(y1)+x1);
|
rx = *(Lx.ptr<float>(y1)+x1);
|
||||||
@ -1741,7 +1759,7 @@ void Upright_MLDB_Full_Descriptor_Invoker::Get_Upright_MLDB_Full_Descriptor(cons
|
|||||||
dx /= nsamples;
|
dx /= nsamples;
|
||||||
dy /= nsamples;
|
dy /= nsamples;
|
||||||
|
|
||||||
float *val = values[z].ptr<float>(dcount2);
|
float *val = &values[dcount2*max_channels];
|
||||||
*(val) = di;
|
*(val) = di;
|
||||||
*(val+1) = dx;
|
*(val+1) = dx;
|
||||||
*(val+2) = dy;
|
*(val+2) = dy;
|
||||||
@ -1753,13 +1771,11 @@ void Upright_MLDB_Full_Descriptor_Invoker::Get_Upright_MLDB_Full_Descriptor(cons
|
|||||||
const int num = (z + 2) * (z + 2);
|
const int num = (z + 2) * (z + 2);
|
||||||
for (int i = 0; i < num; i++) {
|
for (int i = 0; i < num; i++) {
|
||||||
for (int j = i + 1; j < num; j++) {
|
for (int j = i + 1; j < num; j++) {
|
||||||
const float * valI = values[z].ptr<float>(i);
|
const float * valI = &values[i*max_channels];
|
||||||
const float * valJ = values[z].ptr<float>(j);
|
const float * valJ = &values[j*max_channels];
|
||||||
for (int k = 0; k < 3; ++k) {
|
for (int k = 0; k < 3; ++k) {
|
||||||
if (*(valI + k) > *(valJ + k)) {
|
if (*(valI + k) > *(valJ + k)) {
|
||||||
desc[dcount1 / 8] |= (1 << (dcount1 % 8));
|
desc[dcount1 / 8] |= (1 << (dcount1 % 8));
|
||||||
} else {
|
|
||||||
desc[dcount1 / 8] &= ~(1 << (dcount1 % 8));
|
|
||||||
}
|
}
|
||||||
dcount1++;
|
dcount1++;
|
||||||
}
|
}
|
||||||
@ -1767,6 +1783,9 @@ void Upright_MLDB_Full_Descriptor_Invoker::Get_Upright_MLDB_Full_Descriptor(cons
|
|||||||
}
|
}
|
||||||
|
|
||||||
} // for (int z = 0; z < 3; z++)
|
} // for (int z = 0; z < 3; z++)
|
||||||
|
|
||||||
|
CV_Assert(dcount1 <= desc_size*8);
|
||||||
|
CV_Assert(divUp(dcount1, 8) == desc_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MLDB_Full_Descriptor_Invoker::MLDB_Fill_Values(float* values, int sample_step, const int level,
|
void MLDB_Full_Descriptor_Invoker::MLDB_Fill_Values(float* values, int sample_step, const int level,
|
||||||
@ -1791,8 +1810,8 @@ void MLDB_Full_Descriptor_Invoker::MLDB_Fill_Values(float* values, int sample_st
|
|||||||
float sample_y = yf + (l*co * scale + k*si*scale);
|
float sample_y = yf + (l*co * scale + k*si*scale);
|
||||||
float sample_x = xf + (-l*si * scale + k*co*scale);
|
float sample_x = xf + (-l*si * scale + k*co*scale);
|
||||||
|
|
||||||
int y1 = fRound(sample_y);
|
int y1 = cvRound(sample_y);
|
||||||
int x1 = fRound(sample_x);
|
int x1 = cvRound(sample_x);
|
||||||
|
|
||||||
// fix crash: indexing with out-of-bounds index, this might happen near the edges of image
|
// fix crash: indexing with out-of-bounds index, this might happen near the edges of image
|
||||||
// clip values so they fit into the image
|
// clip values so they fit into the image
|
||||||
@ -1852,10 +1871,6 @@ void MLDB_Full_Descriptor_Invoker::MLDB_Binary_Comparisons(float* values, unsign
|
|||||||
if (ival > ivalues[chan * j + pos]) {
|
if (ival > ivalues[chan * j + pos]) {
|
||||||
desc[dpos >> 3] |= (1 << (dpos & 7));
|
desc[dpos >> 3] |= (1 << (dpos & 7));
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
desc[dpos >> 3] &= ~(1 << (dpos & 7));
|
|
||||||
}
|
|
||||||
|
|
||||||
dpos++;
|
dpos++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1869,30 +1884,41 @@ void MLDB_Full_Descriptor_Invoker::MLDB_Binary_Comparisons(float* values, unsign
|
|||||||
* @param kpt Input keypoint
|
* @param kpt Input keypoint
|
||||||
* @param desc Descriptor vector
|
* @param desc Descriptor vector
|
||||||
*/
|
*/
|
||||||
void MLDB_Full_Descriptor_Invoker::Get_MLDB_Full_Descriptor(const KeyPoint& kpt, unsigned char *desc) const {
|
void MLDB_Full_Descriptor_Invoker::Get_MLDB_Full_Descriptor(const KeyPoint& kpt, unsigned char *desc, int desc_size) const {
|
||||||
|
|
||||||
const int max_channels = 3;
|
const int max_channels = 3;
|
||||||
CV_Assert(options_->descriptor_channels <= max_channels);
|
CV_Assert(options_->descriptor_channels <= max_channels);
|
||||||
|
const int pattern_size = options_->descriptor_pattern_size;
|
||||||
|
|
||||||
float values[16*max_channels];
|
float values[16*max_channels];
|
||||||
const double size_mult[3] = {1, 2.0/3.0, 1.0/2.0};
|
CV_Assert((pattern_size & 1) == 0);
|
||||||
|
//const double size_mult[3] = {1, 2.0/3.0, 1.0/2.0};
|
||||||
|
const int sample_step[3] = { // static_cast<int>(ceil(pattern_size * size_mult[lvl]))
|
||||||
|
pattern_size,
|
||||||
|
divUp(pattern_size * 2, 3),
|
||||||
|
divUp(pattern_size, 2)
|
||||||
|
};
|
||||||
|
|
||||||
float ratio = (float)(1 << kpt.octave);
|
float ratio = (float)(1 << kpt.octave);
|
||||||
float scale = (float)fRound(0.5f*kpt.size / ratio);
|
float scale = (float)cvRound(0.5f*kpt.size / ratio);
|
||||||
float xf = kpt.pt.x / ratio;
|
float xf = kpt.pt.x / ratio;
|
||||||
float yf = kpt.pt.y / ratio;
|
float yf = kpt.pt.y / ratio;
|
||||||
float angle = (kpt.angle * static_cast<float>(CV_PI)) / 180.f;
|
float angle = kpt.angle * static_cast<float>(CV_PI / 180.f);
|
||||||
float co = cos(angle);
|
float co = cos(angle);
|
||||||
float si = sin(angle);
|
float si = sin(angle);
|
||||||
int pattern_size = options_->descriptor_pattern_size;
|
|
||||||
|
memset(desc, 0, desc_size);
|
||||||
|
|
||||||
int dpos = 0;
|
int dpos = 0;
|
||||||
for(int lvl = 0; lvl < 3; lvl++) {
|
for(int lvl = 0; lvl < 3; lvl++)
|
||||||
|
{
|
||||||
int val_count = (lvl + 2) * (lvl + 2);
|
int val_count = (lvl + 2) * (lvl + 2);
|
||||||
int sample_step = static_cast<int>(ceil(pattern_size * size_mult[lvl]));
|
MLDB_Fill_Values(values, sample_step[lvl], kpt.class_id, xf, yf, co, si, scale);
|
||||||
MLDB_Fill_Values(values, sample_step, kpt.class_id, xf, yf, co, si, scale);
|
|
||||||
MLDB_Binary_Comparisons(values, desc, val_count, dpos);
|
MLDB_Binary_Comparisons(values, desc, val_count, dpos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CV_Assert(dpos == 486);
|
||||||
|
CV_Assert(divUp(dpos, 8) == desc_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ************************************************************************* */
|
/* ************************************************************************* */
|
||||||
@ -1903,7 +1929,7 @@ void MLDB_Full_Descriptor_Invoker::Get_MLDB_Full_Descriptor(const KeyPoint& kpt,
|
|||||||
* @param kpt Input keypoint
|
* @param kpt Input keypoint
|
||||||
* @param desc Descriptor vector
|
* @param desc Descriptor vector
|
||||||
*/
|
*/
|
||||||
void MLDB_Descriptor_Subset_Invoker::Get_MLDB_Descriptor_Subset(const KeyPoint& kpt, unsigned char *desc) const {
|
void MLDB_Descriptor_Subset_Invoker::Get_MLDB_Descriptor_Subset(const KeyPoint& kpt, unsigned char *desc, int desc_size) const {
|
||||||
|
|
||||||
float di = 0.f, dx = 0.f, dy = 0.f;
|
float di = 0.f, dx = 0.f, dy = 0.f;
|
||||||
float rx = 0.f, ry = 0.f;
|
float rx = 0.f, ry = 0.f;
|
||||||
@ -1915,8 +1941,8 @@ void MLDB_Descriptor_Subset_Invoker::Get_MLDB_Descriptor_Subset(const KeyPoint&
|
|||||||
|
|
||||||
// Get the information from the keypoint
|
// Get the information from the keypoint
|
||||||
float ratio = (float)(1 << kpt.octave);
|
float ratio = (float)(1 << kpt.octave);
|
||||||
int scale = fRound(0.5f*kpt.size / ratio);
|
int scale = cvRound(0.5f*kpt.size / ratio);
|
||||||
float angle = (kpt.angle * static_cast<float>(CV_PI)) / 180.f;
|
float angle = kpt.angle * static_cast<float>(CV_PI / 180.f);
|
||||||
const int level = kpt.class_id;
|
const int level = kpt.class_id;
|
||||||
Mat Lx = evolution[level].Mx;
|
Mat Lx = evolution[level].Mx;
|
||||||
Mat Ly = evolution[level].My;
|
Mat Ly = evolution[level].My;
|
||||||
@ -1927,17 +1953,25 @@ void MLDB_Descriptor_Subset_Invoker::Get_MLDB_Descriptor_Subset(const KeyPoint&
|
|||||||
float si = sin(angle);
|
float si = sin(angle);
|
||||||
|
|
||||||
// Allocate memory for the matrix of values
|
// Allocate memory for the matrix of values
|
||||||
Mat values((4 + 9 + 16)*options.descriptor_channels, 1, CV_32FC1);
|
// Buffer for the M-LDB descriptor
|
||||||
|
const int max_channels = 3;
|
||||||
|
const int channels = options.descriptor_channels;
|
||||||
|
CV_Assert(channels <= max_channels);
|
||||||
|
float values[(4 + 9 + 16)*max_channels];
|
||||||
|
|
||||||
// Sample everything, but only do the comparisons
|
// Sample everything, but only do the comparisons
|
||||||
vector<int> steps(3);
|
const int pattern_size = options.descriptor_pattern_size;
|
||||||
steps.at(0) = options.descriptor_pattern_size;
|
CV_Assert((pattern_size & 1) == 0);
|
||||||
steps.at(1) = (int)ceil(2.f*options.descriptor_pattern_size / 3.f);
|
const int sample_steps[3] = {
|
||||||
steps.at(2) = options.descriptor_pattern_size / 2;
|
pattern_size,
|
||||||
|
divUp(pattern_size * 2, 3),
|
||||||
|
divUp(pattern_size, 2)
|
||||||
|
};
|
||||||
|
|
||||||
for (int i = 0; i < descriptorSamples_.rows; i++) {
|
for (int i = 0; i < descriptorSamples_.rows; i++) {
|
||||||
const int *coords = descriptorSamples_.ptr<int>(i);
|
const int *coords = descriptorSamples_.ptr<int>(i);
|
||||||
int sample_step = steps.at(coords[0]);
|
CV_Assert(coords[0] >= 0 && coords[0] < 3);
|
||||||
|
const int sample_step = sample_steps[coords[0]];
|
||||||
di = 0.0f;
|
di = 0.0f;
|
||||||
dx = 0.0f;
|
dx = 0.0f;
|
||||||
dy = 0.0f;
|
dy = 0.0f;
|
||||||
@ -1949,8 +1983,8 @@ void MLDB_Descriptor_Subset_Invoker::Get_MLDB_Descriptor_Subset(const KeyPoint&
|
|||||||
sample_y = yf + (l*scale*co + k*scale*si);
|
sample_y = yf + (l*scale*co + k*scale*si);
|
||||||
sample_x = xf + (-l*scale*si + k*scale*co);
|
sample_x = xf + (-l*scale*si + k*scale*co);
|
||||||
|
|
||||||
y1 = fRound(sample_y);
|
y1 = cvRound(sample_y);
|
||||||
x1 = fRound(sample_x);
|
x1 = cvRound(sample_x);
|
||||||
|
|
||||||
di += *(Lt.ptr<float>(y1)+x1);
|
di += *(Lt.ptr<float>(y1)+x1);
|
||||||
|
|
||||||
@ -1970,26 +2004,27 @@ void MLDB_Descriptor_Subset_Invoker::Get_MLDB_Descriptor_Subset(const KeyPoint&
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
*(values.ptr<float>(options.descriptor_channels*i)) = di;
|
float* pValues = &values[channels * i];
|
||||||
|
pValues[0] = di;
|
||||||
|
|
||||||
if (options.descriptor_channels == 2) {
|
if (channels == 2) {
|
||||||
*(values.ptr<float>(options.descriptor_channels*i + 1)) = dx;
|
pValues[1] = dx;
|
||||||
}
|
}
|
||||||
else if (options.descriptor_channels == 3) {
|
else if (channels == 3) {
|
||||||
*(values.ptr<float>(options.descriptor_channels*i + 1)) = dx;
|
pValues[1] = dx;
|
||||||
*(values.ptr<float>(options.descriptor_channels*i + 2)) = dy;
|
pValues[2] = dy;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Do the comparisons
|
// Do the comparisons
|
||||||
const float *vals = values.ptr<float>(0);
|
|
||||||
const int *comps = descriptorBits_.ptr<int>(0);
|
const int *comps = descriptorBits_.ptr<int>(0);
|
||||||
|
|
||||||
|
CV_Assert(divUp(descriptorBits_.rows, 8) == desc_size);
|
||||||
|
memset(desc, 0, desc_size);
|
||||||
|
|
||||||
for (int i = 0; i<descriptorBits_.rows; i++) {
|
for (int i = 0; i<descriptorBits_.rows; i++) {
|
||||||
if (vals[comps[2 * i]] > vals[comps[2 * i + 1]]) {
|
if (values[comps[2 * i]] > values[comps[2 * i + 1]]) {
|
||||||
desc[i / 8] |= (1 << (i % 8));
|
desc[i / 8] |= (1 << (i % 8));
|
||||||
} else {
|
|
||||||
desc[i / 8] &= ~(1 << (i % 8));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2002,7 +2037,7 @@ void MLDB_Descriptor_Subset_Invoker::Get_MLDB_Descriptor_Subset(const KeyPoint&
|
|||||||
* @param kpt Input keypoint
|
* @param kpt Input keypoint
|
||||||
* @param desc Descriptor vector
|
* @param desc Descriptor vector
|
||||||
*/
|
*/
|
||||||
void Upright_MLDB_Descriptor_Subset_Invoker::Get_Upright_MLDB_Descriptor_Subset(const KeyPoint& kpt, unsigned char *desc) const {
|
void Upright_MLDB_Descriptor_Subset_Invoker::Get_Upright_MLDB_Descriptor_Subset(const KeyPoint& kpt, unsigned char *desc, int desc_size) const {
|
||||||
|
|
||||||
float di = 0.0f, dx = 0.0f, dy = 0.0f;
|
float di = 0.0f, dx = 0.0f, dy = 0.0f;
|
||||||
float rx = 0.0f, ry = 0.0f;
|
float rx = 0.0f, ry = 0.0f;
|
||||||
@ -2014,7 +2049,7 @@ void Upright_MLDB_Descriptor_Subset_Invoker::Get_Upright_MLDB_Descriptor_Subset(
|
|||||||
|
|
||||||
// Get the information from the keypoint
|
// Get the information from the keypoint
|
||||||
float ratio = (float)(1 << kpt.octave);
|
float ratio = (float)(1 << kpt.octave);
|
||||||
int scale = fRound(0.5f*kpt.size / ratio);
|
int scale = cvRound(0.5f*kpt.size / ratio);
|
||||||
const int level = kpt.class_id;
|
const int level = kpt.class_id;
|
||||||
Mat Lx = evolution[level].Mx;
|
Mat Lx = evolution[level].Mx;
|
||||||
Mat Ly = evolution[level].My;
|
Mat Ly = evolution[level].My;
|
||||||
@ -2025,14 +2060,18 @@ void Upright_MLDB_Descriptor_Subset_Invoker::Get_Upright_MLDB_Descriptor_Subset(
|
|||||||
// Allocate memory for the matrix of values
|
// Allocate memory for the matrix of values
|
||||||
Mat values ((4 + 9 + 16)*options.descriptor_channels, 1, CV_32FC1);
|
Mat values ((4 + 9 + 16)*options.descriptor_channels, 1, CV_32FC1);
|
||||||
|
|
||||||
vector<int> steps(3);
|
const int pattern_size = options.descriptor_pattern_size;
|
||||||
steps.at(0) = options.descriptor_pattern_size;
|
CV_Assert((pattern_size & 1) == 0);
|
||||||
steps.at(1) = static_cast<int>(ceil(2.f*options.descriptor_pattern_size / 3.f));
|
const int sample_steps[3] = {
|
||||||
steps.at(2) = options.descriptor_pattern_size / 2;
|
pattern_size,
|
||||||
|
divUp(pattern_size * 2, 3),
|
||||||
|
divUp(pattern_size, 2)
|
||||||
|
};
|
||||||
|
|
||||||
for (int i = 0; i < descriptorSamples_.rows; i++) {
|
for (int i = 0; i < descriptorSamples_.rows; i++) {
|
||||||
const int *coords = descriptorSamples_.ptr<int>(i);
|
const int *coords = descriptorSamples_.ptr<int>(i);
|
||||||
int sample_step = steps.at(coords[0]);
|
CV_Assert(coords[0] >= 0 && coords[0] < 3);
|
||||||
|
int sample_step = sample_steps[coords[0]];
|
||||||
di = 0.0f, dx = 0.0f, dy = 0.0f;
|
di = 0.0f, dx = 0.0f, dy = 0.0f;
|
||||||
|
|
||||||
for (int k = coords[1]; k < coords[1] + sample_step; k++) {
|
for (int k = coords[1]; k < coords[1] + sample_step; k++) {
|
||||||
@ -2042,8 +2081,8 @@ void Upright_MLDB_Descriptor_Subset_Invoker::Get_Upright_MLDB_Descriptor_Subset(
|
|||||||
sample_y = yf + l*scale;
|
sample_y = yf + l*scale;
|
||||||
sample_x = xf + k*scale;
|
sample_x = xf + k*scale;
|
||||||
|
|
||||||
y1 = fRound(sample_y);
|
y1 = cvRound(sample_y);
|
||||||
x1 = fRound(sample_x);
|
x1 = cvRound(sample_x);
|
||||||
di += *(Lt.ptr<float>(y1)+x1);
|
di += *(Lt.ptr<float>(y1)+x1);
|
||||||
|
|
||||||
if (options.descriptor_channels > 1) {
|
if (options.descriptor_channels > 1) {
|
||||||
@ -2076,11 +2115,12 @@ void Upright_MLDB_Descriptor_Subset_Invoker::Get_Upright_MLDB_Descriptor_Subset(
|
|||||||
const float *vals = values.ptr<float>(0);
|
const float *vals = values.ptr<float>(0);
|
||||||
const int *comps = descriptorBits_.ptr<int>(0);
|
const int *comps = descriptorBits_.ptr<int>(0);
|
||||||
|
|
||||||
|
CV_Assert(divUp(descriptorBits_.rows, 8) == desc_size);
|
||||||
|
memset(desc, 0, desc_size);
|
||||||
|
|
||||||
for (int i = 0; i<descriptorBits_.rows; i++) {
|
for (int i = 0; i<descriptorBits_.rows; i++) {
|
||||||
if (vals[comps[2 * i]] > vals[comps[2 * i + 1]]) {
|
if (vals[comps[2 * i]] > vals[comps[2 * i + 1]]) {
|
||||||
desc[i / 8] |= (1 << (i % 8));
|
desc[i / 8] |= (1 << (i % 8));
|
||||||
} else {
|
|
||||||
desc[i / 8] &= ~(1 << (i % 8));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2120,7 +2160,7 @@ void generateDescriptorSubsample(Mat& sampleList, Mat& comparisons, int nbits,
|
|||||||
for (int i = 0, c = 0; i < 3; i++) {
|
for (int i = 0, c = 0; i < 3; i++) {
|
||||||
int gdiv = i + 2; //grid divisions, per row
|
int gdiv = i + 2; //grid divisions, per row
|
||||||
int gsz = gdiv*gdiv;
|
int gsz = gdiv*gdiv;
|
||||||
int psz = (int)ceil(2.f*pattern_size / (float)gdiv);
|
int psz = divUp(2*pattern_size, gdiv);
|
||||||
|
|
||||||
for (int j = 0; j < gsz; j++) {
|
for (int j = 0; j < gsz; j++) {
|
||||||
for (int k = j + 1; k < gsz; k++, c++) {
|
for (int k = j + 1; k < gsz; k++, c++) {
|
||||||
@ -2134,12 +2174,12 @@ void generateDescriptorSubsample(Mat& sampleList, Mat& comparisons, int nbits,
|
|||||||
}
|
}
|
||||||
|
|
||||||
RNG rng(1024);
|
RNG rng(1024);
|
||||||
Mat_<int> comps = Mat_<int>(nchannels * (int)ceil(nbits / (float)nchannels), 2);
|
const int npicks = divUp(nbits, nchannels);
|
||||||
|
Mat_<int> comps = Mat_<int>(nchannels * npicks, 2);
|
||||||
comps = 1000;
|
comps = 1000;
|
||||||
|
|
||||||
// Select some samples. A sample includes all channels
|
// Select some samples. A sample includes all channels
|
||||||
int count = 0;
|
int count = 0;
|
||||||
int npicks = (int)ceil(nbits / (float)nchannels);
|
|
||||||
Mat_<int> samples(29, 3);
|
Mat_<int> samples(29, 3);
|
||||||
Mat_<int> fullcopy = fullM.clone();
|
Mat_<int> fullcopy = fullM.clone();
|
||||||
samples = -1;
|
samples = -1;
|
||||||
|
@ -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) {
|
|||||||
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)
|
|||||||
|
|
||||||
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
|
|||||||
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
|
|||||||
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
|
|||||||
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
|
|||||||
// 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
|
|||||||
// 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
|
|||||||
|
|
||||||
// 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
|
|||||||
// 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
|
|||||||
// 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
|
|||||||
// 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,
|
|||||||
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
|
|||||||
|
|
||||||
// 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_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,31 +1,6 @@
|
|||||||
#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) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ************************************************************************* */
|
|
||||||
/**
|
|
||||||
* @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;
|
|||||||
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)
|
|||||||
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)
|
|||||||
#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)
|
|||||||
{
|
{
|
||||||
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)
|
|||||||
#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 )
|
|||||||
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 )
|
|||||||
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:
|
|||||||
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
|
||||||
stringstream ss;
|
if (dist > 0)
|
||||||
ss << "Max distance between valid and computed descriptors " << curMaxDist;
|
|
||||||
if( curMaxDist <= maxDist )
|
|
||||||
ss << "." << endl;
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
ss << ">" << maxDist << " - bad accuracy!"<< endl;
|
std::cout << "i=" << y << " fail_count=" << failed_count << " dist=" << dist << std::endl;
|
||||||
ts->set_failed_test_info( cvtest::TS::FAIL_BAD_ACCURACY );
|
std::cout << "valid: " << validDescriptors.row(y) << std::endl;
|
||||||
|
std::cout << " calc: " << calcDescriptors.row(y) << std::endl;
|
||||||
}
|
}
|
||||||
ts->printf(cvtest::TS::LOG, ss.str().c_str() );
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
float exact_percents = (100 * (float)exact_count / validDescriptors.rows);
|
||||||
|
float failed_percents = (100 * (float)failed_count / validDescriptors.rows);
|
||||||
|
stringstream ss;
|
||||||
|
ss << "Exact count (dist == 0): " << exact_count << " (" << (int)exact_percents << "%)" << std::endl
|
||||||
|
<< "Failed count (dist > " << maxDist << "): " << failed_count << " (" << (int)failed_percents << "%)" << std::endl
|
||||||
|
<< "Max distance between valid and computed descriptors (" << validDescriptors.size() << "): " << curMaxDist;
|
||||||
|
EXPECT_LE(failed_percents, 20.0f);
|
||||||
|
std::cout << ss.str() << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
void emptyDataTest()
|
void emptyDataTest()
|
||||||
@ -202,14 +217,49 @@ 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);
|
||||||
}
|
}
|
||||||
if(!keypoints.empty())
|
else
|
||||||
|
{
|
||||||
|
detector->detect(img, keypoints);
|
||||||
|
}
|
||||||
|
write(fs, "keypoints", keypoints);
|
||||||
|
fs.release();
|
||||||
|
}
|
||||||
|
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();
|
||||||
@ -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();
|
||||||
|
EXPECT_FALSE(validDescriptors.empty()) << "Descriptors testdata is missing. Re-writing descriptors testdata...";
|
||||||
if (!validDescriptors.empty())
|
if (!validDescriptors.empty())
|
||||||
|
{
|
||||||
compareDescriptors(validDescriptors, calcDescriptors);
|
compareDescriptors(validDescriptors, calcDescriptors);
|
||||||
else
|
|
||||||
{
|
|
||||||
if( !writeDescriptors( 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 )
|
|||||||
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;
|
|||||||
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
|
|||||||
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
|
|||||||
|
|
||||||
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
|
|||||||
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")
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user