Рисование спектра изображения в C ++ (fftw, OpenCV) - PullRequest
2 голосов
/ 31 июля 2011

Я пытаюсь создать программу, которая будет рисовать 2-мерный спектр серого для заданного изображения. Я использую библиотеки OpenCV и FFTW. Используя советы и коды из интернета и модифицируя их, мне удалось загрузить изображение, рассчитать fft этого изображения и воссоздать изображение из fft (это то же самое). Что я не могу сделать, так это нарисовать сам спектр Фурье. Не могли бы вы мне помочь? Вот код (удалены менее важные строки):

/* Copy input image */

/* Create output image */

/* Allocate input data for FFTW */
in   = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * N);
dft  = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * N);

/* Create plans */
plan_f = fftw_plan_dft_2d(w, h, in, dft, FFTW_FORWARD, FFTW_ESTIMATE);

/* Populate input data in row-major order */
for (i = 0, k = 0; i < h; i++) 
{
    for (j = 0; j < w; j++, k++)
    {
        in[k][0] = ((uchar*)(img1->imageData + i * img1->widthStep))[j];
        in[k][1] = 0.;
    }
}

/* forward DFT */
fftw_execute(plan_f);

/* spectrum */
for (i = 0, k = 0; i < h; i++)
{
    for (j = 0; j < w; j++, k++)
        ((uchar*)(img2->imageData + i * img2->widthStep))[j] = sqrt(pow(dft[k][0],2) + pow(dft[k][1],2));
}       

cvShowImage("iplimage_dft(): original", img1);
cvShowImage("iplimage_dft(): result", img2);
cvWaitKey(0);

/* Free memory */

}

Проблема в разделе "Спектр". Вместо спектра я получаю шум. Что я делаю неправильно? Буду благодарен за вашу помощь.

Ответы [ 2 ]

1 голос
/ 16 августа 2012

Вам нужно нарисовать величину спектра.вот код.

void ForwardFFT(Mat &Src, Mat *FImg)
{
    int M = getOptimalDFTSize( Src.rows );
    int N = getOptimalDFTSize( Src.cols );
    Mat padded;    
    copyMakeBorder(Src, padded, 0, M - Src.rows, 0, N - Src.cols, BORDER_CONSTANT, Scalar::all(0));
    // Создаем комплексное представление изображения
    // planes[0] содержит само изображение, planes[1] его мнимую часть (заполнено нулями)
    Mat planes[] = {Mat_<float>(padded), Mat::zeros(padded.size(), CV_32F)};
    Mat complexImg;
    merge(planes, 2, complexImg); 
    dft(complexImg, complexImg);    
    // После преобразования результат так-же состоит из действительной и мнимой части
    split(complexImg, planes);

    // обрежем спектр, если у него нечетное количество строк или столбцов
    planes[0] = planes[0](Rect(0, 0, planes[0].cols & -2, planes[0].rows & -2));
    planes[1] = planes[1](Rect(0, 0, planes[1].cols & -2, planes[1].rows & -2));

    Recomb(planes[0],planes[0]);
    Recomb(planes[1],planes[1]);
    // Нормализуем спектр
    planes[0]/=float(M*N);
    planes[1]/=float(M*N);
    FImg[0]=planes[0].clone();
    FImg[1]=planes[1].clone();
}
void ForwardFFT_Mag_Phase(Mat &src, Mat &Mag,Mat &Phase)
{
    Mat planes[2];
    ForwardFFT(src,planes);
    Mag.zeros(planes[0].rows,planes[0].cols,CV_32F);
    Phase.zeros(planes[0].rows,planes[0].cols,CV_32F);
    cv::cartToPolar(planes[0],planes[1],Mag,Phase);
}
Mat LogMag;
    LogMag.zeros(Mag.rows,Mag.cols,CV_32F);
    LogMag=(Mag+1);
    cv::log(LogMag,LogMag);
    //---------------------------------------------------
    imshow("Логарифм амплитуды", LogMag);
    imshow("Фаза", Phase);
    imshow("Результат фильтрации", img);  
0 голосов
/ 01 сентября 2011

Можете ли вы попробовать выполнить IFFT и посмотреть, восстановите ли вы исходное изображение? Затем вы можете проверить шаг за шагом, где ваша проблема. Другим решением этой проблемы является выполнение этого процесса с предопределенной вами небольшой матрицей, вычисление ее FFT в MATLAB и проверка шаг за шагом, она работает для меня!

...