Thursday 21 December 2017

Média móvel vs filtro passa-baixa


Resposta de Freqüência do Filtro de Média Corrente A resposta de freqüência de um sistema LTI é a DTFT da resposta de impulso. A resposta de impulso de uma média móvel de L é uma média móvel. Uma vez que o filtro de média móvel é FIR, a resposta de freqüência reduz-se à soma finita We Pode usar a identidade muito útil para escrever a resposta de freqüência como onde temos deixar ae menos jomega. N 0 e M L menos 1. Podemos estar interessados ​​na magnitude desta função para determinar quais freqüências passam pelo filtro sem atenuação e quais são atenuadas. Abaixo está um gráfico da magnitude desta função para L 4 (vermelho), 8 (verde) e 16 (azul). O eixo horizontal varia de zero a pi radianos por amostra. Observe que, em todos os três casos, a resposta de freqüência tem uma característica de passagem baixa. Uma componente constante (frequência zero) na entrada passa através do filtro sem ser atenuada. Certas frequências mais elevadas, como pi / 2, são completamente eliminadas pelo filtro. No entanto, se a intenção era projetar um filtro lowpass, então não temos feito muito bem. Algumas das frequências mais altas são atenuadas apenas por um factor de cerca de 1/10 (para a média móvel de 16 pontos) ou 1/3 (para a média móvel de quatro pontos). Podemos fazer muito melhor do que isso. O gráfico acima foi criado pelo seguinte código de Matlab: omega 0: pi / 400: pi H4 (1/4) (1-exp (-iomega4)) ./ (1-exp (-iomega)) H8 (1/8 ) (1-exp (-iomega8)) ./ (1-exp (-iomega)) lote (omega , Abs (H4) abs (H8) abs (H16)) eixo (0, pi, 0, 1) Copyright copy 2000- - Universidade da Califórnia, BerkeleyIm codificação algo no momento em que Im tendo um monte de valores ao longo do tempo de um Hardware bússola. Esta bússola é muito precisa e atualiza com muita freqüência, com o resultado de que se ele jiggles ligeiramente, eu acabar com o valor estranho que é descontroladamente inconsistente com seus vizinhos. Quero suavizar esses valores. Tendo feito alguma leitura ao redor, parece que o que eu quero é um filtro passa-alta, um filtro passa-baixa ou uma média móvel. Movendo a média que eu posso começar para baixo com, basta manter um histórico dos últimos 5 valores ou o que quer que, e usar a média desses valores a jusante no meu código onde eu estava uma vez apenas usando o valor mais recente. Isso deve, eu acho, suavizar esses jiggles muito bem, mas parece-me que o seu provavelmente bastante ineficiente, e este é provavelmente um daqueles Problemas Conhecidos aos Programadores Adequados para que theres uma solução de Matemática Inteligente realmente limpa. Eu sou, entretanto, um daqueles programadores self-taught terríveis sem um pedaço da instrução formal em qualquer coisa vagamente relacionado a CompSci ou à matemática. Ler em torno de um pouco sugere que este pode ser um filtro de alta ou baixa passagem, mas eu não consigo encontrar nada que explique em termos compreensíveis para um hack como eu o que o efeito desses algoritmos seria sobre uma matriz de valores, muito menos como a matemática Funciona. A resposta dada aqui. Por exemplo, tecnicamente responde à minha pergunta, mas apenas em termos compreensíveis para aqueles que provavelmente já sabem como resolver o problema. Seria uma pessoa muito linda e inteligente quem poderia explicar o tipo de problema que isso é, e como as soluções funcionam, em termos compreensíveis para um graduado em Artes. Se a sua média móvel tem que ser longa, a fim de alcançar a suavização necessária, e você realmente não precisa de qualquer forma especial de kernel, então você está melhor se você usar uma média móvel exponencial decadência: onde você Escolha minúscula para ser uma constante apropriada (por exemplo, se você escolher minúsculo 1- 1 / N, ele terá a mesma quantidade de média como uma janela de tamanho N, mas distribuídos de forma diferente sobre pontos mais antigos). Enfim, uma vez que o próximo valor da média móvel depende apenas do anterior e seus dados, você não tem que manter uma fila ou qualquer coisa. E você pode pensar nisso como fazendo algo como, Bem, eu tenho um novo ponto, mas eu realmente não confio, então eu vou manter 80 da minha antiga estimativa da medição, e só confiar neste novo ponto de dados 20. Isso é Praticamente o mesmo que dizer, Bem, eu só confio neste novo ponto 20, e eu uso 4 outros pontos que eu confio na mesma quantidade, exceto que em vez de tomar explicitamente os 4 outros pontos, você está supondo que a média que você fez na última vez Era sensato para que você possa usar seu trabalho anterior. Resposta Eu sei que isso é 5 anos de atraso, mas obrigado por uma resposta incrível. I39m trabalhando em um jogo onde o som muda com base na sua velocidade, mas devido à execução do jogo em um computador lento ass, a velocidade flutuaria descontroladamente, o que era bom para a direção, mas super irritante em termos de som. Esta foi uma solução realmente simples e barata para algo que eu pensei que seria um problema muito complexo. Ndash Adam Mar 16 15 at 20:20 Se você estiver tentando remover o valor estranho ocasional, um filtro passa-baixa é a melhor das três opções que você identificou. Os filtros passa-baixa permitem mudanças de baixa velocidade, como as causadas pela rotação de uma bússola à mão, ao mesmo tempo em que rejeitam mudanças de alta velocidade, como as causadas por solavancos na estrada, por exemplo. Uma média móvel provavelmente não será suficiente, uma vez que os efeitos de um único blip em seus dados afetarão vários valores subseqüentes, dependendo do tamanho de sua janela de média móvel. Se os valores ímpares forem facilmente detectados, você pode até estar melhor com um algoritmo de remoção de glitch que ignora completamente eles: Aqui está um gráfico guick para ilustrar: O primeiro gráfico é o sinal de entrada, com uma falha desagradável. O segundo gráfico mostra o efeito de uma média móvel de 10 amostras. O gráfico final é uma combinação da média de 10 amostras e do algoritmo de detecção de falhas simples mostrado acima. Quando a falha é detectada, a média de 10 amostras é usada em vez do valor real. Respondeu Sep 21 10 at 13:38 Bem explicado, e pontos de bônus para o gráfico) ndash Henry Cooke Sep 22 10 at 0:50 Uau. Seldomly viu uma resposta tão agradável ndash Muis Jun 4 13 at 9:14 A média móvel é um filtro passa-baixa. Ndash nomen Oct 21 13 at 19:36 Experimente uma mediana de execução / streaming em vez disso. Ndash kert Apr 25 14 at 22:09 Movendo média, eu posso descer com. Mas parece-me que o seu provavelmente bastante ineficaz. Não há realmente nenhuma razão uma média móvel deve ser ineficiente. Você mantém o número de pontos de dados desejados em algum buffer (como uma fila circular). Em cada novo ponto de dados, você pop o valor mais antigo e subtraí-lo de uma soma, e empurrar o mais novo e adicioná-lo à soma. Assim, cada novo ponto de dados realmente só envolve um pop / push, uma adição e uma subtração. A sua média móvel é sempre esta soma deslocada dividida pelo número de valores no seu buffer. Ele fica um pouco mais complicado se você está recebendo dados simultaneamente a partir de vários segmentos, mas desde que seus dados vem de um dispositivo de hardware que parece altamente duvidoso para mim. Oh e também: programadores autodidacta terríveis se unem) A média móvel parecia ineficiente para mim porque você tem que armazenar um buffer de valores - melhor apenas fazer algumas Matemática Inteligente com seu valor de entrada e valor de funcionamento atual Eu acho que é como média móvel exponencial Funciona. Uma otimização que eu tenho visto para esse tipo de média móvel envolve o uso de um amplificador de fila de comprimento fixo, um ponteiro para onde você está nessa fila, e apenas envolver o ponteiro ao redor (com ou um if). Voila Nenhum impulso caro / pop. Poder para os amadores, irmão Henry: Para uma média móvel em linha reta você precisa do buffer simplesmente para que você saiba o valor obtém estourou quando o próximo valor ser empurrado. Dito isto, o amplificador de fila de comprimento fixo que você está descrevendo é exatamente o que eu quis dizer com fila quotcircular. Isso é porque eu estava dizendo que ele não é eficiente. O que você acha que eu quis dizer E se sua resposta é quotan array que muda seus valores de volta em cada remoção indexada (como std :: vector em C). Bem, então, I39m tão machucar eu don39t ainda quero falar com você mais) ndash Dan Tao Sep 22 10 às 1:58 Henry: Eu don39t saber sobre AS3, mas um programador Java tem coleções como CircularQueue à sua disposição (I39m Não um desenvolvedor Java, então tenho certeza de que há melhores exemplos lá fora que é exatamente o que eu encontrei a partir de uma pesquisa rápida do Google), que implementa precisamente a funcionalidade que estamos falando. I39m bastante confiante a maioria das linguagens de médio e baixo nível com bibliotecas padrão têm algo semelhante (por exemplo, em QueueltTgt lá). Enfim, eu era filosofia, então. tudo é perdoado. Ndash Dan Tao Sep 22 10 em 12:44 Uma média móvel decrescente exponencialmente pode ser calculada manualmente com apenas a tendência se você usar os valores adequados. Veja fourmilab. ch/hackdiet/e4/ para obter uma idéia sobre como fazer isso rapidamente com uma caneta e papel, se você está procurando exponencialmente suavizada média móvel com 10 suavização. Mas desde que você tem um computador, você provavelmente quer fazer deslocamento binário ao contrário de deslocamento decimal) Desta forma, tudo que você precisa é uma variável para o seu valor atual e um para a média. A média seguinte pode então ser calculada a partir daí. Há uma técnica chamada uma porta de intervalo que funciona bem com amostras espúrias de baixa ocorrência. Supondo o uso de uma das técnicas de filtro mencionadas acima (média móvel, exponencial), uma vez que você tenha histórico suficiente (uma Constante de Tempo) você pode testar a nova amostra de dados para razoabilidade antes de ser adicionada à computação. É necessário algum conhecimento da taxa máxima de mudança razoável do sinal. A amostra bruta é comparada com o valor mais recente suavizado, e se o valor absoluto dessa diferença é maior do que o intervalo permitido, essa amostra é descartada (ou substituída por alguma heurística, por exemplo, uma previsão baseada no diferencial de inclinação ou na tendência Valor de predição de suavização exponencial dupla) respondeu 30 de abril a 6: 56 Um filtro de média móvel mede um número de amostras de entrada e produzir uma única amostra de saída. Esta acção de média remove os componentes de alta frequência presentes no sinal. Filtros de média móvel são normalmente utilizados como filtros de passa-baixa. No algoritmo de filtragem recursiva, amostras de saída anteriores também são tomadas para a média. Um filtro de média móvel mede um número de amostras de entrada e produz uma única amostra de saída. Esta acção de média remove os componentes de alta frequência presentes no sinal. Filtros de média móvel são normalmente utilizados como filtros de passa-baixa. No algoritmo de filtragem recursiva, amostras de saída anteriores também são tomadas para a média. Esta é a razão pela qual sua resposta ao impulso se estende até o infinito. Como usar o programa de exemplo O arquivo. zip contém tanto o código-fonte como o executável. Para compilar e executar o código-fonte que você precisa ter o Visual Basic 6.0 instalado no seu computador. Para executar o executável, você deve baixar e instalar arquivos de tempo de execução do Visual Basic 6.0. Execute movavgfilt. exe e você verá a janela principal. Na janela principal. A parte mais superior é o gerador de função. Que produz diferentes formas de onda para testar o filtro. Podemos interativamente alterar a amplitude, freqüência e forma do sinal gerado. Para testar o programa, primeiro devemos gerar uma forma de onda apropriada. Aqui nós geraremos uma forma de onda complexa que consiste em duas freqüências diferentes. Deixe tudo em configurações padrão e clique no botão quotgeneratequot. Agora você pode ver um sinal de 10 Hz no gráfico ao lado do gerador de sinal. A figura abaixo mostra a forma de onda. Agora altere a Freqüência para 100 Hz e clique no botão quotgeneratequot novamente. A forma de onda recém-gerada é adicionada à forma de onda existente e a forma de onda resultante parece uma onda sin 10Hz com ruído de 100 Hz. Veja a forma de onda abaixo. Esta forma de onda é mais adequada para testar o filtro, pois contém duas freqüências diferentes. Você pode executar o filtro clicando no botão quotFilterquot. Das opções disponíveis à esquerda para o botão quotFilterquot. Você pode escolher Filtração recursiva, não recursiva ou sem filtragem. A figura abaixo mostra a saída do filtro. Download Moving Average Filtro de código fonteMoving Average Filter (MA filter) Carregando. O filtro de média móvel é um simples filtro Low Pass FIR (Finite Impulse Response) comumente usado para suavizar uma matriz de dados / sinal amostrados. Ele toma M amostras de entrada de cada vez e pegue a média dessas M-amostras e produz um único ponto de saída. É uma estrutura de LPF (Low Pass Filter) muito simples que é útil para cientistas e engenheiros para filtrar o componente ruidoso indesejado dos dados pretendidos. À medida que o comprimento do filtro aumenta (o parâmetro M) a suavidade da saída aumenta, enquanto que as transições nítidas nos dados são feitas cada vez mais sem corte. Isto implica que este filtro tem excelente resposta no domínio do tempo mas uma resposta de frequência pobre. O filtro MA executa três funções importantes: 1) Toma M pontos de entrada, calcula a média desses pontos M e produz um único ponto de saída 2) Devido à computação / cálculos envolvidos. O filtro introduz uma quantidade definida de atraso 3) O filtro age como um Filtro de Passagem Baixa (com fraca resposta de domínio de freqüência e uma boa resposta de domínio de tempo). Código Matlab: O código matlab seguinte simula a resposta no domínio do tempo de um filtro M-point Moving Average e também traça a resposta de freqüência para vários comprimentos de filtro. Time Domain Response: No primeiro gráfico, temos a entrada que está entrando no filtro de média móvel. A entrada é barulhenta e nosso objetivo é reduzir o ruído. A figura a seguir é a resposta de saída de um filtro de média móvel de 3 pontos. Pode-se deduzir da figura que o filtro de média móvel de 3 pontos não fez muito na filtragem do ruído. Aumentamos os toques do filtro para 51 pontos e podemos ver que o ruído na saída reduziu muito, o que é mostrado na próxima figura. Nós aumentamos as derivações para 101 e 501 e podemos observar que mesmo que o ruído seja quase zero, as transições são drasticamente ditas (observe a inclinação em ambos os lados do sinal e compare-as com a transição ideal da parede de tijolo em Nossa entrada). Resposta de Freqüência: A partir da resposta de freqüência pode-se afirmar que o roll-off é muito lento ea atenuação de banda de parada não é boa. Dada esta atenuação de banda de parada, claramente, o filtro de média móvel não pode separar uma banda de freqüências de outra. Como sabemos que um bom desempenho no domínio do tempo resulta em mau desempenho no domínio da freqüência, e vice-versa. Em suma, a média móvel é um filtro de suavização excepcionalmente bom (a ação no domínio do tempo), mas um filtro de passagem baixa excepcionalmente ruim (a ação no domínio da freqüência) Links externos: Livros recomendados: Primary SidebarAs outros já mencionaram, você Deve considerar um filtro IIR (resposta de impulso infinito) em vez do filtro FIR (resposta de impulso finito) que você está usando agora. Há mais, mas à primeira vista os filtros FIR são implementados como convoluções explícitas e filtros IIR com equações. O filtro IIR especial que eu uso muito em microcontroladores é um filtro de passa-baixa de pólo único. Este é o equivalente digital de um simples filtro analógico R-C. Para a maioria das aplicações, elas terão melhores características do que o filtro de caixa que você está usando. A maioria dos usos de um filtro de caixa que eu encontrei são o resultado de alguém não prestar atenção na classe de processamento de sinal digital, e não como resultado de precisar de suas características particulares. Se você só quer atenuar as altas freqüências que você sabe que são ruído, um único pólo filtro passa-baixo é melhor. A melhor maneira de implementar um digitalmente em um microcontrolador é geralmente: FILT lt - FILT FF (NEW - FILT) FILT é um pedaço de estado persistente. Esta é a única variável persistente que você precisa para calcular este filtro. NEW é o novo valor que o filtro está sendo atualizado com esta iteração. FF é a fracção do filtro. Que ajusta o peso do filtro. Olhe para este algoritmo e veja que para FF 0 o filtro é infinitamente pesado desde a saída nunca muda. Para FF 1, seu realmente nenhum filtro em tudo desde que a saída apenas segue a entrada. Os valores úteis estão no meio. Em sistemas pequenos você escolhe FF para ser 1/2 N de modo que a multiplicação por FF possa ser realizada como um deslocamento para a direita por N bits. Por exemplo, FF pode ser 1/16 e multiplicar por FF, portanto, um deslocamento para a direita de 4 bits. Caso contrário, este filtro precisa apenas de uma subtração e uma adição, embora os números geralmente precisam ser mais largos do que o valor de entrada (mais na precisão numérica em uma seção separada abaixo). Eu costumo tomar leituras A / D significativamente mais rápido do que eles são necessários e aplicar dois desses filtros em cascata. Este é o equivalente digital de dois filtros R-C em série, e atenua por 12 dB / oitava acima da freqüência de rolloff. No entanto, para as leituras A / D é geralmente mais relevante olhar para o filtro no domínio do tempo, considerando sua resposta passo. Isso indica a rapidez com que seu sistema verá uma alteração quando a coisa que você está medindo muda. Para facilitar a concepção destes filtros (que significa apenas escolher FF e decidir quantos deles para cascatear), eu uso o meu programa FILTBITS. Você especifica o número de bits de deslocamento para cada FF na série de filtros em cascata e calcula a resposta da etapa e outros valores. Na verdade eu costumo correr isso através do meu script wrapper PLOTFILT. Isso executa FILTBITS, que faz um arquivo CSV, e depois traça o arquivo CSV. Por exemplo, aqui está o resultado de PLOTFILT 4 4: Os dois parâmetros para PLOTFILT significa que haverá dois filtros em cascata do tipo descrito acima. Os valores de 4 indicam o número de bits de mudança para realizar a multiplicação por FF. Os dois valores de FF são, portanto, 1/16 neste caso. O traço vermelho é a resposta da etapa da unidade, e é a coisa principal a olhar. Por exemplo, isto diz-lhe que se a entrada muda instantaneamente, a saída do filtro combinado estabelecerá a 90 do novo valor em 60 iterações. Se você se preocupa com 95 settling tempo, então você tem que esperar cerca de 73 iterações, e por 50 tempo de resolução apenas 26 iterações. O traço verde mostra a saída de um único pico de amplitude total. Isto dá-lhe alguma idéia da supressão de ruído aleatória. Parece que nenhuma amostra irá causar mais do que uma alteração de 2,5 na saída. O traço azul é dar uma sensação subjetiva do que este filtro faz com o ruído branco. Este não é um teste rigoroso, uma vez que não há garantia o que exatamente o conteúdo foi dos números aleatórios escolhidos como a entrada de ruído branco para esta execução de PLOTFILT. Seu somente para dar-lhe uma sensação áspera de quanto será squashed e de como liso é. PLOTFILT, talvez FILTBITS, e muitas outras coisas úteis, especialmente para o desenvolvimento de firmware PIC está disponível no software PIC Development Tools release na minha página de downloads de Software. Adicionado sobre precisão numérica eu vejo dos comentários e agora uma nova resposta que há interesse em discutir o número de bits necessários para implementar este filtro. Observe que a multiplicação por FF criará Log 2 (FF) novos bits abaixo do ponto binário. Em sistemas pequenos, FF é geralmente escolhido para ser 1/2 N para que este multiplicar é realmente realizado por um deslocamento à direita de N bits. FILT é geralmente um inteiro de ponto fixo. Observe que isso não altera nenhuma das matemáticas do ponto de vista dos processadores. Por exemplo, se você estiver filtrando leituras A / D de 10 bits e N 4 (FF 1/16), então você precisará de 4 bits de fração abaixo das leituras A / D inteiras de 10 bits. Um processadores mais, youd estar fazendo operações de 16 bits inteiro devido às leituras de 10 bit A / D. Neste caso, você ainda pode fazer exatamente as mesmas operações de 16 bits inteiros, mas comece com as leituras A / D esquerda deslocada por 4 bits. O processador não sabe a diferença e não precisa. Fazer a matemática em inteiros inteiros de 16 bits funciona se você os considera 12,4 pontos fixos ou inteiros verdadeiros de 16 bits (16,0 ponto fixo). Em geral, você precisa adicionar N bits cada pólo de filtro se você não quiser adicionar ruído devido à representação numérica. No exemplo acima, o segundo filtro de dois teria 1044 18 bits para não perder informações. Na prática em uma máquina de 8 bits que significa youd usar valores de 24 bits. Tecnicamente apenas o segundo pólo de dois precisaria do valor mais amplo, mas para a simplicidade do firmware eu costumo usar a mesma representação, e, portanto, o mesmo código, para todos os pólos de um filtro. Normalmente eu escrevo uma sub-rotina ou macro para executar uma operação de pólo de filtro, em seguida, aplicar isso a cada pólo. Se uma subrotina ou macro depende se os ciclos ou a memória do programa são mais importantes nesse projeto específico. De qualquer maneira, eu uso algum estado zero para passar NOVO para a subrotina / macro, que atualiza FILT, mas também carrega isso para o mesmo estado zero NOVO foi dentro Isso torna mais fácil para aplicar vários pólos desde o FILT atualizado de um pólo é O NOVO do próximo. Quando uma sub-rotina, é útil ter um ponteiro apontar para FILT no caminho, que é atualizado para logo após FILT na saída. Desta forma, a sub-rotina opera automaticamente em filtros consecutivos na memória se for chamada várias vezes. Com uma macro você não precisa de um ponteiro desde que você passa no endereço para operar em cada iteração. Exemplos de código Aqui está um exemplo de uma macro como descrito acima para um PIC 18: E aqui está uma macro semelhante para um PIC 24 ou dsPIC 30 ou 33: Ambos estes exemplos são implementados como macros usando o meu pré-processador de assembler PIC. Que é mais capaz do que qualquer um das instalações macro incorporadas. Clabacchio: Outra questão que eu deveria ter mencionado é a implementação de firmware. Você pode escrever uma sub-rotina de filtro passa-baixa de um único pólo uma vez, depois aplicá-la várias vezes. Na verdade eu costumo escrever tal sub-rotina para ter um ponteiro na memória para o estado do filtro, em seguida, tê-lo avançar o ponteiro para que ele pode ser chamado em sucessão facilmente para realizar filtros multi-polo. Ndash Olin Lathrop Apr 20 12 at 15:03 1. muito obrigado por suas respostas - todas elas. Eu decidi usar este filtro IIR, mas este filtro não é usado como um filtro LowPass padrão, uma vez que eu preciso para a média de valores de contador e compará-los para detectar alterações em um determinado intervalo. Uma vez que estes Valores van ser de dimensões muito diferentes, dependendo de hardware que eu queria tomar uma média, a fim de ser capaz de reagir a estas alterações Hardware específicas automaticamente. Ndash sensslen May 21 12 at 12:06 Se você pode viver com a restrição de um poder de dois números de itens para a média (ou seja, 2,4,8,16,32 etc), então a divisão pode ser feita de forma fácil e eficiente em um Micro de baixo desempenho sem divisão dedicada, pois pode ser feito como um deslocamento bit. Cada turno é um poder de dois, por exemplo: O OP pensou que ele tinha dois problemas, dividindo em um PIC16 e memória para seu buffer de anel. Esta resposta mostra que a divisão não é difícil. É verdade que ele não trata o problema da memória, mas o sistema SE permite respostas parciais, e os usuários podem tirar algo de cada resposta por si mesmos, ou mesmo editar e combinar outras respostas. Uma vez que algumas das outras respostas exigem uma operação de divisão, elas são igualmente incompletas, uma vez que não mostram como efetivamente conseguir isso em um PIC16. Ndash Martin Apr 20 12 at 13:01 Há uma resposta para um verdadeiro filtro de média móvel (aka boxcar filtro) com menos requisitos de memória, se você não mente downsampling. É chamado um filtro integrador-pente em cascata (CIC). A idéia é que você tem um integrador que você toma as diferenças de um período de tempo, eo dispositivo de economia de memória chave é que por downsampling, você não tem que armazenar cada valor do integrador. Ele pode ser implementado usando o seguinte pseudocódigo: Seu comprimento médio móvel efetivo é decimationFactorstatesize, mas você só precisa manter em torno de amostras statesize. Obviamente, você pode obter um melhor desempenho se o seu statesize e decimationFactor são poderes de 2, de modo que a divisão e os operadores restantes são substituídos por turnos e máscara-ands. Postscript: Eu concordo com Olin que você deve sempre considerar filtros IIR simples antes de um filtro de média móvel. Se você não precisa de freqüência-nulos de um filtro de vagão, um filtro de passa-baixa de 1 pólo ou de 2 pólos provavelmente funcionará bem. Por outro lado, se você estiver filtrando para fins de decimação (tomando uma alta taxa de amostragem de entrada e de média para o seu uso por um processo de baixa taxa), em seguida, um CIC filtro pode ser exatamente o que você está procurando. (Especialmente se você pode usar statesize1 e evitar o ringbuffer completamente com apenas um valor único integrador anterior) Theres alguma análise em profundidade da matemática por trás usando o filtro IIR de primeira ordem que Olin Lathrop já descreveu mais sobre a troca de pilha Digital Signal Processing (Inclui muitas imagens bonitas.) A equação para este filtro IIR é: Isso pode ser implementado usando apenas inteiros e nenhuma divisão usando o código a seguir (pode precisar de alguma depuração como eu estava digitando na memória.) Este filtro aproxima uma média móvel de Os últimos K amostras, definindo o valor de alfa para 1 / K. Faça isso no código anterior, definindo BITS para LOG2 (K), ou seja, para K 16 set BITS para 4, para K 4 set BITS para 2, etc (eu verificar o código listado aqui logo que eu recebo uma alteração e Editar esta resposta, se necessário.) Responder Jun 23 12 at 4:04 Heres um filtro passa-baixo de um único pólo (média móvel, com freqüência de corte CutoffFrequency). Muito simples, muito rápido, funciona muito bem, e quase nenhuma sobrecarga de memória. Nota: Todas as variáveis ​​têm escopo além da função de filtro, exceto o passado em newInput Nota: Este é um filtro de etapa única. Várias etapas podem ser conectadas em cascata para aumentar a nitidez do filtro. Se você usar mais de uma etapa, você terá que ajustar DecayFactor (como se relaciona com a Cutoff-Frequency) para compensar. E, obviamente, tudo o que você precisa é dessas duas linhas colocadas em qualquer lugar, eles não precisam de sua própria função. Este filtro tem um tempo de aceleração antes que a média móvel represente a do sinal de entrada. Se você precisar ignorar esse tempo de aceleração, basta inicializar MovingAverage para o primeiro valor de newInput em vez de 0 e esperar que o primeiro newInput não seja um outlier. (CutoffFrequency / SampleRate) tem um intervalo entre 0 e 0,5. DecayFactor é um valor entre 0 e 1, geralmente perto de 1. Flutuadores de precisão única são bons o suficiente para a maioria das coisas, eu só prefiro dobra. Se você precisar ficar com números inteiros, você pode converter DecayFactor e Amplitude Factor em inteiros fracionários, em que o numerador é armazenado como o inteiro, eo denominador é um número inteiro de 2 (assim você pode bit-shift para a direita como o Denominador em vez de ter que dividir durante o loop de filtro). Por exemplo, se você usar DecayFactor 0,99, e você quiser usar números inteiros, você pode definir DecayFactor 0,99 65536 64881. E então, sempre que você multiplicar por DecayFactor em seu loop de filtro, basta deslocar o resultado 16. Para obter mais informações sobre isso, um excelente livro thats Online, capítulo 19 sobre filtros recursivos: dspguide / ch19.htm PS Para o paradigma da média móvel, uma abordagem diferente para definir DecayFactor e AmplitudeFactor que pode ser mais relevante para suas necessidades, vamos dizer que você quer o anterior, cerca de 6 itens média juntos, fazê-lo discretamente, youd adicionar 6 itens e dividir por 6, então Você pode definir o AmplitudeFactor para 1/6 e DecayFactor para (1.0 - AmplitudeFactor). Respondeu May 14 12 at 22:55 Todo mundo tem comentado completamente sobre a utilidade de IIR vs FIR, e na divisão de poder-de-dois. Id gostaria de dar alguns detalhes de implementação. O abaixo funciona bem em pequenos microcontroladores sem FPU. Não há multiplicação, e se você manter N um poder de dois, toda a divisão é de ciclo único bit-shifting. Tampão de toque FIR básico: mantém um buffer de execução dos últimos N valores e uma Soma em execução de todos os valores no buffer. Cada vez que uma nova amostra entra, subtraia o valor mais antigo no buffer de SUM, substitua-o pela nova amostra, adicione a nova amostra à SUM e a saída SUM / N. Tampão de anel IIR modificado: mantenha uma SUM corrente dos últimos N valores. Cada vez que uma nova amostra chega, SUM - SUM / N, adicione a nova amostra e a saída SUM / N. Se I39m lendo você direito, você está descrevendo um filtro IIR de primeira ordem, o valor que você está subtraindo isn39t o valor mais antigo que está caindo, mas é, em vez disso, a média dos valores anteriores. Os filtros IIR de primeira ordem podem certamente ser úteis, mas não tenho certeza do que você quer dizer quando sugere que a saída é a mesma para todos os sinais periódicos. A uma taxa de amostragem de 10KHz, a alimentação de uma onda quadrada de 100Hz em um filtro de caixa de 20 estágios produzirá um sinal que sobe uniformemente para 20 amostras, senta alto para 30, cai uniformemente para 20 amostras e senta baixo para 30. Uma primeira ordem IIR. Ndash supercat Aug 28 13 às 15:31 vai produzir uma onda que começa bruscamente a subir e gradualmente nivela perto (mas não no) máximo de entrada, então começa bruscamente a cair e nivela gradualmente perto (mas não) o mínimo de entrada. Comportamento muito diferente. Uma questão é que uma média móvel simples pode ou não ser útil. Com um filtro IIR, você pode obter um bom filtro com relativamente poucos calcs. O FIR que você descreve só pode lhe dar um retângulo no tempo - um sinc em freq - e você não pode gerenciar os lobos laterais. Pode valer a pena jogar algumas multiplicações inteiras para torná-la uma simpática e simétrica sintonia FIR se você pode poupar os carrapatos do relógio. Ndash Scott Seidman Aug 29 13 às 13:50 ScottSeidman: Não há necessidade de multiplicar se um simplesmente tem cada estágio do FIR ou saída a média da entrada para esse estágio e seu valor armazenado anterior, e depois armazenar a entrada (se tiver O intervalo numérico, pode-se usar a soma em vez da média). Se isso é melhor do que um filtro de caixa depende da aplicação (a resposta de passo de um filtro de caixa com um atraso total de 1ms, por exemplo, terá um pico d2 / dt desagradável quando a mudança de entrada e novamente 1ms mais tarde, mas terá O mínimo possível d / dt para um filtro com um atraso total de 1 ms). Como disse mikeselectricstuff, se você realmente precisa reduzir suas necessidades de memória, e você não se importa sua resposta ao impulso é uma exponencial (em vez de um pulso retangular), eu iria para um filtro de média móvel exponencial . Eu uso-os extensivamente. Com esse tipo de filtro, você não precisa de nenhum buffer. Você não tem que armazenar N amostras passadas. Apenas um. Assim, seus requisitos de memória são cortados por um fator de N. Além disso, você não precisa de qualquer divisão para isso. Somente multiplicações. Se você tiver acesso a aritmética de ponto flutuante, use multiplicações de ponto flutuante. Caso contrário, faça multiplicações inteiras e desloque para a direita. No entanto, estamos em 2017, e eu recomendo que você use compiladores (e MCUs) que permitem que você trabalhe com números de ponto flutuante. Além de ser mais memória eficiente e mais rápido (você não tem que atualizar itens em qualquer buffer circular), eu diria que é também mais natural. Porque uma resposta de impulso exponencial corresponde melhor à maneira como a natureza se comporta, na maioria dos casos. Um problema com o filtro IIR como quase tocado por olin e supercat mas aparentemente desconsiderado por outros é que o arredondamento para baixo introduz alguma imprecisão (e potencialmente viés / truncamento). Assumindo que N é uma potência de dois, e apenas aritmética inteira é usada, o deslocamento direto sistematicamente elimina os LSBs da nova amostra. Isso significa que quanto tempo a série poderia ser, a média nunca vai levar esses em conta. Por exemplo, suponha uma série lentamente decrescente (8,8,8,8,7,7,7,7,6,6) e suponha que a média é realmente 8 no início. A amostra do punho 7 trará a média para 7, independentemente da intensidade do filtro. Apenas para uma amostra. Mesma história para 6, etc. Agora pense no oposto. A série sobe. A média ficará em 7 para sempre, até que a amostra seja grande o suficiente para fazer a mudança. Claro, você pode corrigir o viés adicionando 1 / 2N / 2, mas isso não vai realmente resolver o problema de precisão. Nesse caso a série decrescente permanecerá para sempre em 8 até que a amostra seja 8-1 / 2 (N / 2). Para N4, por exemplo, qualquer amostra acima de zero manterá a média inalterada. Acredito que uma solução para isso implicaria manter um acumulador dos LSBs perdidos. Mas eu não fui longe o suficiente para ter o código pronto, e não tenho certeza que não iria prejudicar o poder IIR em alguns outros casos de série (por exemplo, se 7,9,7,9 seria média para 8 então). Olin, sua cascata de dois estágios também precisaria de alguma explicação. Você quer dizer segurando dois valores médios com o resultado do primeiro alimentado para o segundo em cada iteração. Qual é o benefício deste

No comments:

Post a Comment