我尝试使用C ++接口使用FFTW 3.3和OpenCV 2.1编写FFT / IFFT函数。我已经看过许多使用旧OpenCV格式的例子,我做了直接转换,但有些东西不起作用。
我的函数的目标是返回一个Mat对象,其中包含FFT的实部和虚部,就像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;
}
答案 0 :(得分:3)
您使用step
错误。它旨在索引Mat::data
。由于您在将Mat::data
分配给double*
时已将im_data
投放到im_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];
}
}
<强>更新强>
尝试按行访问您的图片。这样你就可以避免遇到stride / step的问题,同时仍然利用快速访问:
{{1}}
答案 1 :(得分:0)
我知道这是旧的,但是当你使用fftw时,你需要初始化fftw_complex *data_in
只有在为fft创建计划之后,如果我在创建计划时正确回想起它会设置所有
*data_in
值为0。
所以在计划之前分配并在之后初始化!