更新时间:2023-02-26 19:06:19
使用FFT和Afrog进行互相关:
To do Cross-correlation with FFTs and Afrog:
因此,您需要确保将输入大小正确填充到2的幂的长度,并在指定范围内:考虑到至少有一半的波浪是空白"(零)
So you would need to make sure the input size is correctly padded to a length that is a power of 2, and in the specified range: taking into account at least half of the wave is "blank" (zeros)
参考:
https://dsp.stackexchange.com/questions/741/为什么要在进行傅立叶变换之前先将i-zero-pad-a-signal
https://dsp.stackexchange.com/questions/1919/ficiently-calculating-autocorrelation-using-ffts
为什么所得IFFT的最大值:
来自***,互相关可用于确定两个之间的时间延迟信号,例如用于确定在麦克风阵列上传播声信号的时间延迟. 2 [3] [需要澄清]在计算两个信号之间的互相关之后,互相关函数的最大值(如果信号为负相关,则为最小值)指示信号***对齐的时间点,即,两个信号之间的时间延迟为由互相关的最大值或arg max的参数确定,如
from wikipedia, Cross-correlations are useful for determining the time delay between two signals, e.g. for determining time delays for the propagation of acoustic signals across a microphone array.2[3][clarification needed] After calculating the cross-correlation between the two signals, the maximum (or minimum if the signals are negatively correlated) of the cross-correlation function indicates the point in time where the signals are best aligned, i.e. the time delay between the two signals is determined by the argument of the maximum, or arg max of the cross-correlation, as in
参考: https://math.stackexchange.com/questions/1080709/为什么在相似部分获得互相关的最大价值
基于以上几点,交叉计算使用以下代码进行计算:
Based on the above points, the Cross Calculation is calculated using the following code:
//same as OP
public Complex[] CrossCorrelation(Complex[] ffta, Complex[] fftb)
{
var conj = ffta.Select(i => new Complex(i.Re, -i.Im)).ToArray();
conj = conj.Zip(fftb, (v1, v2) => Complex.Multiply(v1, v2)).ToArray();
FourierTransform.FFT(conj, FourierTransform.Direction.Backward);
//get that data and plot in Excel, to show the max peak
Console.WriteLine("---------rr[i]---------");
double[] rr = new double[conj.Length];
rr = conj.Select(i => i.Magnitude).ToArray();
for (int i = 0; i < conj.Length; i++)
Console.WriteLine(rr[i]);
Console.WriteLine("----end-----");
return conj;
}
//tuble.Item1: Cor. Coefficient
//tuble.Item2: Delay of signal (Lag)
public Tuple<double, int> CorrelationCoefficient(Complex[] ffta, Complex[] fftb)
{
Tuple<double, int> tuble;
var correlation = CrossCorrelation(ffta, fftb);
var seq = correlation.Select(i => i.Magnitude);
var maxCoeff = seq.Max();
int maxIndex = seq.ToList().IndexOf(maxCoeff);
Console.WriteLine("max: {0}", maxIndex);
tuble = new Tuple<double, int>(maxCoeff, maxIndex);
return tuble;
}
// Pad signal with zeros up to 2^n and convert to complex
public List<Complex> ToComplexWithPadding(List<double> sample, int padding = 1)
{
//As per AForge documentation:
// The method accepts data array of 2n size only, where n may vary in the [1, 14] range
//So you would need to make sure the input size is correctly padded to a length that is a power of 2, and in the specified range:
double logLength = Math.Ceiling(Math.Log(sample.Count * padding, 2.0));
int paddedLength = (int)Math.Pow(2.0, Math.Min(Math.Max(1.0, logLength), 14.0));
Complex[] complex = new Complex[paddedLength];
var samples = sample.ToArray();
// copy all input samples
int i = 0;
for (; i < sample.Count; i++)
{
complex[i] = new Complex(samples[i], 0);
Console.WriteLine(complex[i].Re);
}
// pad with zeros
for (; i < paddedLength; i++)
{
complex[i] = new Complex(0, 0);
Console.WriteLine(complex[i].Re);
}
return complex.ToList();
}
// extra for signal generation for testing. You can find in the link of the life demo.
您可以使用延迟11生成的两个信号样本运行生活演示结果与信号的实际延迟相符
You can run life demo with sample of two signal generated with delay 11 and the result match the actual delay of the signal
输出结果:
correlation Coef: 0.33867796353274 | Delay: 11| actual delay: 11