una - Picos electicos del filtro Matlab en datos acelerométricos
quitar ruido de una señal matlab (4)
He utilizado el archivo despiking
del intercambio de archivos centrales de matlab con muy buen efecto para problemas similares, aunque veo que lo has intentado también.
Otro enfoque que he tomado es tratar los picos como valores atípicos estadísticos y eliminarlos usando esta función que usa la prueba de muchos valores atípicos de Rosner . (El sitio NIST está inactivo por razones obvias, así que aquí está la versión en caché de Google )
Editado para agregar: estaba equivocado. Mi algoritmo de descifrado no proviene de la función de intercambio de archivos a la que he vinculado anteriormente. En realidad, fue sacado de un artículo de revista (el código aparece en la información complementaria del documento, pero no publicaron el código en el intercambio de archivos). El papel fue:
Métodos prácticos para la eliminación de ruido: aplicaciones a picos, ruido cuasi-periódico no estacionario y deriva de línea de base
Delphine Feuerstein, Kim H. Parker y Martyn G. Boutelle
Anal. Chem., 2009, 81 (12), pp 4987-4994
Como los derechos de autor pertenecen a la American Chemical Society y a los autores, no puedo copiar el código aquí, pero si tiene acceso a una cuenta de la biblioteca de la universidad, puede descargar una copia. Si no lo hace, dejé el enlace a la versión de intercambio de archivos, pero no lo he usado, así que no puedo garantizar su eficacia.
Tengo un conjunto de datos acelerométricos que se ven afectados por picos eléctricos.
Estoy buscando un buen método para filtrar o reducir estos picos, ya que necesito calcular en estos datos una ventana de FFT y otros indicadores estadísticos como la curtosis y la asimetría. No puedo simplemente borrar estos valores atípicos o reemplazarlos con NaN. Muestreo 2000 [hz]
Hasta ahora probé MATLAB 2012b:
- Eliminación de ondulaciones de onda (Haar wavelet)
- Filtro mediano
- Despike e iterpolate enfoque
¿Puede sugerir un enfoque adecuado para tratar con estos datos?
Sugeriría un alisamiento local. Al definir umbrales y promediar todos los valores por debajo y por encima.
Af = data.example1;
% Thresholds
Tl = -0.6;
To = 0.6;
peaks = find( Af < Tl | Af > To);
Af(peaks) = ( Af(peaks-1) + Af(peaks+1) ) / 2;
El problema con este enfoque es que sus outliners a veces consisten en hasta 6 muestras. Por lo tanto, debe suavizar en múltiples pasos utilizando un ciclo while:
Af = data.example1;
% Thresholds
Tl = -0.6;
To = 0.6;
% initialisation
peaks = find( Af < Tl | Af > To);
counter = 0;
while ~isempty(peaks)
peaks = find( Af < Tl | Af > To);
Af(peaks) = ( Af(peaks-1) + Af(peaks+1) ) / 2;
counter=counter+1;
end
después de 6 iteraciones obtienes el siguiente resultado:
Para otros que puedan necesitar esto, esto es lo que terminé usando. Aquí está el enlace del archivo de datos del archivo de datos
Gracias a @thewaywewalk
Picos electicos del filtro Matlab en datos acelerométricos
clear all, clc,clf,tic
aa=csvread(strcat(''/tmp/example_data_with_peak.txt''),5,0); %will skip the first 5 rows that are text and zeros
figure(1);
plot(aa)
Af=aa;
% Thresholds
Tl = -mean(abs(aa))*10
To =mean(abs(aa))*10
% initialisation
[peaks_r,peaks_c] = find( Af < Tl | Af > To);
peaks = find( Af < Tl | Af > To);
counter = 0;
while ~isempty(peaks)
peaks = find( Af < Tl | Af > To);
try
Af(peaks) = ( Af(peaks-1) + Af(peaks+1) ) / 2;
catch
if peaks(1) == 1
Af(1) = 0;
else
Af(end) = 0;
end
end
counter=counter+1;
end
counter
figure(2);
plot(Af)
Aquí están las imágenes de antes y después.
Un moderador fusionó esta pregunta con esta pregunta , por eso se ve un poco complicado aquí. ¡Esta respuesta considera problemas adicionales en la segunda pregunta!
La siguiente no es una solución completamente limpia, el código se adoptó de mi respuesta anterior , pero agregué una excepción para su caso, por lo que no es necesario que borre valores al principio y / o al final de sus datos manualmente. Descarta solo estos valores no válidos, que no deberían causar problemas.
Af = csvread(strcat(''example_data_with_peak.txt''),5,0);
% Thresholds
Tl = -0.04;
To = 0.04;
% initialisation
peaks = find( Af < Tl | Af > To);
counter = 0;
while ~isempty(peaks)
peaks = find( Af < Tl | Af > To);
try
Af(peaks) = ( Af(peaks-1) + Af(peaks+1) ) / 2;
catch
if peaks(1) == 1
Af(1) = 0;
else
Af(end) = 0;
end
end
counter=counter+1;
end
figure(2);
plot(Af)
Para determinar el umbral, puede usar algo como esto, pero también es bastante fuerza bruta:
thresh = 15*mean(abs(findpeaks(Af)));