Pergunta

O FAQ Matlab descreve um método de uma linha para encontrar os Maximas locais:

index = find( diff( sign( diff([0; x(:); 0]) ) ) < 0 );

Mas eu acredito que isso só funciona se os dados é mais ou menos suave. Suponha que você tenha dados que salta para cima e para baixo em pequenos intervalos, mas ainda tem alguns Maximas locais aproximados. Como você vai encontrar esses pontos? Você poderia dividir o vetor em n peças e encontrar o maior valor não na borda de cada um, mas deve haver uma solução mais elegante e mais rápido.

A solução one-line seria ótimo também.

Editar: Eu estou trabalhando com imagens biológicas ruidosos que estou tentando dividir em seções distintas.

Foi útil?

Solução

Dependendo do que você quer, é frequentemente útil para filtrar os dados ruidosos. Dê uma olhada na MEDFILT1 , ou usando CONV juntamente com FSPECIAL . Na segunda abordagem, você provavelmente vai querer usar o 'mesmo' argumento para CONV e um filtro 'Gaussian' criado por FSPECIAL.

Depois de ter feito a filtragem, alimentá-lo através do maxima finder.

EDIT: runtime complexidade

Digamos que o vetor de entrada tem comprimento X eo comprimento do kernel filtro é K.

O filtro mediano pode trabalhar, fazendo uma espécie de inserção em execução, por isso deve ser O (X K + K log K). Eu não olhei o código fonte e outras implementações são possíveis, mas basicamente deve ser O (X K).

Quando K é pequena, conv utiliza uma O-linear para a frente (X * K) algoritmo. Quando X e K são quase os mesmos, então é mais rápido usar um jejum transformada de Fourier. Que a execução é O (X log X + K log K). Matlab é inteligente o suficiente para escolher automaticamente o algoritmo certo dependendo dos tamanhos de entrada.

Outras dicas

Eu não tenho certeza que tipo de dados que você está lidando, mas aqui está um método que usei para o processamento de dados de fala que poderiam ajudá-lo a localizar máximos locais. Ele usa três funções do Processing Toolbox sinal: HILBERT , MANTEIGA , e FILTFILT .

data = (...the waveform of noisy data...);
Fs = (...the sampling rate of the data...);
[b,a] = butter(5,20/(Fs/2),'low');  % Create a low-pass butterworth filter;
                                    %   adjust the values as needed.
smoothData = filtfilt(b,a,abs(hilbert(data)));  % Apply a hilbert transform
                                                %   and filter the data.

Você, então, realizar o seu constatação maxima em smoothData . O uso de HILBERT primeiro cria um envelope positivo sobre os dados, então FILTFILT usa os coeficientes de filtro a partir de manteiga de filtro passa-baixo o envelope de dados.

Para um exemplo de como esse processamento funciona, aqui estão algumas imagens que mostram os resultados de um segmento do discurso gravado. A linha azul é o sinal de voz original, a linha vermelha representa a envelope (obtido utilizando HILBERT), e a linha verde representa o resultado filtrado de passagem baixa. A figura inferior é um zoom na versão do primeiro.

text alt

algo aleatório para tentar:

Esta foi uma ideia aleatória eu tive no início ... você poderia tentar repetir o processo encontrando os Maximas dos Maximas:

index = find(diff(sign(diff([0; x(:); 0]))) < 0);
maxIndex = index(find(diff(sign(diff([0; x(index); 0]))) < 0));

No entanto, dependendo da relação sinal-ruído, seria claro quantas vezes isso precisa ser repetido para obter os máximos locais que você está interessado. É apenas uma opção aleatória não-filtragem para tentar. =)

MAXIMA ENCONTRAR:

Apenas no caso de você estiver curioso, outro de uma linha algoritmo de encontrar maxima que eu vi (em adição ao que listadas) é:

index = find((x > [x(1) x(1:(end-1))]) & (x >= [x(2:end) x(end)]));

Se os dados salta para cima e para baixo muito, então a função terá muitos maxima local. Então, eu estou supondo que você não quer encontrar todos os máximos locais. Mas o que é seu critério para que um máximo local é? Se você tem um critério, então pode-se projetar um schem ou algoritmo para isso.

Eu acho que agora que talvez você deve aplicar um filtro low-pass aos seus dados em primeiro lugar, e em seguida, encontrar os máximos locais. Embora as posições da máximos locais após a filtragem pode não corresponder exactamente aos antes.

Existem duas maneiras de ver esse problema a. Pode-se olhar para isto como essencialmente um problema de alisamento, usando uma ferramenta de filtragem para suavizar os dados, só depois de interpolar usando alguma variedade de interpolação, talvez uma spline de interpolação. Encontrar um máximo local de uma spline de interpolação é uma coisa bastante fácil. (Note que você deve geralmente usar um verdadeiro ranhura aqui, não uma interpolação pchip. Pchip, o método utilizado quando especificar uma interpolação "cúbico" em interp1, não vai localizar com precisão um minimizador local que cai entre dois pontos de dados).

A outra abordagem a esse problema um é um que eu tendem a preferir. Aqui se usa um modelo de mínimos quadrados spline para tanto suavizar os dados e produzir um approximant em vez de uma interpolação. Tal quadrados ranhura menos, tem a vantagem de permitir ao usuário uma grande quantidade de controle para introduzir os seus conhecimentos sobre o problema no modelo. Por exemplo, muitas vezes, o cientista ou engenheiro tem informações, como monotonicity, sobre o processo em estudo. Isso pode ser construído em um modelo de mínimos quadrados spline. Outra, opção relacionada é usar uma spline suavização. Eles também podem ser construídos com regularização restrições construído para eles. Se você tiver a caixa de ferramentas ranhura, então spap2 será de alguma utilidade para ajustar um modelo spline. Então fnmin vai encontrar um minimizador. (Um maximizador é facilmente obtido a partir de um código de minimização.)

esquemas de suavização que empregam métodos de filtragem são geralmente mais simples quando os pontos de dados estão igualmente espaçados. espaçamento desigual pode empurrar para os mínimos quadrados de spline modelo. Por outro lado, a colocação de nó pode ser um problema em praças estrias menos. Meu ponto em tudo isso é para sugerir que qualquer abordagem tem mérito, e podem ser feitas para produzir resultados viáveis.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top