逆汉宁窗

信息处理 窗函数 窗户
2022-02-12 13:11:23

我使用以下公式来计算一组点的 Hann 值:

w(n)=0.5(1cos(2πnN))

为了在 java 中实现这一点,我使用以下代码:

private static void applyHannWindow(final double[] points) {
    for (int i = 0; i < points.length; i++) {
        points[i] = 0.5 * (1.0 - Math.cos(2.0 * Math.PI * points[i] / points.length));
    }
}

取反,求解,我可以重新使用因此,我提出的等式是: nw(n)

n=12πarccos(2w(n)+1)

为了在 Java 中实现这一点,我使用了以下代码:

private static void reverseHannWindow(final double[] points) {
    for (int i = 0; i < points.length; i++) {
        points[i] = points.length * (Math.acos(-2.0 * points[i] + 1.0) / (2.0 * Math.PI));
    }
}

我编写了一个简单的测试,以确保在应用 Hann 窗口并将其反转后,我得到相同的结果。不过,我好像没有。

给定原始数组:

final double[] data = new double[5];
data[0] = 200;
data[1] = 210;
data[2] = 215;
data[3] = 207;
data[4] = 203;

我得到以下输出:

### applying Hann window
0.0
0.0
0.0
0.9045084971874686
0.9045084971874787
### Reversing Hann window
0.0
0.0
0.0
1.9999999999999862
2.0000000000000138

不确定我在将逆应用到 Hann 窗口时做错了什么?

1个回答

我认为您在这里误解了“”一词。

给定一个窗口序列w[n]长度L有一个支持区域,使得w[n]0,  为了0nL1, 和一个信号x[n]你得到窗口信号v[n]=w[n]x[n],作为信号的每个样本x[n]乘以窗口的对应样本w[n].

反相v[n]意味着,给定窗口序列v[n]您获得的原始(未加权)段x[n]位于窗口的支持范围区域内w[n]这是由:

x[n]=v[n]w[n]  ,  w[n]0

恢复原始信号段的操作如下: 设原始信号为Matlab向量:

x = [1 2 3 0 5];   % original signal segment with 5 samples (L=5)

让窗口为 5 个样本的汉明型长度:

w = hamming(5)';   % 5 sample Hamming window w = [0.08 0.54 1.0 0.54 0.08]

因此加窗信号为:

v = x.*w;          % v = [0.08 1.08 3.0 0.0 0.4] (windowed signal)

现在要从 v[n] 中恢复 x[n],请执行以下操作:

xrec = v./w;      % xrec = [1.0 2.0 3.0 0.0 5.0]; recovered

操作xrec[n]=v[n]/w[n]是按样本实施的,这样xrec[0]=v[0]/w[0]或者xrec[1]=v[1]/w[1]或一般来说

xrec[n]=v[n]/w[n]

然而,现在 Hann 窗口具有其初始和最终样本为零的属性(实际上将窗口长度减少了 2),因此需要重叠实现才能恢复x[n]多个回来 v[n]段,如下:

设原始信号为 Matlab 向量:

x = [1 2 3 4 5 4 3 2 1];   % original signal segment with 9 samples (L=9)

让我们使用长度为 5 的 Hann 窗:

w = hann(5)';   % 5 sample Hann window w = [0.0 0.5 1.0 0.5 0.0]

首先在 x[n] 的第一个和最后一个样本中嵌入一个零:

xe = [0 x 0];   % xe = [0 1 2 3 4 5 4 3 2 1 0] (xe has 11 samples)

现在将窗口应用到重叠段中,如下所示:

v1 = x[1:5].*w;          % v1 = [0.0 0.5 2.0 1.5 0.0] (first segment)
v2 = x[4:8].*w;          % v2 = [0.0 2.0 5.0 2.0 0.0] (second segment)
v3 = x[7:11].*w;         % v3 = [0.0 1.5 2.0 0.5 0.0] (third segment)

(注意 MATLAB 索引操作 x[i:j] 选择输入向量的部分)

现在要恢复x[n]vk[n]执行以下操作:首先请注意,每个段都以零样本开始和结束,您应该丢弃这些样本,并且您应该只考虑剩余的L2审查那些。

然后还要考虑重叠量,这样您就不会重新计算先前计算的输入样本,然后:

x1_rec = v1[2:4]./w[2:4];      % x1_rec = [1.0 2.0 3.0]; recovered first 3 samples of x[n]

x2_rec = v2[2:4]./w[2:4];      % x2_rec = [4.0 5.0 4.0]; recovered middle 3 samples of x[n]

x3_rec = v3[2:4]./w[2:4];      % x3_rec = [3.0 2.0 1.0]; recovered last 3 samples of x[n]