1

我正在尝试使用 C++ 接口使用 FFTW 3.3 和 OpenCV 2.1 编写 FFT/IFFT 函数。我见过很多使用旧 OpenCV 格式的示例,我进行了直接转换,但有些东西不起作用。

我的函数的目标是返回一个具有 FFT 实部和虚部的 Mat 对象,就像 dft 默认 OpenCV 函数一样。这是函数的代码。程序在将 im_data 复制到 data_in 的行中因内存问题而阻塞。

有人知道我在做什么错吗?谢谢

Mat fft_sr(Mat& I)
{

double          *im_data;
double          *realP_data;
double          *imP_data;

fftw_complex    *data_in;
fftw_complex    *fft;      

fftw_plan       plan_f;

int width     = I.cols;
int height    = I.rows;
int step      = I.step;

int             i, j, k;

Mat realP=Mat::zeros(height,width,CV_64F); // Real Part FFT
Mat imP=Mat::zeros(height,width,CV_64F); // Imaginary Part FFT


im_data = ( double* ) I.data;
realP_data = ( double* ) realP.data;
imP_data = ( double* ) imP.data;


data_in = ( fftw_complex* )fftw_malloc( sizeof( fftw_complex ) * width * height );
fft     = ( fftw_complex* )fftw_malloc( sizeof( fftw_complex ) * width * height );

// Problem Here
for( i = 0, k = 0 ; i < height ; i++ ) {
    for( j = 0 ; j < width ; j++ ) {
        data_in[k][0] = ( double )im_data[i * step + j];
        data_in[k][1] = ( double )0.0;
        k++;
    }
}


plan_f = fftw_plan_dft_2d( height, width, data_in, fft,  FFTW_FORWARD,  FFTW_ESTIMATE );


fftw_execute( plan_f );

// Copy real and imaginary data
for( i = 0, k = 0 ; i < height ; i++ ) {
    for( j = 0 ; j < width ; j++ ) {
        realP_data[i * step + j] = ( double )fft[k][0];
        imP_data[i * step + j] = ( double )fft[k][1];
        k++;

    }
}



Mat fft_I(I.size(),CV_64FC2);
Mat fftplanes[] = {Mat_<double>(realP), Mat_<double>(imP)};
merge(fftplanes, 2, fft_I);

fftw_destroy_plan(plan_f);
fftw_free(data_in);
fftw_free(fft);
return fft_I;   
}
4

3 回答 3

3

你用step错了。它旨在索引到Mat::data. 由于您在将其分配Mat::data给时已经转换为,因此您可以索引到“通常”:double*im_dataim_data

data_in[k][0] = im_data[i * width + j];

使用step正确的索引方式时是:

data_in[k][0] = ( double )I.data[i * step + j];

更新:

尝试按行访问您的图像。这样您就可以避免遇到步幅/步幅问题,同时仍然利用快速访问:

for (int i = 0; i < I.rows; i++)
{
    double* row = I.ptr<double>(i);

    for (int j = 0; j < I.cols; j++)
    {
        // Do something with the current pixel.
        double someValue = row[j];
    }
}
于 2012-11-26T13:04:56.077 回答
0

我知道这很旧,但是当您使用 fftw 时,您 fftw_complex *data_in 只需要在为 fft 创建计划之后进行初始化,如果我没记错的话,当您创建计划时它会将所有 *data_in值设置为 0。所以在计划之前分配并在之后初始化!

于 2014-02-15T20:41:21.720 回答
0

陈述

im_data = ( double* ) I.data;

定义im_datadouble指向图像数据的指针。我认为这应该是强制性的,这I是一个双重价值形象。

于 2021-11-23T14:47:30.297 回答