Gravei 2 sinais de um osciloscópio. Eles se parecem com isso:
Quero medir o atraso de tempo entre eles no Matlab. Cada sinal possui 2000 amostras com uma frequência de amostragem de 2001000,5.
Os dados estão em um arquivo csv. É isso que eu tenho até agora.
Apaguei os dados de tempo do arquivo csv para que apenas os níveis de tensão estejam no arquivo csv.
x1 = csvread('C://scope1.csv');
x2 = csvread('C://scope2.csv');
cc = xcorr(x1,x2);
plot(cc);
Isso fornece este resultado:
Pelo que li, preciso fazer a correlação cruzada desses sinais e isso deve me dar um pico em relação ao atraso de tempo. No entanto, quando tomo a correlação cruzada desses sinais, obtenho um pico em 2000, que sei que não está correto. O que devo fazer com esses sinais antes de cruzá-los? Apenas procurando alguma direção.
EDIT: depois de remover o deslocamento DC, este é o resultado que agora estou obtendo:
Existe uma maneira de limpar isso para obter um atraso de tempo mais definido?
EDIT 2: Aqui estão os arquivos:
http://dl.dropbox.com/u/10147354/scope1col.csv
http://dl.dropbox.com/u/10147354/scope2col.csv
fonte
Respostas:
@NickS
Como está longe de ser certo que o segundo sinal nas parcelas é de fato uma versão apenas atrasada do primeiro, outros métodos além da correlação cruzada clássica devem ser tentados. Isso ocorre porque a correlação cruzada (CC) é apenas um estimador de probabilidade máxima se o (s) seu (s) sinal (es) forem atrasados versões um do outro. Nesse caso, eles claramente não são, para não dizer nada sobre a não estacionariedade deles.
Nesse caso, acredito que o que pode funcionar é uma estimativa de tempo da energia significativa dos sinais. É verdade que 'significativo' pode ou não pode ser um pouco subjetivo, mas acredito que, observando seus sinais do ponto de vista estatístico, seremos capazes de quantificar 'significativo' e partir daí.
Para esse fim, fiz o seguinte:
PASSO 1: Calcule os envelopes de sinal:
Este passo é simples, pois o valor absoluto da saída da Hilbert-Transform de cada um de seus sinais é calculado. Existem outros métodos para calcular envelopes, mas isso é bastante simples. Este método calcula essencialmente a forma analítica do seu sinal, ou seja, a representação fasorial. Quando você toma o valor absoluto, está destruindo a fase e somente depois da energia.
Além disso, como estamos buscando uma estimativa de atraso de tempo da energia de seus sinais, essa abordagem é garantida.
PASSO 2: Ruído com filtros mediais não lineares que preservam as bordas:
Este é um passo importante. O objetivo aqui é suavizar os envelopes de energia, mas sem destruir ou suavizar as bordas e aumentar os tempos de subida. Na verdade, existe um campo inteiro dedicado a isso, mas para nossos propósitos aqui, podemos simplesmente usar um filtro Medial não linear fácil de implementar . (Filtragem mediana). Essa é uma técnica poderosa porque, diferentemente da filtragem média , a filtragem medial não anulará suas bordas, mas ao mesmo tempo 'suavizará' o seu sinal sem degradação significativa das bordas importantes, pois em nenhum momento qualquer aritmética está sendo realizada em seu sinal. (desde que o comprimento da janela seja ímpar). Para o nosso caso aqui, selecionei um filtro medial de amostras de tamanho de janela 25:
PASSO 3: Remover Tempo: Construir Funções de Estimativa de Densidade de Kernel Gaussiana:
O que aconteceria se você olhasse para o gráfico acima de lado e não da maneira normal? Matematicamente falando, o que você obteria se projetasse todas as amostras de nossos sinais denoisados no eixo da amplitude y? Ao fazer isso, conseguiremos remover o tempo, por assim dizer, e poderemos estudar apenas as estatísticas do sinal.
Intuitivamente, o que aparece na figura acima? Embora a energia do ruído seja baixa, ela tem a vantagem de ser mais 'popular'. Por outro lado, enquanto o envelope de sinal que possui energia é mais energético que o ruído, ele é fragmentado entre os limites. E se considerarmos a 'popularidade' como uma medida de energia? Isto é o que faremos com a implementação (básica) de uma Função de Densidade do Kernel (KDE), com um Kernel Gaussiano.
Para fazer isso, cada amostra é coletada e uma função gaussiana é construída usando seu valor como média, e uma largura de banda predefinida (variação) é selecionada a priori. Definir a variação do seu gaussiano é um parâmetro importante, mas você pode configurá-lo com base em estatísticas de ruído com base em sua aplicação e sinais típicos. (Eu só tenho dois arquivos para ativar). Se construirmos a Estimação do KDE, obteremos o seguinte gráfico:
Você pode pensar no KDE como uma forma contínua de um histograma, por assim dizer, e a variação como sua largura de caixa. No entanto, ele tem a vantagem de garantir um PDF suave, no qual podemos executar o primeiro e o segundo cálculos derivados. Agora que temos os KDEs gaussianos, podemos ver onde as amostras de ruído atingem seu pico de popularidade. Lembre-se de que o eixo x aqui representa as projeções de nossos dados no espaço de amplitude. Assim, podemos ver em quais limiares o ruído é o mais 'energético', e aqueles nos dizem quais limiares evitar.
No segundo gráfico, a primeira derivada dos KDEs gaussianos é obtida, e escolhemos a abcissa da primeira amostra após a primeira derivada após o pico da mistura de gaussianos para atingir um determinado valor próximo de zero. (Ou primeiro cruzamento de zero). Podemos usar esse método e ser 'seguros' porque nosso KDE foi construído com gaussianos suaves, com largura de banda razoável, e a primeira derivada dessa função suave e sem ruído foi usada. (Normalmente, as primeiras derivadas podem ser problemáticas em qualquer coisa, exceto nos sinais SNR altos, pois aumentam o ruído).
As linhas pretas mostram, então, em que limites seria sensato segmentar a imagem, de modo a evitar todo o ruído. Se aplicarmos nossos sinais originais, obteremos os seguintes gráficos, com as linhas pretas indicando o início da energia de nossos sinais:
Espero que isso tenha ajudado.
fonte
Existem alguns problemas ao fazer isso com autocorrelação
Uma abordagem muito mais simples seria usar um detector de limiar para encontrar os pontos de partida e simplesmente usar a diferença entre esses pontos como atraso.
fonte
Como as pichenettes indicaram, neste caso, um pico no meio da saída indica 0 atraso. O deslocamento do pico do ponto médio é o seu atraso de tempo.
EDIT: Me preocupa que a correlação seja quase um triângulo perfeito. Isso indica para mim que a correlação cruzada não está normalizando a energia. Isso fornece um viés injusto para atrasos menores em relação a atrasos maiores. Eu modificaria sua chamada xcorr para "cc = xcorr (x1, x2, 'imparcial');".
Essa não é, em sua opinião, uma solução perfeita, porque os resultados de grande atraso agora são mais instáveis do que os resultados de baixo atraso, porque são baseados em menos dados. Um grande pico nas extremidades pode ser falso pela mesma razão que você pode obter 100% de cara e sem coroa em apenas alguns lançamentos de moedas, embora seja extremamente improvável que ocorra em muitos lançamentos.
fonte
Como os outros apontaram, e parece que você percebeu com base na sua última edição da pergunta, não parece que a correlação cruzada forneça uma boa estimativa de atraso de tempo para os conjuntos de dados mostrados. A correlação mede a similaridade na forma entre duas séries temporais, deslizando uma pela outra por um intervalo de tempo e calculando um produto interno entre as duas séries a cada atraso. O resultado terá uma grande magnitude quando as duas séries forem qualitativamente semelhantes ou forem "correlacionadas" umas com as outras. É semelhante à forma como um produto interno de dois vetores é maior quando os dois vetores são apontados na mesma direção.
O problema com os dados que você mostrou é que (pelo menos para os trechos que podemos ver) não parece haver muita semelhança na forma. Não há atraso que você possa aplicar a um dos sinais para que se pareça com o outro, que é exatamente o que você está fazendo calculando a correlação cruzada entre eles.
Há casos em que a correlação cruzada é útil, no entanto. Digamos que seu segundo sinal foi realmente uma versão com alteração de tempo do original, mesmo com algum ruído adicional adicionado:
Agora não está claro imediatamente que os dois sinais estão relacionados por um atraso de tempo. No entanto, se fizermos a correlação cruzada, obtemos:
que mostra um pico no atraso correto de 200 amostras. A correlação pode ser uma ferramenta útil para determinar o atraso, quando aplicada a conjuntos de dados que contêm o tipo certo de similaridade.
fonte
Com base na sugestão de Muhammad, tentei fazer um script do Matlab. No entanto, não sou capaz de deduzir se ele constrói uma distribuição gaussiana com base nas variações e, em seguida, faz uma estimativa do KDE ou executa uma estimativa do KDE com suposição gaussiana.
Também é difícil inferir como ele traduz o tempo de compensação do KDE no domínio do tempo. Aqui está a minha tentativa. Qualquer usuário interessado em usar o script é livre e atualiza a versão aprimorada, se possível.
fonte