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];
}

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

posted @ 2012-07-18 10:53  zhuangzhuang1988  阅读(2886)  评论(1编辑  收藏  举报