C 无法使用FFT和FFTW检索原始图像

C 无法使用FFT和FFTW检索原始图像,c,valgrind,fftw,C,Valgrind,Fftw,我在我的C代码中使用FFTW,我有一些问题。 首先,我可以将一幅原始图像转换为两幅图像(mag+相位),然后通过逆变换得到原始图像。 然而,如果我想得到一个以频率为中心的mag文件,它就不再工作了:最终的图像有一些问题 这里是我的一些代码。有人能帮我找到代码中的错误吗 编辑:我已经修改了遵循@francis recommandation的代码,但我的问题总是在这里 enum { TYPE_CENTERED, TYPE_REGULAR }; static void fft_to

我在我的C代码中使用FFTW,我有一些问题。 首先,我可以将一幅原始图像转换为两幅图像(mag+相位),然后通过逆变换得到原始图像。 然而,如果我想得到一个以频率为中心的mag文件,它就不再工作了:最终的图像有一些问题

这里是我的一些代码。有人能帮我找到代码中的错误吗

编辑:我已经修改了遵循@francis recommandation的代码,但我的问题总是在这里


enum {
    TYPE_CENTERED,
    TYPE_REGULAR
};

static void fft_to_spectra(fits* fit, fftw_complex *frequency_repr, double *as,
        double *ps, int nbdata) {
    unsigned int i;

    for (i = 0; i < nbdata; i++) {
        double r = creal(frequency_repr[i]);
        double im = cimag(frequency_repr[i]);
        as[i] = hypot(r, im);
        ps[i] = atan2(im, r);
    }
}

static void fft_to_freq(fits* fit, fftw_complex *frequency_repr, double *as, double *ps, int nbdata) {
    unsigned int i;

    for (i = 0; i < nbdata; i++) {
        frequency_repr[i] = as[i] * (cos(ps[i]) + I * sin(ps[i]));
    }
}

void change_symmetry(unsigned int width, unsigned int height, unsigned int i, unsigned int j, unsigned int *x,
        unsigned int *y) {

    if (i < width / 2 && j < height / 2) {
        *x = i + width / 2;
        *y = j + height / 2;
    }
    if (i >= width / 2 && j < height / 2) {
        *x = i - width / 2;
        *y = j + height / 2;
    }
    if (i < width / 2 && j >= height / 2) {
        *x = i + width / 2;
        *y = j - height / 2;
    }
    if (i >= width / 2 && j >= height / 2) {
        *x = i - width / 2;
        *y = j - height / 2;
    }
}

static void centered(WORD *buf, unsigned int width,
        unsigned int height) {
    unsigned int i, j;

    WORD *temp = malloc(width * height * sizeof(WORD));
    for (j = 0; j < height; j++) {
        for (i = 0; i < width; i++) {
            unsigned int x = i;
            unsigned int y = j;
            change_symmetry(width, height, i, j, &x, &y);

            temp[j * width + i] = buf[y * width + x];
        }
    }

    memcpy(buf, temp, sizeof(WORD) * width * height);
    free(temp);
}

static void normalisation_spectra(unsigned int w, unsigned int h, double *modulus, double *phase,
        WORD *abuf, WORD *pbuf) {
    unsigned int i;

    for (i = 0; i < h * w; i++) {
        pbuf[i] = round_to_WORD(((phase[i] + M_PI) * USHRT_MAX_DOUBLE / (2 * M_PI)));
        abuf[i] = round_to_WORD((modulus[i] / w / h));
    }
}

static void save_dft_information_in_gfit(fits *fit) {
    strcpy(gfit.dft.ord, fit->dft.type);
    strcpy(gfit.dft.ord, fit->dft.ord);
}

