二维图像上的 FFTW 错误反向变换 [with Qt]
FFTW wrong backward transform on 2D image [with Qt]
我在 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的数组,保存像素值(灰度) , in 和 out 是 fftw_complex 输入和输出数组的对象。
这个函数给我一些结果,必须显示出来。为此,我进行了某种缩放。首先,我对每个值都使用 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 等)- 图像的宽度或高度(它始终是一个正方形),但这些值与原始值不同。
你知道我遗漏了什么吗?缩放?我应该使用库中的其他 fft 方法吗?我卡住了。
为了显示图像而采用绝对值和缩放复杂组件,您正在以逆变换不再为您提供原始输入的方式修改数据。为避免此问题,我建议您在缩放之前创建要显示的数据的副本。另外,请确保不要忘记逆变换的输入应该是正向变换的输出(或者可能是信号处理链中的最后一个输出)。
在伪代码中你可以这样做:
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);
我在 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的数组,保存像素值(灰度) , in 和 out 是 fftw_complex 输入和输出数组的对象。
这个函数给我一些结果,必须显示出来。为此,我进行了某种缩放。首先,我对每个值都使用 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 等)- 图像的宽度或高度(它始终是一个正方形),但这些值与原始值不同。
你知道我遗漏了什么吗?缩放?我应该使用库中的其他 fft 方法吗?我卡住了。
为了显示图像而采用绝对值和缩放复杂组件,您正在以逆变换不再为您提供原始输入的方式修改数据。为避免此问题,我建议您在缩放之前创建要显示的数据的副本。另外,请确保不要忘记逆变换的输入应该是正向变换的输出(或者可能是信号处理链中的最后一个输出)。
在伪代码中你可以这样做:
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);