【问题标题】:Implementing FFT low-pass filter in C with FFTW使用 FFTW 在 C 中实现 FFT 低通滤波器
【发布时间】:2014-06-04 06:43:26
【问题描述】:

我正在尝试创建一个非常简单的 C++ 程序,该程序给定 [0-100] 范围内的参数,将低通滤波器应用于灰度图像,该图像应该将其按比例“压缩”到给定参数的值。 我正在使用 FFTW 库。

我对如何定义频率阈值有一些疑问,cut。有没有更有效的方法来定义这样的价值?

//fftw_complex *fft
//double[] magnitude
// . . . 

int percent = 100;
    if (percent < 0 || percent > 100) {
        cerr << "Compression rate must be a value between 0 and 100." << endl;
        return -1;
    }

double cut =(double)(w*h) * ((double)percent / (double)100);
    for (i = 0; i < (w * h); i++) {
        magnitude[i] = sqrt(pow(fft[i][0], 2.0) + pow(fft[i][1], 2.0));
        if (magnitude[i] < cut) {
            fft[i][0] = 0.0;
            fft[i][1] = 0.0;
        }
    }

更新1:

我已将代码更改为此,但我再次不确定这是过滤频率的正确方法。图像肯定是压缩的,但非方形图像被弄乱了,将压缩设置为 100% 并不是真正可用的最大压缩(我可以达到 ~140%)。 Here 你可以找到我现在看到的图像。

int cX = w/2;
int cY = h/2;
cout<<"TEST "<<((double)percent/(double)100)*h<<endl;
for(i = 0; i<(w*h);i++){
    int row = i/s;
    int col = i%s;
    int distance = sqrt((col-cX)*(col-cX)+(row-cY)*(row-cY));
    if(distance<((double)percent/(double)100)*min(cX,cY)){
        fft[i][0] = 0.0;
        fft[i][1] = 0.0;
    }
}

【问题讨论】:

  • abs(sqrt(foo)) - 你希望sqrt 返回负值吗??
  • @MSalters 当您从一些 powerpoint 幻灯片中复制公式时会发生这种情况 :)
  • 注意:pow(x, 2.0) 通常比 xx 慢得多。 pow 允许浮点指数。如果 (fft[i][0]*fft[i][0] + fft[i][1]*fft[i][1] cut) 会更好
  • 这根本不是一个低通滤波器,正如其他人所提到的 - 它所做的只是在能量低于某个阈值的垃圾箱中去除能量。您应该更改问题和标题中的术语以避免进一步混淆。
  • @PaulR 甚至更新的代码?我将此问题作为参考:stackoverflow.com/questions/22740632/…,它似乎与我的代码非常相似..

标签: c++ image-processing fft fftw


【解决方案1】:

这根本不是低通滤波器。低通滤波器通过低频,即它去除精细细节(模糊)。为此,您显然需要 2D FFT。

此代码本质上只是删除了随机位。

[编辑] 新代码看起来更像一个低通滤波器。 141% 的设置是预期的:正方形的对角线是 sqrt(2)=1.41 乘以它的边。将索引转换为行/列对应该使用图像宽度,而不是一些随机无法解释的s

我不知道你的零频率在哪里。这应该很容易发现(最大值),但它可能在 (0,0) 而不是 (w/2,h/2) 中

【讨论】:

  • 我应该如何转换该代码以执行 2D FFT?我的 fft 是这样定义的:fwd = fftw_plan_dft_2d(w, h, data_in, fft,FFTW_FORWARD,FFTW_ESTIMATE); 我以为我在做 2d 变换。
  • @Vektor88:哦,我没有说你没有做 2D FFT,你没有展示它,所以我只是想确保你做了。但是你意识到结果也是二维的?
  • 是的,我意识到这一点,在阅读了一些文档后,我对代码进行了一些更改并更新了我的问题。问题依旧,如何正确设置频率阈值?我也有一些不是正方形的图像的问题。
  • scv::Mat().step的值,对应图片的宽度。
猜你喜欢
  • 2015-05-09
  • 2011-03-06
  • 2015-05-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-04-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多