Интерфейс FFTW и OpenCV C ++, действительная и мнимая часть в выводе Mat

Я пытаюсь кодировать функцию FFT / IFFT с FFTW 3.3 и OpenCV 2.1, используя интерфейс C ++. Я видел много примеров использования старых форматов OpenCV и сделал прямое преобразование, но что-то не работает.

Цель моей функции — вернуть объект Mat с реальной частью и мнимой частью FFT, как это делает функция OpenCV по умолчанию в dft. Вот код функции. Программа блокируется из-за проблем с памятью в строках, которые копируют 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 FFTim_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;
}

1

Решение

Ты используешь 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];
}
}
3

Другие решения

Я знаю, что это старый, но когда вы используете fftw, вам нужно инициализировать fftw_complex *data_in
только после создания плана для БПФ, если я правильно помню, когда вы создаете план, он устанавливает все
*data_in значения до 0.
так что выделите до плана и инициализируйте после!

0

По вопросам рекламы [email protected]