Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/image/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ c+中奇异但相近的图像fft和ifft+;_C++_Image_Image Processing_Fft_Ifft - Fatal编程技术网

C++ c+中奇异但相近的图像fft和ifft+;

C++ c+中奇异但相近的图像fft和ifft+;,c++,image,image-processing,fft,ifft,C++,Image,Image Processing,Fft,Ifft,我编写了一个程序,加载、保存并对黑白png图像执行fft和ifft。经过多次调试,我终于得到了一些相干输出,结果发现它扭曲了原始图像 输入: 快速傅立叶变换: ifft: 据我测试,每个阵列中的像素数据都被正确存储和转换。像素存储在两个数组中,“数据”包含每个像素的b/w值,“复数数据”是“数据”的两倍,并以交替索引存储每个像素的实b/w值和虚部。我的fft算法在类似“复杂数据”的数组结构上运行。在从用户处读取命令的代码之后,下面是有问题的代码: if (cmd == "fft")

我编写了一个程序,加载、保存并对黑白png图像执行fft和ifft。经过多次调试,我终于得到了一些相干输出,结果发现它扭曲了原始图像

输入:

快速傅立叶变换:

ifft:

据我测试,每个阵列中的像素数据都被正确存储和转换。像素存储在两个数组中,“数据”包含每个像素的b/w值,“复数数据”是“数据”的两倍,并以交替索引存储每个像素的实b/w值和虚部。我的fft算法在类似“复杂数据”的数组结构上运行。在从用户处读取命令的代码之后,下面是有问题的代码:

