¿Cuál es la mejor manera de obtener la fase entre señales ruidosas?

1

Tengo unas pocas señales sinusoidales en aproximadamente la misma frecuencia. Me gustaría saber la diferencia de fase entre las tres señales. ¿Cuál es la mejor manera de hacer esto? También sería útil adjuntar una incertidumbre a estas mediciones de fase. He adjuntado una imagen de las señales

    
pregunta cpc333

4 respuestas

2

La respuesta obvia sería tomar la FFT de cada señal. El ángulo de fase del recipiente más alto (magnitud) le da la fase de la onda sinusoidal fundamental enterrada en cada señal. Compara y contrasta según sea necesario.

Use una función de ventana apropiada para minimizar los efectos de borde.

    
respondido por el Dave Tweed
1

Recomiendo técnicas de estimación de la función de transferencia, como el Periodograma de Welch, que se usa junto con las estimaciones de coherencia, que se pueden usar para establecer intervalos de confianza alrededor de su estimación. Recomiendo Bendat y Piersol, Datos aleatorios: Procedimientos de análisis y medición para un tratamiento muy completo.

El periodograma de Welch implica tomar el espectro de segmentos de datos superpuestos para producir el periodograma.

La coherencia indica en gran medida el ruido y las no linealidades inherentes a la relación entre entrada y salida. Una coherencia de 1.0 refleja un sistema perfectamente lineal sin ruido. Tanto el ruido como la no linealidad reducen la coherencia.

También puede trazar una señal contra la otra, y calcular la fase de la figura de Lissajou resultante

Otra opción sería examinar los picos en la correlación cruzada entre las dos señales.

    
respondido por el Scott Seidman
0

¿Eso parece ser un gráfico matplotlib correcto? Esto implicaría que está usando python para el proceso posterior. Igualmente desea postprocesar los datos ya recopilados.

Lo que sugeriría es aplicar un filtro de promedio móvil a cada señal. Si bien un filtro de este tipo "cambiará de fase" una forma de onda individual con respecto al original, en relación con la otra (posterior al filtro) no habrá diferencia, ya que se habrá aplicado el mismo "cambio"

Un simple

1 / 4x + 1/4 (x-1) + 1/4 (x-2) + 1/4 (x-3) debe hacer o un simple numpy.mean con una ventana de división de corrección y un índice variable.

De cualquier manera, una vez que haya filtrado ligeramente los datos para minimizar el jitter de cruce cero, puede utilizar un par de funciones numpy:

zero_crossings = numpy.where(numpy.diff(numpy.sign(DATA)))[0]

Esto devolverá una matriz de todos los cruces por cero. Es posible que deba aumentar el filtrado si hay varios muy juntos.

Si tiene matlab, se puede lograr un esquema similar con el comando de filtro & hay un archivo crossing.m disponible públicamente desde mathworks exchange.

NOTA, esto no hará una distinción para cruces positivos o negativos.

--EDIT--

Toma este pedazo de código python:

#!/usr/bin/env python3

import numpy as np
from pylab import * 
import matplotlib
matplotlib.pyplot.switch_backend('QT4Agg')

def filt(data, l=4):
    tmp = np.zeros(len(data))
    for i in range(l,len(data)):
        tmp[i] = np.mean(data[i-l:i])
    return tmp


t = np.arange(0,10*np.pi,0.1e-3)
s = np.sin(t) + np.random.normal(0,0.01,len(t))

crossings = np.where(np.diff(np.sign(s)))[0]
print(len(crossings))
s2 = filt(s,l=4)
crossings = np.where(np.diff(np.sign(s2)))[0]
print(len(crossings))
s3 = filt(s,l=10)
crossings = np.where(np.diff(np.sign(s3)))[0]
print(len(crossings))
s4 = filt(s,l=150)
crossings = np.where(np.diff(np.sign(s4)))[0]
print(len(crossings))




filt(s)
plot(t,s)
grid(True)
hold(True)
plot(t,s2)
plot(t,s3)
plot(t,s4,linewidth='2')
show()

Esto genera una onda de sen de punto de datos de 300,000 y acopla a ella una fuente de ruido normalmente distribuida con un sd de 0.01

Comosepuedeverunagrancantidadderuidodecrucecero,unacantidadmolesta.

El resto de la secuencia de comandos tiene un promedio móvil muy burdo (una mejor implementación sería la de mover el filtro de cobertura y esto es fácil en una secuencia de comandos de matlab a través del comando "filtro". ( enlace )

Cada iteración utiliza un tamaño de ventana diferente & Imprime igualmente el número total de cruces por cero detectados.

[jrb@FluidMotion:~/tmp] 27s 1 $ ./test.py 
1126
272
120
12

El número de cruces por cero detectados ha disminuido de 1126 a 12.

Como se mencionó, hay un cambio de fase absoluto (se reduciría significativamente si se usara un filtro mejor, pero este fue un ejemplo de 5 minutos), pero para comparar diferencias relativas es válido ya que todos los conjuntos de datos se desplazan en la misma cantidad.

Una vez que conoce los índices de los cruces por cero y conoce el paso de tiempo de una muestra, puede calcular la diferencia de tiempo entre los cruces por cero. Combine eso con el número de muestras entre tres cruces por cero de los mismos datos y amp; Usted sabe el número de muestras por 360 grados

Esto tomó 150 muestras de las 300,000 (para producir una detección de cruce por cero razonable pero la fuente tenía muchos cruces por cero aleatorios. Los datos OP parecen tener solo un par de eventos de cruce por cero.

    
respondido por el JonRB
0

Podrías filtrar agresivamente las señales, ya que parece que conoces la frecuencia aproximada en la que estás interesado. Paso bajo para eliminar el ruido, y paso alto porque los picos diferentes de una sola señal se encuentran en niveles desmedidos diferentes amplitudes. Luego compara los tiempos de los cruces por cero.

    
respondido por el Rennex

Lea otras preguntas en las etiquetas