vb.net - resueltos - suma de filas y columnas de una matriz en visual basic
Análisis matemático de una muestra de sonido(como una matriz de números) (7)
Necesito encontrar la frecuencia de una muestra, almacenada (en vb) como una matriz de bytes. La muestra es una onda sinusoidal, frecuencia conocida, así que puedo verificar), pero los números son un poco extraños, y mi matemática-foo es débil. Rango completo 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 puedo calcular cero cruces para obtener la frecuencia? Disculpas si esta descripción es basura!
Aunque me gustaría ir con la mayoría y decir 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 la razón que sea, puede intentar ajustar una curva sinusoidal a los datos utilizando un programa de adaptación y lectura de la frecuencia ajustada.
Usando Fityk , puede cargar los datos y ajustarlos a a*sin(b*xc)
donde 2*pi/b
le dará la frecuencia después del ajuste.
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 para "fft básico". Visual Basic FFT Su pregunta esgrime FFT, pero tenga cuidado al usar FFT sin entender siquiera un poco acerca de que DSP puede generar resultados que usted no entiende o no sabe de dónde vienen.
El método estándar para atacar este problema es considerar un bloque de datos, con suerte al menos dos veces la frecuencia real (tomar más datos no es malo, así que es bueno sobreestimar un poco), luego tomar la FFT y adivinar que la frecuencia corresponde al mayor número en el espectro de FFT resultante.
Por cierto, aquí se han planteado problemas muy similares; también podría buscar esas respuestas.
La FFT es probablemente la mejor respuesta, pero si realmente quieres hacerlo por tu método, prueba esto:
Para normalizar, primero haga un histograma para contar cuántas ocurrencias de cada valor va de 0 a 255. Luego arroje 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
Bote los resultados fuera del rango -128..127.
Ahora puedes contar cruces cero. Para asegurarse de que no se deje engañar por el ruido, es posible que desee realizar un seguimiento de la pendiente en los últimos puntos, y solo contar los cruces cuando la pendiente promedio va por el camino correcto.
Si entendí bien de tu descripción, lo que tienes es una señal que es una combinación de un seno más una constante más algunas fallas técnicas al azar. Digamos, como
x[n] = A*sin(f*n + phi) + B + N[n]
donde N [n] es el ruido "fallo" del que desea deshacerse.
Si los problemas técnicos son de una muestra de longitud, puede eliminarlos utilizando un filtro mediano que debe ser más grande que la longitud de falla. En ambos lados del problema. Glitches de longitud 1 significa que tendrá suficiente con una mediana de 3 muestras de longitud.
y[n] = median3(x[n])
La mediana se calcula de manera que: 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 está ausente, deshazte de la señal constante. Entiendo que el buffer es de una longitud limitada y conocida, por lo que puede calcular la media de todo el buffer. Substraerlo.
Ahora tienes tu única señal sinusal. Ahora puede calcular la frecuencia fundamental contando los cruces por cero. Cuente la cantidad de muestras por encima de 0 en que la muestra anterior estaba por debajo de 0. El período es la cantidad total de muestras de su memoria intermedia dividida por esta, y la frecuencia es la opuesta (1 / x) del período.
Usa la transformada de Fourier, es mucho más insensible al ruido que contar cruces por cero
Editar: @WaveyDavey
Encontré una biblioteca F # para hacer una FFT: desde aquí
Resulta que la mejor implementación gratuita que he encontrado para los usuarios de F # hasta el momento sigue siendo la fantástica biblioteca de FFTW. Su sitio tiene una DLL de Windows precompilada. He escrito enlaces mínimos que permiten el acceso seguro a subprocesos a FFTW desde F #, tanto con guru como con interfaces simples. El rendimiento es excelente, Windows XP Pro de 32 bits es solo hasta un 35% más lento que Linux de 64 bits.
Ahora estoy seguro de que puedes llamar a F # lib desde VB.net, C #, etc., que debería estar en sus documentos
obtenga el Frequency Analyzer en http://www.relisoft.com/Freeware/index.htm y ejecútelo y observe el código.