Pregunta

Necesito encontrar la frecuencia de una muestra, almacenada (en vb) como una matriz de bytes.La muestra es una onda sinusoidal, de frecuencia conocida, así que puedo comprobarlo), pero los números son un poco impares y mis matemáticas son débiles.Gama completa de valores 0-255.El 99% de los números están en el rango de 235 a 245, pero hay algunos valores atípicos hasta 0 y 1, y hasta 255 en el 1% restante.¿Cómo normalizo esto para eliminar valores atípicos (calculando el intervalo 235-245, ya que puede cambiar con diferentes muestras) y cómo luego calculo los cruces por cero para obtener la frecuencia?¡Disculpas si esta descripción es basura!

¿Fue útil?

Solución

La FFT es probablemente la mejor respuesta, pero si realmente quieres hacerlo con tu método, prueba esto:

Para normalizar, primero haga un histograma para contar cuántas apariciones de cada valor del 0 al 255.Luego desecha el X por ciento de los valores de cada extremo con algo como:

for (i=lower=0;i< N*(X/100); lower++)
  i+=count[lower];
//repeat in other direction for upper

Ahora normaliza con

A[i] = 255*(A[i]-lower)/(upper-lower)-128

Deseche los resultados fuera del rango -128..127.

Ahora puedes contar los cruces por cero.Para asegurarse de que el ruido no lo engañe, es posible que desee realizar un seguimiento de la pendiente en los últimos puntos y contar solo los cruces cuando la pendiente promedio vaya en la dirección correcta.

Otros consejos

El método estándar para atacar este problema es considerar un bloque de datos, con suerte al menos el doble de la frecuencia real (tomar más datos no está mal, por lo que es bueno sobreestimar un poco), luego tomar el FFT y suponga que la frecuencia corresponde al número más grande en el espectro FFT resultante.

Por cierto, aquí se han planteado problemas muy similares antes; también puedes buscar esas respuestas.

Utilice la transformada de Fourier, es mucho más insensible al ruido que contar los cruces por cero

Editar:@WaveyDavey

Encontré una biblioteca de F# para hacer una FFT: De aquí

Resulta que la mejor implementación gratuita que he encontrado para los usuarios de F# hasta ahora sigue siendo la fantástica biblioteca FFTW.Su sitio tiene una DLL de Windows precompilada.He escrito vinculaciones mínimas que permiten el acceso a FFTW de FFTW desde F#, con Guru e interfaces simples.El rendimiento es excelente, Windows XP Pro de 32 bits es solo hasta un 35% más lento que los 64 bits Linux.

Ahora estoy seguro de que puedes llamar a F# lib desde VB.net, C#, etc., eso debería estar en sus documentos.

Si entendí bien por tu descripción, lo que tienes es una señal que es una combinación de un seno más una constante más algunos fallos aleatorios.decir, como

x[n] = A*sin(f*n + phi) + B + N[n]

donde N[n] es el ruido de "fallo" del que desea deshacerse.

Si los fallos tienen una longitud de una muestra, puede eliminarlos utilizando un filtro mediano que debe ser mayor que la longitud del fallo.A ambos lados del problema.Los fallos de longitud 1 significan que tendrá suficiente con una mediana de 3 muestras de longitud.

y[n] = median3(x[n])

La mediana se calcula así:Tome las muestras de x que desea filtrar (x[n-1],x[n],x[n+1]), ordénelas y su salida será la del medio.

Ahora que la señal de ruido desapareció, deshazte de la señal constante.Entiendo que el búfer tiene una longitud limitada y conocida, por lo que puede calcular la media de todo el búfer.Réstalo.

Ahora tienes tu señal sinusal única.Ahora puede calcular la frecuencia fundamental contando los cruces por cero.Cuente la cantidad de muestras por encima de 0 en las que la muestra anterior estaba por debajo de 0.El período es la cantidad total de muestras de su buffer dividida por esto, y la frecuencia es el opuesto (1/x) del período.

Aunque iría con la mayoría y diría que parece que lo que quieres es una solución fft (el algoritmo fft es bastante rápido), si fft no es la respuesta por cualquier motivo, puedes intentar ajustar una curva sinusoidal a los datos usando un programa de adaptación y leyendo la frecuencia ajustada.

Usando Fityk, puede cargar los datos y ajustarlos a a*sin(b*x-c) dónde 2*pi/b Le dará la frecuencia después de la instalación.

Fityk se puede utilizar desde una interfaz gráfica de usuario, desde una línea de comandos para secuencias de comandos y tiene una API de C++, por lo que podría incluirse directamente en sus programas.

Busqué en Google "fft básico". FFT de Visual Básico Su pregunta grita FFT, pero tenga cuidado, usar FFT sin comprender ni un poquito sobre DSP puede generar resultados que no comprende o no sabe de dónde vienen.

obtenga el analizador de frecuencia en http://www.relisoft.com/Freeware/index.htm y ejecútelo y mire el código.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top