Я разрабатываю алгоритм, который несколько раз вызывает функцию БПФ. У меня есть несколько ограничений по времени (желательно в режиме реального времени), поэтому мне нужно минимизировать время, затрачиваемое на каждый вызов БПФ.
Я работаю с библиотекой OpenCV и уже реализовал свой код двумя разными способами:
- Использование библиотеки FFTW. Управление данными/памятью + БПФ (8 мс) = 14 мс (в среднем, флаг FFT_MEASURE).
- Использование функции OpenCV fft. Управление данными/памятью + БПФ (21 мс) = 23 мс (в среднем).
Поскольку мои входные данные всегда фиксируются как реальное изображение размером 512x512 пикселей, как вы думаете, если я реализую алгоритм БПФ, основанный на математическом определении ДПФ, сохраняя таблицы синуса/косинуса, смогу ли я добиться лучшей производительности, или библиотека FFTW действительно сильно оптимизирован? Есть идеи получше?
Все идеи и предложения будут действительно оценены. На данный момент я не рассматриваю параллелизацию или реализацию GPU.
Спасибо
Обновление:
Система: процессор Intel Xeon 5130 2,0 ГГц в Windows 7, Visual Studio 10.0 и FFTW 3.3.3 (составлен по инструкциям на сайте), OpenCV 2.4.3.
Пример кода для вызова FFT с FFTW (вход: OpenCV Mat CV_32F (1 канал, тип с плавающей запятой), вывод OpenCV Mat CV_32FC2 (2 канала, тип с плавающей запятой):
float *im_data;
fftwf_complex *data_in;
fftwf_complex *fft;
fftwf_plan plan_f;
int i, j, k;
int height=I.rows;
int width=I.cols;
int N=height*width;
float* outdata = new float[2*N];
im_data = ( float* ) I.data;
data_in = ( fftwf_complex* )fftwf_malloc( sizeof( fftwf_complex ) * N );
fft = ( fftwf_complex* )fftwf_malloc( sizeof( fftwf_complex ) * N );
plan_f = fftwf_plan_dft_2d( height , width , data_in , fft , FFTW_FORWARD , FFTW_MEASURE );
for(int i = 0,k=0; i < height; ++i) {
float* row = I.ptr<float>(i);
for(int j = 0; j < width; j++) {
data_in[k][0]=(float)row[j];
data_in[k][1] =(float)0.0;
k++;
}
}
fftwf_execute( plan_f );
int width2=2*width;
// writing output matrix: RealFFT[0],ImaginaryFFT[0],RealFFT[1],ImaginaryFFT[1],...
for( i = 0, k = 0 ; i < height ; i++ ) {
for( j = 0 ; j < width2 ; j++ ) {
outdata[i * width2 + j] = ( float )fft[k][0];
outdata[i * width2 + j+1] = ( float )fft[k][1];
j++;
k++;
}
}
Mat fft_I(height,width,CV_32FC2,outdata);
fftwf_destroy_plan( plan_f );
fftwf_free( data_in );
fftwf_free( fft );
return fft_I;