Path: blob/master/modules/features2d/src/kaze/fed.cpp
16337 views
//=============================================================================1//2// fed.cpp3// Authors: Pablo F. Alcantarilla (1), Jesus Nuevo (2)4// Institutions: Georgia Institute of Technology (1)5// TrueVision Solutions (2)6// Date: 15/09/20137// Email: [email protected]8//9// AKAZE Features Copyright 2013, Pablo F. Alcantarilla, Jesus Nuevo10// All Rights Reserved11// See LICENSE for the license information12//=============================================================================1314/**15* @file fed.cpp16* @brief Functions for performing Fast Explicit Diffusion and building the17* nonlinear scale space18* @date Sep 15, 201319* @author Pablo F. Alcantarilla, Jesus Nuevo20* @note This code is derived from FED/FJ library from Grewenig et al.,21* The FED/FJ library allows solving more advanced problems22* Please look at the following papers for more information about FED:23* [1] S. Grewenig, J. Weickert, C. Schroers, A. Bruhn. Cyclic Schemes for24* PDE-Based Image Analysis. Technical Report No. 327, Department of Mathematics,25* Saarland University, Saarbrücken, Germany, March 201326* [2] S. Grewenig, J. Weickert, A. Bruhn. From box filtering to fast explicit diffusion.27* DAGM, 201028*29*/30#include "../precomp.hpp"31#include "fed.h"3233using namespace std;3435//*************************************************************************************36//*************************************************************************************3738/**39* @brief This function allocates an array of the least number of time steps such40* that a certain stopping time for the whole process can be obtained and fills41* it with the respective FED time step sizes for one cycle42* The function returns the number of time steps per cycle or 0 on failure43* @param T Desired process stopping time44* @param M Desired number of cycles45* @param tau_max Stability limit for the explicit scheme46* @param reordering Reordering flag47* @param tau The vector with the dynamic step sizes48*/49int fed_tau_by_process_time(const float& T, const int& M, const float& tau_max,50const bool& reordering, std::vector<float>& tau) {51// All cycles have the same fraction of the stopping time52return fed_tau_by_cycle_time(T/(float)M,tau_max,reordering,tau);53}5455//*************************************************************************************56//*************************************************************************************5758/**59* @brief This function allocates an array of the least number of time steps such60* that a certain stopping time for the whole process can be obtained and fills it61* it with the respective FED time step sizes for one cycle62* The function returns the number of time steps per cycle or 0 on failure63* @param t Desired cycle stopping time64* @param tau_max Stability limit for the explicit scheme65* @param reordering Reordering flag66* @param tau The vector with the dynamic step sizes67*/68int fed_tau_by_cycle_time(const float& t, const float& tau_max,69const bool& reordering, std::vector<float> &tau) {70int n = 0; // Number of time steps71float scale = 0.0; // Ratio of t we search to maximal t7273// Compute necessary number of time steps74n = cvCeil(sqrtf(3.0f*t/tau_max+0.25f)-0.5f-1.0e-8f);75scale = 3.0f*t/(tau_max*(float)(n*(n+1)));7677// Call internal FED time step creation routine78return fed_tau_internal(n,scale,tau_max,reordering,tau);79}8081//*************************************************************************************82//*************************************************************************************8384/**85* @brief This function allocates an array of time steps and fills it with FED86* time step sizes87* The function returns the number of time steps per cycle or 0 on failure88* @param n Number of internal steps89* @param scale Ratio of t we search to maximal t90* @param tau_max Stability limit for the explicit scheme91* @param reordering Reordering flag92* @param tau The vector with the dynamic step sizes93*/94int fed_tau_internal(const int& n, const float& scale, const float& tau_max,95const bool& reordering, std::vector<float> &tau) {96float c = 0.0, d = 0.0; // Time savers97vector<float> tauh; // Helper vector for unsorted taus9899if (n <= 0) {100return 0;101}102103// Allocate memory for the time step size104tau = vector<float>(n);105106if (reordering) {107tauh = vector<float>(n);108}109110// Compute time saver111c = 1.0f / (4.0f * (float)n + 2.0f);112d = scale * tau_max / 2.0f;113114// Set up originally ordered tau vector115for (int k = 0; k < n; ++k) {116float h = cosf((float)CV_PI * (2.0f * (float)k + 1.0f) * c);117118if (reordering) {119tauh[k] = d / (h * h);120}121else {122tau[k] = d / (h * h);123}124}125126// Permute list of time steps according to chosen reordering function127int kappa = 0, prime = 0;128129if (reordering == true) {130// Choose kappa cycle with k = n/2131// This is a heuristic. We can use Leja ordering instead!!132kappa = n / 2;133134// Get modulus for permutation135prime = n + 1;136137while (!fed_is_prime_internal(prime)) {138prime++;139}140141// Perform permutation142for (int k = 0, l = 0; l < n; ++k, ++l) {143int index = 0;144while ((index = ((k+1)*kappa) % prime - 1) >= n) {145k++;146}147148tau[l] = tauh[index];149}150}151152return n;153}154155//*************************************************************************************156//*************************************************************************************157158/**159* @brief This function checks if a number is prime or not160* @param number Number to check if it is prime or not161* @return true if the number is prime162*/163bool fed_is_prime_internal(const int& number) {164bool is_prime = false;165166if (number <= 1) {167return false;168}169else if (number == 1 || number == 2 || number == 3 || number == 5 || number == 7) {170return true;171}172else if ((number % 2) == 0 || (number % 3) == 0 || (number % 5) == 0 || (number % 7) == 0) {173return false;174}175else {176is_prime = true;177int upperLimit = (int)sqrt(1.0f + number);178int divisor = 11;179180while (divisor <= upperLimit ) {181if (number % divisor == 0)182{183is_prime = false;184}185186divisor +=2;187}188189return is_prime;190}191}192193194