我在Qt中创建了一个应用程序,它允许我打开图像并使用FFTW库进行2D FFT变换。问题是我无法通过反向转换检索正确的像素值。但是,让我们从开始开始吧。
这就是我使用
的FFTW功能void FFTInterface::FFTW(int rows, int cols, QColor **imageInput,fftw_complex * in, fftw_complex * out)
{
fftw_plan g;
g = fftw_plan_dft_2d(rows, cols, in, out, FFTW_FORWARD, FFTW_MEASURE);
int k = 0;
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
in[k][0] = imageInput[i][j].red();
in[k][1] = 0.0;
k++;
}
}
fftw_execute(g);
fftw_destroy_plan(g);
}
rows,cols 是图片的大小, imageInput 是QColor的数组,它保留像素值(灰度), 和 out 是fftw_complex,输入和输出数组的对象。
这个函数给我一些结果,必须显示。要做到这一点,我做了一些scalling。首先,我对每个值使用abs()函数,以确保它具有正值。之后,我缩放结果。
void FFTInterface::Abs(fftw_complex *out, int rows, int cols)
{
int k = 0;
for(int i = 0; i < rows; i++){
for(int j = 0; j<cols; j++){
out[k][0] = abs(out[k][0]);
out[k][1] = abs(out[k][1]);
k++;
}
}
}
void FFTInterface::Scale(fftw_complex * in,int rows, int cols)
{
float c = 255.0 / log(1+Max(in,rows,cols));
int k = 0;
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
in[k][0] = c*log(1+in[k][0]);
in[k][1] = c*log(1+in[k][0]);
k++;
}
}
}
这个过程给了我一些我需要的东西。图像看起来不错。但我有问题将图像恢复为原始图像。 BACKWARD的功能如下所示
void FFTInterface::IFFTW(int rows, int cols, fftw_complex * in, fftw_complex * out)
{
fftw_plan g;
g = fftw_plan_dft_2d(rows, cols, in, out, FFTW_BACKWARD, FFTW_MEASURE);
int k = 0;
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
in[k][1] = 0.0;
k++;
}
}
fftw_execute(g);
fftw_destroy_plan(g);
}
我发现某个地方没有规范化(结果非常大)。为了标准化我只是将值除以N(256,512等) - 图像的宽度或高度(它总是一个正方形),但值与原始值不同。
你知道我遗失的地方吗? Scalling?我应该使用库中的其他fft方法?我坚持了。
答案 0 :(得分:2)
通过获取绝对值并缩放复杂组件以显示图像,您正在修改数据,使得逆变换不再为您提供原始输入。为避免此问题,我建议您在缩放之前创建要显示的数据的副本。另外,请确保不要忘记逆变换的输入应该是正向变换的输出(或者可能是信号处理链中的最后一个输出)。
在伪代码中你可以这样做:
interface.FFTW(rows, cols, imageInput, in, out);
size_t N = rows*cols;
fftw_complex* todisplay = fftw_malloc(N);
std::copy(out, out+N, todisplay);
interface.Abs(todisplay);
interface.Scale(todisplay);
... display "todisplay" on your Qt user interface
fftw_free(todislay);
interface.IFFTW(rows, cols, out, reconstructed);