2011-07-31 7 views
2

주어진 이미지의 2 차원 그레이 스케일 스펙트럼을 그리는 프로그램을 만들려고합니다. OpenCV 및 FFTW 라이브러리를 사용하고 있습니다. 인터넷의 도움말과 코드를 사용하여 이미지를로드하고 이미지의 fft를 계산 한 다음 fft에서 이미지를 다시 만들었습니다 (동일 함). 내가 할 수없는 것은 푸리에 스펙트럼 자체를 그리는 것입니다. 저 좀 도와 주 시겠어요?C++ (fftw, OpenCV)에서 이미지의 스펙트럼 그리기

/* 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 */ 

}

문제는 "스펙트럼"섹션에 있습니다 다음은 코드 (제거 덜 중요한 라인)입니다. 스펙트럼 대신 나는 약간의 잡음을 얻는다. 내가 도대체 ​​뭘 잘못하고있는 겁니까? 나는 당신의 도움에 감사 할 것입니다.

+0

소리는 스케일링 문제와 유사합니다. FFT 출력 크기 값의 범위를 확인해야합니다. –

+0

그리고 어떻게해야합니까? 내가 다른 포럼에서 읽은 것에서, 크기 정도면 검은 색 이미지 (중앙에 흰색 점이 찍힌)가 생길 것입니다. 답변 주셔서 감사합니다. – Narren

+1

크기에 대한 범위 검사를 수행하지 않으므로 크기가 크면 8 비트 픽셀에 할당 할 때 모듈로 2를 래핑합니다 (그러면 노이즈처럼 보일 것입니다). 그래서 범위를 확인해야한다고 말한 것입니다. 다른 루프를 추가하여 최대 및 최소 크기를 찾은 다음 해당 값이 8 비트 범위에 맞는지 알 수 있도록 값을 조정하십시오. –

답변

0

IFFT 단계를 수행하고 원본 이미지를 복구 할 수 있습니까? 그런 다음 문제가있는 단계를 단계별로 확인할 수 있습니다. 문제를 찾는 또 다른 해결책은 미리 정의 된 작은 행렬을 사용하여이 과정을 수행하고 MATLAB에서 FFT를 계산하고 단계별로 확인하십시오.

1

스펙트럼의 크기를 그려야합니다. 여기 코드가 있습니다.

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);