análisis de espectro FFT vernácula de todo el proceso (el ángulo utilizada en la ingeniería) bis: datos FFT y tomar un medio, módulo

análisis de espectro FFT vernácula de todo el proceso (el ángulo utilizada en la ingeniería) bis: datos FFT y tomar un medio, módulo

revisión

Hemos hablado de una función de ventana, que ahora se ve como una señal tiene una función periódica, seleccionando adecuadamente la función de ventana, que no sólo aseguran el éxito de exactitud de los datos y reduce la fuga espectral!
Aquí Insertar imagen Descripción
Ahora, para ir a través de una señal de FFT, y los datos extraídos de módulo medio él!

empezar

El primer punto de la nota

Introduce el número de puntos FFT debe ser una potencia entera de dos.
Que es como 1024,2048,4096 este punto.
Sin embargo, si tomamos muestras de puntos sobre cómo hacerlo potencia entera de 2 no es así? Llegar a cero!
Por ejemplo:
Tenemos un montón de señal tiene 4000 puntos, entonces se podría llenar 96 ceros detrás de otra FFT.
Aquí entramos en un programa:

uint32_t WaveMeasureUtils::findNextPow2(uint32_t v)
{
        v--;
        v |= v >> 1;
        v |= v >> 2;
        v |= v >> 4;
        v |= v >> 8;
        v |= v >> 16;
        v++;
        return v;
}

Utilice este programa para buscar la siguiente potencia del programa, el número de puntos de datos de entrada, que puede ayudar a encontrar la FFT puntos tienen que ser, también vamos a ser capaces de obtener el número de relleno de ceros.

Después de que el relleno de ceros, podemos tener diversión a través de FFT él! Buen trabajo en otra sección del programa de APC, le dan una referencia (para usar Qt a escribir, ya que puede necesitar ser reescrito el caso):
.h:

#ifndef FFT_H
#define FFT_H

#include <QObject>
#include <QDebug>
/*
*
*
*               计算傅里叶变换频谱
*
*
* */
#define      MAX_MATRIX_SIZE                4194304             // 2048 * 2048
#define      PI                             3.141592653
#define      MAX_VECTOR_LENGTH              10000


typedef struct Complex
{
    double rl;              //实部
    double im;              //虚部
}Complex;

class fft : public QObject
{
    Q_OBJECT
public:
    explicit fft(QObject *parent = nullptr);
    //傅里叶转换 频域
    bool fft1(QVector<Complex>inVec, const int len, QVector<Complex> &outVec);
   int get_computation_layers(int  num);

   bool is_power_of_two(int  num);

   void test();

signals:

public slots:
};

#endif // FFT_H

CPP:

#include "fft.h"
#include <QDebug>
fft::fft(QObject *parent) : QObject(parent)
{

}

