Como em qualquer coisa, algumas vezes algumas ferramentas são melhores que outras.
Os filtros de média móvel (MA) podem ser usados para suavizar os dados e são FIR. Eles são praticamente o filtro mais simples que você pode criar e funcionam bem para muitas tarefas, desde que você não esteja tentando modelar saltos repentinos ou tendências polinomiais. No entanto, lembre-se de que esses filtros são basicamente apenas passa-baixas, portanto, eles funcionam melhor quando os dados de que você gosta no sinal são de baixa frequência e banda bastante estreita.
Os filtros Savitzky-Golay (SG) são um grupo especial de filtros FIR que essencialmente ajustam um polinômio à sua série temporal, à medida que a convolução desliza ao longo do sinal. Os filtros SG são úteis para sinais onde as coisas com as quais você se importa não são necessariamente de baixa frequência e banda bastante estreita.
Eu acho que você descobrirá que, se você ler a página da Wikipedia que vinculou bastante, isso explica a diferença entre os filtros SG e MA com detalhes bastante rigorosos. No entanto, lembre-se: no final, elas são apenas ferramentas para fazer coisas semelhantes; você decide quando usar a ferramenta certa.
EDIT :
Como parece haver alguma confusão de que os filtros SG são "adaptáveis" de alguma forma em um nível básico, incluí um exemplo simples do MATLAB. Como Dan apontou, eles podem ser adaptados, mas sua implementação básica geralmente não é. Ao inspecionar o código, você verá que isso é apenas uma consulta de matriz com um tratamento especial. Nada neste filtro é "adaptável" no sentido tradicional; você simplesmente escolhe um ajuste polinomial e o comprimento sobre o qual esse polinômio será ajustado ao sinal por convolução; SG é FIR essencial. O script que eu tenho abaixo produz este enredo:
Olhando para esta figura, você pode ver que o MA e o SG realizam essencialmente a mesma coisa, mas com algumas distinções importantes:
- O MA faz um ótimo trabalho para suprimir o ruído, mas faz um mau trabalho capturando os saltos transitórios no sinal. Podemos suprimir ainda mais ruído aumentando o comprimento do filtro, mas ele terá um desempenho ainda pior nos transientes; esse efeito será visto como "mancha" perto de qualquer transiente, o que você poderá ver na figura mostrada.
- O SG faz um ótimo trabalho de captura dos transitórios do sinal, mas não muito bom de suprimir o ruído (pelo menos em comparação com um MA do mesmo tamanho). Podemos melhorar a supressão de ruído perto de não-transitórios, aumentando o comprimento do quadro, mas isso apresentará um toque análogo ao fenômeno de Gibb próximo a quaisquer transitórios.
Para que você entenda melhor como esses filtros funcionam, recomendamos que você pegue o código aqui e manipule-o e veja como todas as partes individuais do filtro SG funcionam.
Código para o exemplo MATLAB:
% Generate a signal "s" that has square waves, and scale it with a
% polynomial of order 5
up = 1*ones(1,100);
down = zeros(1,150);
s = [down down up up down up down up down up up up down down down down down];
n = numel(s);
nn = linspace(0,4,numel(s));
s = s .* (nn .^5);
sn = (s + 4*randn(size(s))).';
% smooth it with SMA of length 15
sz = 15;
h = 1/sz * ones(1,sz);
sn_sma = conv(sn,h,'same');
% smooth it with sgolay of frame length 15
m = (sz-1)/2;
% look up the SG matrix for this order and size
B = sgolay(5, sz);
% compute the steady state response for the signal, i.e. everywhere that
% isnt the first or last "frame" for the SG filter
steady = conv(sn, B(m+1,:), 'same');
% handle the transiet portion at the start of the signal
y_st = B(1:m,:)*sn(1:sz);
% handle the transient portion at the end of the signal
y_en = B(sz -m+1 : sz, :) * sn(n - sz+1:n);
% combine our results
sn_sg = steady;
sn_sg(1:m) = y_st;
sn_sg(n-m+1:n) = y_en;
% plots
figure(1);
hold off;
plot(sn,'Color',[0.75 0.75 0.75]);
hold on;
plot(sn_sma,'b');
plot(sn_sg,'r');
legend('Noisy Signal','MA Smoothing','SG Smoothing, order 5','Location','NorthWest');
NOTA
minha resposta anterior (antes desta edição) que indica o filtro Savitzky-Golay (SG) como um dependente não linear dos dados de entrada com variação de tempo estava errado, devido a uma interpretação incorreta prematura de como um filtro Savitzky-Golay (SG) calcula sua saída de acordo com o link wiki fornecido. Portanto, agora estou corrigindo isso para o benefício daqueles que também veriam como os filtros SG são implementáveis pela filtragem FIR-LTI. Graças a @MattL. por sua correção, o grande vínculo que ele forneceu e a paciência que ele tinha (que eu nunca poderia ter demonstrado) durante minha investigação do problema. Embora honestamente prefira uma objeção mais detalhada, que claramente não é necessária. Observe também que a resposta correta é a outra, esta é apenas para esclarecimentos adicionais das propriedades LTI dos filtros SG.
Agora, não é de surpreender que quando alguém (que nunca usou esses filtros antes) enfrenta a definição do filtro SG como um ajuste polinomial de LSE de baixa ordem para dados fornecidos, ele imediatamente salta para a conclusão de que esses dados são dependentes, não lineares e filtros adaptativos com variação de tempo (turno).
No entanto, o procedimento de ajuste polinomial é inteligentemente interpretado pelo próprio SG, de modo que permite uma filtragem linear completamente independente dos dados, invariável no tempo e possível de dados, tornando o SG um filtro LTI-FIR fixo.
Abaixo está um resumo mais curto do link fornecido por MattL. Para detalhes que parecem estar faltando, consulte o documento original ou peça esclarecimentos. Mas eu não gostaria de reproduzir todo o documento aqui.
Agora, para aqueles que estão familiarizados com o procedimento polyfit LSE, simplesmente escreverei a equação da matriz resultante (no link) que define o conjunto ideal de coeficientes:
Agora vamos recuar por um momento e discutir um ponto aqui.
... Este (o polifit LSE) pode ser repetido em cada amostra da entrada, produzindo sempre um novo polinômio e um novo valor da sequência de saída y [n] ...
Então, como superamos essa surpresa intrigante? Ao interpretar e definir a saída do filtro SG para o seguinte:
COMENTE
CÓDIGO MATLAB / OCTVE
A saída é:
Espero que isso esclareça a questão.
fonte