diff --git a/modules/features2d/src/kaze/AKAZEFeatures.cpp b/modules/features2d/src/kaze/AKAZEFeatures.cpp index 77a68a554c..bdfadb6056 100644 --- a/modules/features2d/src/kaze/AKAZEFeatures.cpp +++ b/modules/features2d/src/kaze/AKAZEFeatures.cpp @@ -1117,7 +1117,7 @@ void Upright_MLDB_Full_Descriptor_Invoker::Get_Upright_MLDB_Full_Descriptor(cons 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 sample_x = 0.0, sample_y = 0.0, ratio = 0.0; - int x1 = 0, y1 = 0, sample_step = 0, pattern_size = 0; + int x1 = 0, y1 = 0; int level = 0, nsamples = 0, scale = 0; int dcount1 = 0, dcount2 = 0; @@ -1125,9 +1125,11 @@ void Upright_MLDB_Full_Descriptor_Invoker::Get_Upright_MLDB_Full_Descriptor(cons const std::vector& evolution = *evolution_; // Matrices for the M-LDB descriptor - Mat values_1 = Mat::zeros(4, options.descriptor_channels, CV_32FC1); - Mat values_2 = Mat::zeros(9, options.descriptor_channels, CV_32FC1); - Mat values_3 = Mat::zeros(16, options.descriptor_channels, CV_32FC1); + Mat values[3] = { + Mat::zeros(4, options.descriptor_channels, CV_32FC1), + Mat::zeros(9, options.descriptor_channels, CV_32FC1), + Mat::zeros(16, options.descriptor_channels, CV_32FC1) + }; // Get the information from the keypoint ratio = (float)(1 << kpt.octave); @@ -1136,190 +1138,72 @@ void Upright_MLDB_Full_Descriptor_Invoker::Get_Upright_MLDB_Full_Descriptor(cons yf = kpt.pt.y / ratio; xf = kpt.pt.x / ratio; - // First 2x2 grid - pattern_size = options_->descriptor_pattern_size; - sample_step = pattern_size; + // For 2x2 grid, 3x3 grid and 4x4 grid + const int pattern_size = options_->descriptor_pattern_size; + int sample_step[3] = { + pattern_size, + static_cast(ceil(pattern_size*2./3.)), + pattern_size / 2 + }; - for (int i = -pattern_size; i < pattern_size; i += sample_step) { - for (int j = -pattern_size; j < pattern_size; j += sample_step) { - di = dx = dy = 0.0; - nsamples = 0; + // For the three grids + for (int z = 0; z < 3; z++) { + dcount2 = 0; + const int step = sample_step[z]; + for (int i = -pattern_size; i < pattern_size; i += step) { + for (int j = -pattern_size; j < pattern_size; j += step) { + di = dx = dy = 0.0; + nsamples = 0; - for (int k = i; k < i + sample_step; k++) { - for (int l = j; l < j + sample_step; l++) { + for (int k = i; k < i + step; k++) { + for (int l = j; l < j + step; l++) { - // Get the coordinates of the sample point - sample_y = yf + l*scale; - sample_x = xf + k*scale; + // Get the coordinates of the sample point + sample_y = yf + l*scale; + sample_x = xf + k*scale; - y1 = fRound(sample_y); - x1 = fRound(sample_x); + y1 = fRound(sample_y); + x1 = fRound(sample_x); - ri = *(evolution[level].Lt.ptr(y1)+x1); - rx = *(evolution[level].Lx.ptr(y1)+x1); - ry = *(evolution[level].Ly.ptr(y1)+x1); + ri = *(evolution[level].Lt.ptr(y1)+x1); + rx = *(evolution[level].Lx.ptr(y1)+x1); + ry = *(evolution[level].Ly.ptr(y1)+x1); - di += ri; - dx += rx; - dy += ry; - nsamples++; + di += ri; + dx += rx; + dy += ry; + nsamples++; + } + } + + di /= nsamples; + dx /= nsamples; + dy /= nsamples; + + float *val = values[z].ptr(dcount2); + *(val) = di; + *(val+1) = dx; + *(val+2) = dy; + dcount2++; + } + } + + // Do binary comparison + const int num = (z + 2) * (z + 2); + for (int i = 0; i < num; i++) { + for (int j = i + 1; j < num; j++) { + const float * valI = values[z].ptr(i); + const float * valJ = values[z].ptr(j); + for (int k = 0; k < 3; ++k) { + if (*(valI + k) > *(valJ + k)) { + desc[dcount1 / 8] |= (1 << (dcount1 % 8)); + } + dcount1++; } } - - di /= nsamples; - dx /= nsamples; - dy /= nsamples; - - *(values_1.ptr(dcount2)) = di; - *(values_1.ptr(dcount2)+1) = dx; - *(values_1.ptr(dcount2)+2) = dy; - dcount2++; } - } - // Do binary comparison first level - for (int i = 0; i < 4; i++) { - for (int j = i + 1; j < 4; j++) { - if (*(values_1.ptr(i)) > *(values_1.ptr(j))) { - desc[dcount1 / 8] |= (1 << (dcount1 % 8)); - } - dcount1++; - - if (*(values_1.ptr(i)+1) > *(values_1.ptr(j)+1)) { - desc[dcount1 / 8] |= (1 << (dcount1 % 8)); - } - dcount1++; - - if (*(values_1.ptr(i)+2) > *(values_1.ptr(j)+2)) { - desc[dcount1 / 8] |= (1 << (dcount1 % 8)); - } - dcount1++; - } - } - - // Second 3x3 grid - sample_step = static_cast(ceil(pattern_size*2. / 3.)); - dcount2 = 0; - - for (int i = -pattern_size; i < pattern_size; i += sample_step) { - for (int j = -pattern_size; j < pattern_size; j += sample_step) { - di = dx = dy = 0.0; - nsamples = 0; - - for (int k = i; k < i + sample_step; k++) { - for (int l = j; l < j + sample_step; l++) { - - // Get the coordinates of the sample point - sample_y = yf + l*scale; - sample_x = xf + k*scale; - - y1 = fRound(sample_y); - x1 = fRound(sample_x); - - ri = *(evolution[level].Lt.ptr(y1)+x1); - rx = *(evolution[level].Lx.ptr(y1)+x1); - ry = *(evolution[level].Ly.ptr(y1)+x1); - - di += ri; - dx += rx; - dy += ry; - nsamples++; - } - } - - di /= nsamples; - dx /= nsamples; - dy /= nsamples; - - *(values_2.ptr(dcount2)) = di; - *(values_2.ptr(dcount2)+1) = dx; - *(values_2.ptr(dcount2)+2) = dy; - dcount2++; - } - } - - //Do binary comparison second level - dcount2 = 0; - for (int i = 0; i < 9; i++) { - for (int j = i + 1; j < 9; j++) { - if (*(values_2.ptr(i)) > *(values_2.ptr(j))) { - desc[dcount1 / 8] |= (1 << (dcount1 % 8)); - } - dcount1++; - - if (*(values_2.ptr(i)+1) > *(values_2.ptr(j)+1)) { - desc[dcount1 / 8] |= (1 << (dcount1 % 8)); - } - dcount1++; - - if (*(values_2.ptr(i)+2) > *(values_2.ptr(j)+2)) { - desc[dcount1 / 8] |= (1 << (dcount1 % 8)); - } - dcount1++; - } - } - - // Third 4x4 grid - sample_step = pattern_size / 2; - dcount2 = 0; - - for (int i = -pattern_size; i < pattern_size; i += sample_step) { - for (int j = -pattern_size; j < pattern_size; j += sample_step) { - di = dx = dy = 0.0; - nsamples = 0; - - for (int k = i; k < i + sample_step; k++) { - for (int l = j; l < j + sample_step; l++) { - - // Get the coordinates of the sample point - sample_y = yf + l*scale; - sample_x = xf + k*scale; - - y1 = fRound(sample_y); - x1 = fRound(sample_x); - - ri = *(evolution[level].Lt.ptr(y1)+x1); - rx = *(evolution[level].Lx.ptr(y1)+x1); - ry = *(evolution[level].Ly.ptr(y1)+x1); - - di += ri; - dx += rx; - dy += ry; - nsamples++; - } - } - - di /= nsamples; - dx /= nsamples; - dy /= nsamples; - - *(values_3.ptr(dcount2)) = di; - *(values_3.ptr(dcount2)+1) = dx; - *(values_3.ptr(dcount2)+2) = dy; - dcount2++; - } - } - - //Do binary comparison third level - dcount2 = 0; - for (int i = 0; i < 16; i++) { - for (int j = i + 1; j < 16; j++) { - if (*(values_3.ptr(i)) > *(values_3.ptr(j))) { - desc[dcount1 / 8] |= (1 << (dcount1 % 8)); - } - dcount1++; - - if (*(values_3.ptr(i)+1) > *(values_3.ptr(j)+1)) { - desc[dcount1 / 8] |= (1 << (dcount1 % 8)); - } - dcount1++; - - if (*(values_3.ptr(i)+2) > *(values_3.ptr(j)+2)) { - desc[dcount1 / 8] |= (1 << (dcount1 % 8)); - } - dcount1++; - } - } + } // for (int z = 0; z < 3; z++) } void MLDB_Full_Descriptor_Invoker::MLDB_Fill_Values(float* values, int sample_step, int level,