bool fft::fft1(QVector<Complex> inVec, const int len, QVector<Complex> &outVec)
{
    if ((len <= 0) || (inVec.isEmpty()) || ( outVec.isEmpty()))
        return false;
    if (!is_power_of_two(len))
        return false;

    Complex         *pVec = new Complex[len];
    Complex         *Weights = new Complex[len];
    Complex         *X = new Complex[len];
    int                   *pnInvBits = new int[len];

    //memcpy(pVec, inVec, len*sizeof(Complex));

    for(int i = 0; i < len;i++)
    {
        pVec[i].im = inVec.at(i).im;
        pVec[i].rl = inVec.at(i).rl;
    }


    // 计算权重序列
    double fixed_factor = (-2 * PI) / len;
    for (int i = 0; i < len / 2; i++) {
        double angle = i * fixed_factor;
        Weights[i].rl = cos(angle);
        Weights[i].im = sin(angle);
    }
    for (int i = len / 2; i < len; i++) {
        Weights[i].rl = -(Weights[i - len / 2].rl);
        Weights[i].im = -(Weights[i - len / 2].im);
    }

    int r = get_computation_layers(len);

    // 计算倒序位码
    int index = 0;
    for (int i = 0; i < len; i++) {
        index = 0;
        for (int m = r - 1; m >= 0; m--) {
            index += (1 && (i & (1 << m))) << (r - m - 1);
        }
        pnInvBits[i] = index;
        X[i].rl = pVec[pnInvBits[i]].rl;
        X[i].im = pVec[pnInvBits[i]].im;
    }

    // 计算快速傅里叶变换
    for (int L = 1; L <= r; L++) {
        int distance = 1 << (L - 1);
        int W = 1 << (r - L);

        int B = len >> L;
        int N = len / B;

        for (int b = 0; b < B; b++) {
            int mid = b*N;
            for (int n = 0; n < N / 2; n++) {
                int index = n + mid;
                int dist = index + distance;
                pVec[index].rl = X[index].rl + (Weights[n*W].rl * X[dist].rl - Weights[n*W].im * X[dist].im);                      // Fe + W*Fo
                pVec[index].im = X[index].im + Weights[n*W].im * X[dist].rl + Weights[n*W].rl * X[dist].im;
            }
            for (int n = N / 2; n < N; n++) {
                int index = n + mid;
                pVec[index].rl = X[index - distance].rl + Weights[n*W].rl * X[index].rl - Weights[n*W].im * X[index].im;        // Fe - W*Fo
                pVec[index].im = X[index - distance].im + Weights[n*W].im * X[index].rl + Weights[n*W].rl * X[index].im;
            }
        }



        for(int i = 0; i< len;i++)
        {
            X[i].im = pVec[i].im;
            X[i].rl = pVec[i].rl;
        }
    }


    for(int i = 0; i < len;i++)
    {
        outVec[i].im = pVec[i].im;
        outVec[i].rl = pVec[i].rl;
    }



    if (Weights)      delete[] Weights;
    if (X)                 delete[] X;
    if (pnInvBits)    delete[] pnInvBits;
    if (pVec)           delete[] pVec;
    return true;
}
int fft::get_computation_layers(int num)
{

    int nLayers = 0;
    int len = num;
    if (len == 2)
        return 1;
    while (true) {
        len = len / 2;
        nLayers++;
        if (len == 2)
            return nLayers + 1;
        if (len < 1)
            return -1;
    }

}

bool fft::is_power_of_two(int num)
{

    int temp = num;
    int mod = 0;
    int result = 0;

    if (num < 2)
        return false;
    if (num == 2)
        return true;

    while (temp > 1)
    {
        result = temp / 2;
        mod = temp % 2;
        if (mod)
            return false;
        if (2 == result)
            return true;
        temp = result;
    }
    return false;

}

El segundo punto de nota

salida de datos FFT es tomar un medio!
Después de la FFT, nos dieron el mismo múltiplo del número de puntos de datos.
Pero! Sólo podemos tomar la mitad de ellos. Según teorema de muestreo, la frecuencia de muestreo es de 0,5 puntos más alta que la velocidad de datos a través de la FFT normal no puede ser resuelto.
puntos de datos FFT de 0 a-uno correspondencia con un 0 a la última frecuencia de muestreo, resolución de frecuencia: la frecuencia de muestreo / FFT señala
ejemplo: Si la tasa de muestreo es de 20 kHz, el número de puntos es 4096, entonces 2047 cuando el punto es el punto que corresponde a la frecuencia de 10 kHz, y luego más valor de punto no está disponible.
De hecho, si tiene que extraer el punto de datos es el centro de simetría:
Aquí Insertar imagen Descripción

El tercer punto Nota

La salida de la FFT es complejo real de
entrada del punto de FFT es real (incluso si la entrada necesaria para llenar la parte imaginaria, que la parte imaginaria es cero)
y la salida de la FFT es real complejo (real e imaginaria son útiles)
nos requisitos de varios amplitud de la señal cuando es necesario para ellos modulo operación (teorema de Pitágoras).

for(auto i = 0;i<out_.size()/2;i++)
        {
            x1<<i;
            //进行取模
            y1<<sqrt(out_[i].rl * out_[i].rl+out_[i].im * out_[i].im);
        }

Aquí, FFT, y recuperación de datos media, módulo es más, este artículo Fuente: https: //www.jianshu.com/p/b2f64234cc3b, en esta declaración.
A continuación hablamos multiplicar y dividir diferente coeficiente de coeficiente de restitución.
Bienvenido a la preocupación, el punto como oh, eres mi apoyo y acelerar la actualización se escribe un mejor poder de artículo!

Publicado 39 artículos originales · ganado elogios 113 · Vistas de 100.000 +

Supongo que te gusta

Origin blog.csdn.net/whstudio123/article/details/105155645
Recomendado
Clasificación