2012-07-14 13 views

Respuesta

11

Necesitaba extraer una señal de datos de consumo de CPU muy ruidosos. Aquí está el filtro mediano de Jeff McClintock ...

Inicialice el promedio y la mediana a cero, luego, para cada muestra 'en pulgadas', la mediana hacia la muestra de entrada en un pequeño incremento. Eventualmente se establecerá en un punto donde aproximadamente el 50% de las muestras de entrada son mayores y el 50% son menores que la mediana. El tamaño del incremento debe ser proporcional a la mediana real. Como no conocemos la mediana real, utilizo el promedio como una estimación aproximada. El tamaño del paso se calcula como 0.01 veces el estimado. Los tamaños de pasos más pequeños son más precisos, pero tardan más en resolverse.

float median = 0.0f; 
float average = 0.0f; 

// for each sample 
{ 
    average += (abs(sample) - average) * 0.1f; // rough running average magnitude. 
    median += _copysign(average * 0.01, sample - median); 
} 

enter image description here

+0

Si bien esta solución es muy eficiente, cuidado con las siguientes salvedades: 1) tasa de convergencia depende de amplitud de la señal (comparar las respuestas pasos con diferentes desplazamientos y amplitudes), por lo tanto no converge contra señal cerca de cero! 2) para señal de entrada casi constante esta estimación introduce jitter con amplitud de 'promedio * 0.01' y frecuencia de frecuencia de muestreo 3) se desvía en impulsos cortos (que una mediana originalmente no tiene, siendo popular como filtro de pimienta y ruido) – orzechow

+0

Sí, una mejora para eliminar el jitter es limitar el tamaño del paso (promedio * 0.01) a no más grande que la señal de error (muestra - mediana), es decir: std :: max (promedio * 0.01, fabs (muestra - mediana)). –

Cuestiones relacionadas