cv::getOptimalDFTSize --- OpenCV代码阅读

在DFT中,可以使用FFT来加速,但是如果选个长度很坑爹如某个素数,那FFT就惨了,直接发挥不了作用,这个时候就可以对原始的数据长度进行扩展,最好是2^x(<--一般书上都这样写`不是一般性`我们假设长度是2^n,每次我都看的很郁闷),但是发现1,2,4,....中间的跨度很大,如果我的序列长度是 2^n+1 那就得选得2^(n+1)对内存来说是巨大的浪费,OpenCV中选择的是2^x*3^y*5^z,这样子选择256+1时可以选择270(3^3*2*5),没必要一下子选择512,来浪费内存.

当然在OpenCV中是维护了一张表optimalDFTSizeTab,属于空间换时间的方法,没有使用如下的方法

int getMultipliers(int n, int *n1, int *n2)

{

    int multiplier, i;

    if (n == 1)

    {

        *n1 = 1;

        *n2 = 1;

        return FFT_ERROR; // n = 1

    }

    multiplier = n / 2;

    for (i = multiplier; i >= 2; i--)

    {

        if (n % i == 0)

        {

            *n1 = i;

            *n2 = n / i;

            return FFT_OK; // n = n1 * n2

        }

    }

    *n1 = 1;

    *n2 = n;

    return FFT_ERROR; // n - prime number

}

当然其实上面的代码也是在OpenCV中的.

建立表后就可以查找值了.

查找使用传说中的二分法.

int cv::getOptimalDFTSize( int size0 )

{

    int a = 0, b = sizeof(optimalDFTSizeTab)/sizeof(optimalDFTSizeTab[0]) - 1;

    if( (unsigned)size0 >= (unsigned)optimalDFTSizeTab[b] )

        return -1;



    while( a < b )

    {

        int c = (a + b) >> 1;

        if( size0 <= optimalDFTSizeTab[c] )

            b = c;

        else

            a = c+1;

    }



    return optimalDFTSizeTab[b];

}

开始时判断是否在表中,如果在的话迭代搜索,速度很快.....

你可能感兴趣的:(opencv)