static void FFTD(fits *fit, fits *x, fits *y, int type_order, int layer) {
    WORD *xbuf = x->pdata[layer];
    WORD *ybuf = y->pdata[layer];
    WORD *gbuf = fit->pdata[layer];
    unsigned int i;
    unsigned int width = fit->rx, height = fit->ry;
    int nbdata = width * height;

    fftw_complex *spatial_repr = fftw_malloc(sizeof(fftw_complex) * nbdata);
    if (!spatial_repr) {
        return;
    }
    fftw_complex *frequency_repr = fftw_malloc(sizeof(fftw_complex) * nbdata);
    if (!frequency_repr) {
        fftw_free(spatial_repr);
        return;
    }

    /* copying image selection into the fftw data */
#ifdef _OPENMP
#pragma omp parallel for num_threads(com.max_thread) private(i) schedule(static) if(nbdata > 15000)
#endif
    for (i = 0; i < nbdata; i++) {
        spatial_repr[i] = (double) gbuf[i];
    }

    /* we run the Fourier Transform */
    fftw_plan p = fftw_plan_dft_2d(height, width, spatial_repr, frequency_repr,
            FFTW_FORWARD, FFTW_ESTIMATE);
    fftw_execute(p);

    /* we compute modulus and phase */
    double *modulus = malloc(nbdata * sizeof(double));
    double *phase = malloc(nbdata * sizeof(double));

    fft_to_spectra(fit, frequency_repr, modulus, phase, nbdata);

    //We normalize the modulus and the phase
    normalisation_spectra(width, height, modulus, phase, xbuf, ybuf);
    if (type_order == TYPE_CENTERED) {
        strcpy(x->dft.ord, "CENTERED");
        centered(xbuf, width, height);
        centered(ybuf, width, height);
    }

    free(modulus);
    free(phase);
    fftw_destroy_plan(p);
    fftw_free(spatial_repr);
    fftw_free(frequency_repr);
}

static void FFTI(fits *fit, fits *xfit, fits *yfit, int type_order, int layer) {
    WORD *xbuf = xfit->pdata[layer];
    WORD *ybuf = yfit->pdata[layer];
    WORD *gbuf = fit->pdata[layer];
    unsigned int i;
    unsigned int width = xfit->rx;
    unsigned int height = xfit->ry;
    int nbdata = width * height;

    double *modulus = calloc(1, nbdata * sizeof(double));
    double *phase = calloc(1, nbdata * sizeof(double));

    if (type_order == TYPE_CENTERED) {
        centered(xbuf, width, height);
        centered(ybuf, width, height);
    }

    for (i = 0; i < height * width; i++) {
        modulus[i] = (double) xbuf[i] * (width * height);
        phase[i] = (double) ybuf[i] * (2 * M_PI / USHRT_MAX_DOUBLE);
        phase[i] -= M_PI;
    }

    fftw_complex* spatial_repr = fftw_malloc(sizeof(fftw_complex) * nbdata);
    if (!spatial_repr) {
        return;
    }

    fftw_complex* frequency_repr = fftw_malloc(sizeof(fftw_complex) * nbdata);
    if (!frequency_repr) {
        fftw_free(spatial_repr);
        return;
    }

    fft_to_freq(fit, frequency_repr, modulus, phase, nbdata);

    fftw_plan p = fftw_plan_dft_2d(height, width, frequency_repr, spatial_repr,
            FFTW_BACKWARD, FFTW_ESTIMATE);
    fftw_execute(p);

    for (i = 0; i < nbdata; i++) {
        double pxl = creal(spatial_repr[i]) / nbdata;
        gbuf[i] = round_to_WORD(pxl);
    }

    free(modulus);
    free(phase);
    fftw_destroy_plan(p);
    fftw_free(spatial_repr);
    fftw_free(frequency_repr);
}

