OpenCV DFT_INVERSE 与 Matlab 的 ifft 不同
Posted
技术标签:
【中文标题】OpenCV DFT_INVERSE 与 Matlab 的 ifft 不同【英文标题】:OpenCV DFT_INVERSE different from Matlab's ifft 【发布时间】:2014-01-07 20:22:12 【问题描述】:我尝试使用 opencv 的 dft 函数过滤信号。我尝试这样做的方法是在时域中获取信号:
x = [0.0201920000000000 -0.0514940000000000 0.0222140000000000 0.0142460000000000 -0.00313500000000000 0.00270600000000000 0.0111770000000000 0.0233470000000000 -0.00162700000000000 -0.0306280000000000 0.0239410000000000 -0.0225840000000000 0.0281410000000000 0.0265510000000000 -0.0272180000000000 0.0223850000000000 -0.0366850000000000 0.000515000000000000 0.0213440000000000 -0.0107180000000000 -0.0222150000000000 -0.0888300000000000 -0.178814000000000 -0.0279280000000000 -0.144982000000000 -0.199606000000000 -0.225617000000000 -0.188347000000000 0.00196200000000000 0.0830530000000000 0.0716730000000000 0.0723950000000000]
使用以下方法将其转换为 FOURIER 域:
cv::dft(x, x_fft, cv::DFT_COMPLEX_OUTPUT, 0);
消除不需要的频率:
for(int k=0; k<32;k++)
if(k==0 || k>6 )
x_fft.ptr<float>(0)[2*k+0]=0;
x_fft.ptr<float>(0)[2*k+1]=0;
将其转换回时域:
cv::dft(x_fft, x_filt, cv::DFT_INVERSE, 0);
为了检查我的结果,我将它们与 Matlab 进行了比较。我采用相同的信号 x,使用x_mfft = fft(x);
将其转换为傅里叶结果与我从 opencv 得到的结果相似,除了在 opencv 中我只得到左侧,而在 matlab 中我也得到对称值。
在此之后,我在 Matlab 中将 x_mfft(0) and x_mfft(8:32)
的值设置为 0,现在信号看起来完全一样,除了在 Matlab 中它们是复数形式,而在 opencv 中它们是分开的,实部在一个通道中,虚部在一个通道中另一个。
问题是当我在 matlab 中使用x_mfilt = ifft(x_mfft)
执行逆变换时,结果与我使用 opencv 得到的结果完全不同。
Matlab:
0.0126024108604191 + 0.0100628178150509i 0.00278762121814893 - 0.00615997579216921i 0.0116716145588075 - 0.0150834711251450i 0.0204808089882897 - 0.00937680194210788i 0.0187164132302469 - 0.000843687942567208i 0.0132322795522116 - 0.000108642129381095i 0.0140282455278201 - 0.00325620843335947i 0.0190436542174946 - 0.000556561558544529i 0.0182379867325824 + 0.00764390022568001i 0.00964801276734883 + 0.0107158342431018i 0.00405220362962359 + 0.00339496875258604i 0.0108096973356501 - 0.00476499376334313i 0.0236507440224628 - 0.000415067678294738i 0.0266197220512826 + 0.0154626911663024i 0.0142805873081583 + 0.0267004219364679i 0.000314527358302778 + 0.0215255889620223i 0.00173512964620177 + 0.00865151513638104i 0.0169666351363477 + 0.00836162056544561i 0.0255915540012784 + 0.0277878383595920i 0.0118710562486680 + 0.0506446948330055i -0.0160165379892836 + 0.0553846122152651i -0.0354343989166415 + 0.0406080858067314i -0.0370261047451452 + 0.0261077990289579i -0.0365120038155127 + 0.0268311542287801i -0.0541841640123775 + 0.0312446266697320i -0.0854132555297956 + 0.0125342802025550i -0.0989182320365535 - 0.0377079727602073i -0.0686133217915410 - 0.0925138855355046i -0.00474198249025186 - 0.111728716441247i 0.0515933837210975 - 0.0814138940625859i 0.0663201317560107 - 0.0279433757588921i 0.0426055814586485 + 0.00821080477569232i
cv::dft(x_fft, x_filt, cv::DFT_INVERSE, 0) 之后的OpenCV;
频道 1:
0.322008 -0.197121 -0.482671 -0.300055 -0.026996 -0.003475 -0.104199 -0.017810 0.244606 0.342909 0.108642 -0.152477 -0.013281 0.494806 0.854412 0.688818 0.276848 0.267571 0.889207 1.620622 1.772298 1.299452 0.835450 0.858602 0.999833 0.401098 -1.206658 -2.960446 -3.575316 -2.605239 -0.894184 0.262747
频道 2:
0.403275 0.089205 0.373494 0.655387 0.598925 0.423432 0.448903 0.609397 0.583616 0.308737 0.129670 0.345907 0.756820 0.851827 0.456976 0.010063 0.055522 0.542928 0.818924 0.379870 -0.512527 -1.133893 -1.184826 -1.168379 -1.733893 -2.733226 -3.165383 -2.195622 -0.151738 1.650990 2.122242 1.363375
我错过了什么?结果不应该相似吗?如何检查opencv中的逆变换是否正确完成?
稍后编辑: 经过几个小时的努力,我决定绘制 Matlab 和 OpenCV 的结果,令我惊讶的是,它们非常相似。
虚部
真实零件:
很明显,这与 SCALE 因素有关。在将它们逐个元素划分之后,这个因子显然是 32 - 信号的长度。有人可以解释为什么会这样吗?
显而易见的解决方案是使用cv::dft(x_fft, x_filt, cv::DFT_INVERSE+cv::DFT_SCALE, 0);
,所以我想这个话题已经得到解答,但我仍然对为什么会这样感兴趣。
【问题讨论】:
尝试通过将 FFT 箱归零来“消除”频率会给结果增加很多噪音。对于真实结果,IFFT 的输入需要是共轭对称的,这意味着高 bin 必须镜像低 bin 的虚部,而不是归零。 为什么在cv::dft(x, x_fft, cv::DFT_COMPLEX_OUTPUT, 0);
中使用DFT_COMPLEX_OUTPUT
。我也有这个问题。如果您设置 DFT_COMPLEX_OUTPUT 标志,那么您将获得 2N 长度的向量,以及如何对这个向量进行过滤。没有 DFT_COMPLEX_OUTPUT 标志,那么我们得到 N 长度向量,过滤有什么区别。
对谁来说:同样的问题发生在 ios 加速框架和 openCV 上,并且规模差异为 2。结果的组织也不相同 - 据我所知(在 openCV 中找不到文档)第一个元素是 0 频率的真实部分,然后是真实的 img 真实的 img .. 在加速框架中它是真实的 img 真实的 img 一路.. 编辑:好的 openCV 中的文档说它是真实的(0)真实的(1 ) img(1) 真实(2) img(2).. docs.opencv.org/modules/core/doc/operations_on_arrays.html#dft
好的,找到了其他文档。developer.apple.com/library/ios/documentation/Performance/… 文档中的所有内容显然都在文档中(除了缩放因子)
【参考方案1】:
没有所有 FFT 库使用的比例因子标准。有些不使用,有些包括 1/N 的比例因子,有些是 1/sqrt(N)。您必须测试或查看每个特定库的文档。
【讨论】:
以上是关于OpenCV DFT_INVERSE 与 Matlab 的 ifft 不同的主要内容,如果未能解决你的问题,请参考以下文章