R 如何使用傅里叶逆变换的输出?

R 如何使用傅里叶逆变换的输出?,r,fft,complex-numbers,inverse-transform,R,Fft,Complex Numbers,Inverse Transform,我试图通过光谱减法来增强超声波信号。信号在时域中,包含噪声。我将信号划分为2µs的汉明窗,并计算了这些帧的傅里叶变换。然后我选择了3个连续的帧,我将其解释为噪声。我平均了这3帧的震级谱,然后从每一帧的震级谱中减去平均值。然后,我将所有负幅度谱定义为零,并通过将新幅度谱与相位谱相结合来重建增强傅里叶变换。这给了我每帧一系列的复数。现在我想用傅里叶逆变换把这个序列转换回时域。然而,这个操作为我提供了我不知道如何使用的复数 我在几篇文章中读到,从傅里叶逆变换中获得复输出是正常的。然而,复数的使用是有区

我试图通过光谱减法来增强超声波信号。信号在时域中,包含噪声。我将信号划分为2µs的汉明窗,并计算了这些帧的傅里叶变换。然后我选择了3个连续的帧,我将其解释为噪声。我平均了这3帧的震级谱,然后从每一帧的震级谱中减去平均值。然后,我将所有负幅度谱定义为零,并通过将新幅度谱与相位谱相结合来重建增强傅里叶变换。这给了我每帧一系列的复数。现在我想用傅里叶逆变换把这个序列转换回时域。然而,这个操作为我提供了我不知道如何使用的复数

我在几篇文章中读到,从傅里叶逆变换中获得复输出是正常的。然而,复数的使用是有区别的。有人说忽略虚部,因为它应该是非常小的e-15,但在我的例子中,它是不可忽略的0.01-0.5。老实说,我现在不知道该怎么处理这些数字,因为我希望傅里叶逆变换只给我实数。希望有很小的虚部,但不幸的是

# General parameters
#
total_samples = length(time_or) # Total numbers of samples in the current series
max_time = max(time_or) # Length of the measurement in microseconds
sampling_freq = 1/(max_time/1000000)*total_samples # Sampling frequency
frame_length_t = 2 # In microseconds (time)
frame_length_s = round(frame_length_t/1000000*sampling_freq) # In samples per frame
overlap = frame_length_s/2 # Overlap in number of frames, set to 50% overlap
#
# Transform the frame to frequency domain
#
fft_frames = specgram(amp, n=frame_length_s, Fs=125, window=hamming(frame_length_s), overlap=overlap)

mag_spec=abs(fft_frames[["S"]])
phase_spec=atan(Im(fft_frames[["S"]])/Re(fft_frames[["S"]]))

#
# Determine the arrival time of noise
#
cutoff= 10 #determine the percentage of the signal that has to be cut off
dnr=us_data[(length(us_data[,1])*(cutoff/100)):length(us_data[,1]), ]
noise_arr=(length(us_data[,1])-length(dnr[,1])+min(which(dnr[,2]>0.01)))*0.008
#
# Select the frames for noise spectrum estimation
#
noise_spec=0
noise_spec=mag_spec[,noise_arr]
noise_spec=noise_spec+mag_spec[, (noise_arr+1)]
noise_spec=noise_spec+mag_spec[, (noise_arr+2)]
noise_spec_check=noise_spec/3
#
# Subtract the estimated noise spectrum from every frame
#
est_mag_spec=mag_spec-noise_spec_check
est_mag_spec[est_mag_spec < 0] = 0
#
# Transform back to frequency spectrum
#
j=complex(real=0, imaginary=1)
enh_spec = est_mag_spec*exp(j*phase_spec)
#
# Transform back to time domain
#
install.packages("pracma")
library("pracma")
enh_time=fft(enh_spec[,2], inverse=TRUE)

我希望有人对如何处理这些复杂的数字有想法。也许我之前在处理方法上犯了一个错误,但我已经检查了很多次,对我来说似乎很可靠。这是这一过程的最后一步,希望在傅里叶逆变换后获得一个好的时域信号。

当使用傅里叶变换变换数据时,一个基本的故障排除帮助是这样一个概念,即您可以进行fft,然后获取数据并进行逆fft,然后获取原始数据。。。我建议你用玩具输入时域数据来做这件事。。。让我们说一个1千赫的音频波,这是你的时域数据。。。将其发送到fft调用,该调用将返回其频域表示的数组。。。不做任何事情,数据发送到一个逆fft ifft。。。返回的数据将是您原来的1 Khz音频波。。。现在就这样做,以获得对其力量的欣赏,并在您的项目中使用此技巧,以确认您在球场上。。。或者,如果你从频域数据开始,你也可以这样做

freq domain data -> ifft -> time domain data -> fft -> same freq domain data

请参阅此处的更多详细信息这是您的问题:

phase_spec=atan(Im(fft_frames[["S"]])/Re(fft_frames[["S"]]))
在这里,您计算半个圆中的一个角度,将另一半映射到第一个圆。也就是说,你正在失去信息

许多语言都有一个函数来获取复数值的相位,例如在MATLAB和Python中

或者,使用这个函数,这个函数存在于我使用过的每一种语言中,除了NumPy,他们决定调用它。它通过将两个分量作为单独的值来计算四象限反正切。也就是说,如果结果在前两个象限中,则atany/x与atan2y、x相同

我想你能行

phase_spec=atan2(Im(fft_frames[["S"]]), Re(fft_frames[["S"]]))

您标记了问题R,但代码看起来更像Python。请仔细检查你的标签。嗨,克里斯,我用的是R-tho。嗨,克里斯。我猜我在那里扔掉了我的相位数据中非常重要的一部分!很好的提示。非常感谢。嘿,斯科特,谢谢你的回答。我在时间域和频率域中来回转换数据,每次都能重建原始信号。我在我的脚本tho中发现了一个错误:使用fft“逆”应该除以lengthx来规范化数据。或者至少我是这样理解的。第二,也是更重要的:在函数specgram中,hamming窗口与重叠相结合,改变了每帧中时间步长的权重,增加了重建原始时间信号的难度。为了解决这个问题,我现在选择在零重叠的矩形窗口上执行specgram。结合逆fft除以每帧的长度,我重建了增强的原始信号。问题解决了。谢谢你的回复。卢多干杯
phase_spec=atan2(Im(fft_frames[["S"]]), Re(fft_frames[["S"]]))