枚举{
以U型为中心,
规则型
};
静态空隙fft到频谱(fits*fit,fftw\U复数*频率报告,双*as,
双精度*ps,整数(数据){
无符号整数i;
对于(i=0;i=宽度/2和&j<高度/2){
*x=i-宽度/2;
*y=j+高度/2;
}
如果(i=height/2){
*x=i+宽度/2;
*y=j——高度/2;
}
如果(i>=宽度/2和&j>=高度/2){
*x=i-宽度/2;
*y=j——高度/2;
}
}
静态空心居中(字*buf,无符号整数宽度,
无符号整数高度){
无符号整数i,j;
WORD*temp=malloc(宽度*高度*尺寸(WORD));
对于(j=0;jdft.type);
strcpy(gfit.dft.ord,fit->dft.ord);
}
静态无效FFTD(配合*fit,配合*x,配合*y,整数类型\顺序,整数层){
WORD*xbuf=x->pdata[图层];
WORD*ybuf=y->pdata[层];
WORD*gbuf=fit->pdata[图层];
无符号整数i;
无符号整数宽度=fit->rx,高度=fit->ry;
int nbdata=宽度*高度;
fftw_复合体*spatial_repr=fftw_malloc(sizeof(fftw_复合体)*nbdata);
如果(!空间报告){
返回;
}
fftw_复合体*频率_repr=fftw_malloc(sizeof(fftw_复合体)*nbdata);
如果(!频率报告){
fftw_free(空间报告);
返回;
}
/*将图像选择复制到fftw数据中*/
#ifdef\u OPENMP
#用于num_线程(com.max_线程)的pragma omp并行专用(i)调度(静态)if(nbdata>15000)
#恩迪夫
对于(i=0;idft.ord,“居中”);
居中(xbuf、宽度、高度);
居中(ybuf、宽度、高度);
}
自由(模量);
自由(相位);
fftw销毁计划(p);
fftw_free(空间报告);
无fftw(频率报告);
}
静态无效FFTI(拟合*拟合,拟合*xfit,拟合*yfit,整数类型\顺序,整数层){
WORD*xbuf=xfit->pdata[层];
WORD*ybuf=yfit->pdata[层];
WORD*gbuf=fit->pdata[图层];
无符号整数i;
无符号整数宽度=xfit->rx;
无符号整数高度=xfit->ry;
int nbdata=宽度*高度;
double*模数=calloc(1,nbdata*sizeof(double));
双*相位=calloc(1,nbdata*sizeof(双));
if(类型\顺序==类型\居中){
居中(xbuf、宽度、高度);
居中(ybuf、宽度、高度);
}
对于(i=0;i<高度*宽度;i++){
模数[i]=(双)xbuf[i]*(宽*高);
相位[i]=(双)ybuf[i]*(2*M\uπ/USHRT\u最大值\u双);
相位[i]=muπ;
}
fftw_复合体*spatial_repr=fftw_malloc(sizeof(fftw_复合体)*nbdata);
如果(!空间报告){
返回;
}
fftw_复合体*频率_repr=fftw_malloc(sizeof(fftw_复合体)*nbdata);
如果(!频率报告){
fftw_free(空间报告);
返回;
}
fft到频率(拟合、频率报告、模数、相位、nbdata);
fftw_平面图p=fftw_平面图dft_2d(高度、宽度、频率、空间),
FFTW_向后,FFTW_估计);
fftw_执行(p);
对于(i=0;i
这里是我的图片,原始图片和FFTD(居中)->FFTI结果

该计划是使用标志
FFTW\u MEASURE
创建的。因此,计算了几个DFT
/* we run the Fourier Transform */
fftw_plan p = fftw_plan_dft_2d(width, height, spatial_repr, frequency_repr,
        FFTW_FORWARD, FFTW_MEASURE);

/* copying image selection into the fftw data */
#ifdef _OPENMP
#pragma omp parallel for num_threads(com.max_thread) private(i) schedule(static) if(nbdata > 15000)
#endif
for (i = 0; i < nbdata; i++) {
    spatial_repr[i] = (double) gbuf[i];
}
fftw_execute_dft(p, spatial_repr, frequency_repr);
void change_symmetry_forward(unsigned int width, unsigned int height, unsigned int i, unsigned int j, unsigned int *x,
    unsigned int *y) {
     *x = i + width / 2;
     if (*x>=width){
           *x=*x-width;
     }
     *y = j + height / 2;
     if(*y>=height){
          *y =*y-height;
     }
}
void change_symmetry_backward(unsigned int width, unsigned int height, unsigned int i, unsigned int j, unsigned int *x,
    unsigned int *y) {
     *x = i +width- width / 2;
     if (*x>=width){
           *x=*x-width;
     }
     *y = j +height- height / 2;
     if(*y>=height){
          *y =*y-height;
     }
}