if (cmd == "fft")
        {              
            if (height > width) size = height;
            else size = width;

            N = (int)pow(2.0, ceil(log((double)size)/log(2.0)));

            temp_data = (double*) malloc(sizeof(double) * width * 2); //array to hold each row of the image for processing in FFT()

            for (i = 0; i < (int) height; i++)
            {
                for (j = 0; j < (int) width; j++)
                {
                    temp_data[j*2] = complex_data[(i*width*2)+(j*2)];
                    temp_data[j*2+1] = complex_data[(i*width*2)+(j*2)+1];
                }
                FFT(temp_data, N, 1);
                for (j = 0; j < (int) width; j++)
                {
                    complex_data[(i*width*2)+(j*2)] = temp_data[j*2];
                    complex_data[(i*width*2)+(j*2)+1] = temp_data[j*2+1];
                }
            }
            transpose(complex_data, width, height); //tested
            free(temp_data);
            temp_data = (double*) malloc(sizeof(double) * height * 2);
            for (i = 0; i < (int) width; i++)
            {
                for (j = 0; j < (int) height; j++)
                {
                    temp_data[j*2] = complex_data[(i*height*2)+(j*2)];
                    temp_data[j*2+1] = complex_data[(i*height*2)+(j*2)+1];
                }
                FFT(temp_data, N, 1);
                for (j = 0; j < (int) height; j++)
                {
                    complex_data[(i*height*2)+(j*2)] = temp_data[j*2];
                    complex_data[(i*height*2)+(j*2)+1] = temp_data[j*2+1];
                }
            }
            transpose(complex_data, height, width);

            free(temp_data);
            free(data);

            data = complex_to_real(complex_data, image.size()/4); //tested
            image = bw_data_to_vector(data, image.size()/4); //tested
            cout << "*** fft success ***" << endl << endl;



void FFT(double* data, unsigned long nn, int f_or_b){ // f_or_b is 1 for fft, -1 for ifft

unsigned long n, mmax, m, j, istep, i;
double wtemp, w_real, wp_real, wp_imaginary, w_imaginary, theta;
double temp_real, temp_imaginary;

// reverse-binary reindexing to separate even and odd indices
// and to allow us to compute the FFT in place

n = nn<<1;
j = 1;
for (i = 1; i < n; i += 2) {
    if (j > i) {
        swap(data[j-1], data[i-1]);
        swap(data[j], data[i]);
    }
    m = nn;
    while (m >= 2 && j > m) {
        j -= m;
        m >>= 1;
    }
    j += m;
};

// here begins the Danielson-Lanczos section

mmax = 2;
while (n > mmax) {
    istep = mmax<<1;
    theta = f_or_b * (2 * M_PI/mmax);
    wtemp = sin(0.5 * theta);
    wp_real = -2.0 * wtemp * wtemp;
    wp_imaginary = sin(theta);
    w_real = 1.0;
    w_imaginary = 0.0;
    for (m = 1; m < mmax; m += 2) {
        for (i = m; i <= n; i += istep) {
            j = i + mmax;
            temp_real = w_real * data[j-1] - w_imaginary * data[j];
            temp_imaginary = w_real * data[j] + w_imaginary * data[j-1];

            data[j-1] = data[i-1] - temp_real;
            data[j] = data[i] - temp_imaginary;
            data[i-1] += temp_real;
            data[i] += temp_imaginary;
        }
        wtemp = w_real;
        w_real += w_real * wp_real - w_imaginary * wp_imaginary;
        w_imaginary += w_imaginary * wp_real + wtemp * wp_imaginary;
    }
    mmax=istep;
}}
if(cmd==“fft”)
{              
如果(高度>宽度)尺寸=高度;
尺寸=宽度;
N=(int)pow(2.0,ceil(对数((双)大小)/log(2.0));
temp_data=(double*)malloc(sizeof(double)*width*2);//用于保存图像的每一行以便在FFT()中进行处理的数组
对于(i=0;i<(int)高度;i++)
{
对于(j=0;j<(int)宽度;j++)
{
temp_数据[j*2]=复数_数据[(i*width*2)+(j*2)];
温度数据[j*2+1]=复杂的温度数据[(i*width*2)+(j*2)+1];
}
FFT(温度数据,N,1);
对于(j=0;j<(int)宽度;j++)
{
复数_数据[(i*宽度*2)+(j*2)]=温度_数据[j*2];
复数_数据[(i*width*2)+(j*2)+1]=临时_数据[j*2+1];
}
}
转置(复数_数据、宽度、高度);//已测试
免费(临时数据);
温度数据=(双*)malloc(尺寸(双)*高度*2);
对于(i=0;i<(int)宽度;i++)
{
对于(j=0;j<(int)高度;j++)
{
温度数据[j*2]=复杂的温度数据[(i*高度*2)+(j*2)];
温度数据[j*2+1]=复杂的温度数据[(i*高度*2)+(j*2)+1];
}
FFT(温度数据,N,1);
对于(j=0;j<(int)高度;j++)
{
复数_数据[(i*高度*2)+(j*2)]=温度_数据[j*2];
复合_数据[(i*高度*2)+(j*2)+1]=温度_数据[j*2+1];
}
}
转置(复数_数据、高度、宽度);
免费(临时数据);
免费(数据);
data=complex_to_real(complex_数据,image.size()/4);//已测试
image=bw_data_to_vector(data,image.size()/4);//已测试
cout=1;
}
j+=m;
};
//这里开始丹尼尔森·兰佐斯的部分
mmax=2;
而(n>mmax){

istep=mmax不是一个实际的答案,因为这个问题只是调试而已,所以需要一些提示:

你的成绩真糟糕

应该是这样的:

  • 第一行是实际的DFFT结果
  • Re,Im,Power
    被一个常数放大,否则你会看到一个黑色图像
  • 最后一幅图像是原始图像的IDFFT,未放大
    Re,IM
    结果
  • 第二行是相同的,但DFFT结果被booth
    x,y
    中一半大小的图像包裹,以匹配大多数DIP/CV文本中的常见结果
如您所见,如果您IDFFT返回包装结果,则结果不正确(棋盘格掩码)

您只有一张图像作为DFFT结果

  • 是功率谱吗
  • 或者你们忘了包括虚部?仅仅是为了观察,或者可能也是为了计算
您的1D**DFFT是否正常工作**

  • 对于实际数据,结果应该是对称的
  • 检查我的评论中的链接,并比较一些示例1D数组的结果
  • 首先调试/修复1DFFT,然后再移动到下一级
  • 不要忘记测试真实和复杂的数据
您的IDFFT看起来BW(无灰色)饱和

  • 那么,您是否放大了DFFT结果以查看图像,并将其用于IDFFT而不是原始的DFFT结果
  • 还要检查是否在计算过程中没有舍入到整数
小心(I)DFFT溢出/下溢


如果您的图像像素强度较大,并且图像的分辨率太高,则您的计算可能会丢失精度。更新的人在图像中看到了这一点,但如果您的图像是HDR,则这是可能的。这是由DFFT计算的卷积对于大多项式的常见问题。

建议您阅读本文

Christophe有一个很好的观点,但他错了,因为在现代,使用malloc而不是new()/free()似乎不会初始化内存或选择最佳数据类型,这将导致下面列出的所有问题:-

可能的原因是:

  • 数字的符号在某个地方发生了变化,我在dll上使用平台调用时看到过类似的问题,并且值是通过值而不是引用传递的。这是由内存不一定为空造成的,因此当图像数据输入时,将对其值执行布尔数学。我建议您确保内存为空在将图像数据放在那里之前清空

  • 内存向右旋转(汇编语言中的ROR)或向左旋转(ROL)。如果使用的数据类型不一定匹配,例如输入无符号数据类型的有符号值,或者一个变量中的位数不同,则会发生这种情况

  • 由于无符号值输入有符号变量而导致数据丢失。结果是丢失1位