2014-07-05 33 views
6

Hi entuzjastów pytona!SciPy medfilt nieprawidłowy wynik

Obecnie pracuję z filtrowaniem sygnału do celów badawczych i postanowiłem użyć SciPy. Nic specjalnego, tylko automatyzacja rutynowej pracy.

Więc tutaj jest kod

from scipy.signal import medfilt 
print(medfilt([2,6,5,4,0,3,5,7,9,2,0,1], 5)) 

Ale sprawa jest taka, że ​​wrócił sequense obliczana jest źle

SciPy: [ 2. 4. 4. 4. 4. 4. 5. 5. 5. 2. 1. 0.] 
Me : [ 5. 4.5 4. 4. 4. 4. 5. 5. 5. 2. 1.5 1.] 

Wydaje się, że twórcy pakietu pomieszane jeden szczegół. Kiedy apertura (jądro pod względem SciPy) jest większa niż okno do analizy, istnieje kolejna zasada filtrowania.

Na przykład z kernel=5 filtrowany podsekwencja [2, 6, 5] ma medianę 5, a nie 2, ponieważ obliczono SciPy, prawda? I w ten sam sposób, jeśli mediana wynosi dla podsekwencji kernel=5, musimy przyjąć średnią między nimi, więc mediana wynosi 4,5.

Czy ktoś może mi wyjaśnić, kto ma odpowiedni wynik w tej sprawie?

Odpowiedz

13

Wierzę, że zarówno ty, jak i SciPy mają poprawne wyniki. Różnica polega na tym, co dzieje się na granicach, ale wierzę, że zarówno ty, jak i SciPy dokonaliście ważnych wyborów.

Pytanie brzmi: Co należy zrobić, gdy okno przesuwne znajduje się na krawędziach i nie ma ważnych danych do wypełnienia okna przesuwnego.

Zdecydowałeś się wziąć medianę ważnej części okna przesuwnego, co ma sens, ale może dodać pewne odchylenie, ponieważ twoje punkty brzegowe są nadreprezentowane w porównaniu do wszystkich innych punktów.

SciPy zamiast tego zdecydował się wydłużyć sygnał przy każdej krawędzi, wypełniając zera. Tak więc, na granicach, scipy zasadniczo obliczania

>>> np.median([0, 0, 2, 6, 5]) 
2.0 
>>> np.median([0, 2, 6, 5, 4]) 
4.0 
>>> np.median([9, 2, 0, 1, 0]) 
1.0 
>>> np.median([2, 0, 1, 0, 0]) 
0.0 

powód dlaczego scipy robi to prawie na pewno prędkość podobne: to jest zoptymalizowany pod kątem robi to samo wiele razy, i to jest o wiele łatwiejsze do optymalizacji median dla cała pęczka tablic złożonych z 5 elementów niż w celu zoptymalizowania jej dla całej wiązki tablic złożonych z 5 elementów, a także dwóch tablic złożonych z 4 elementów i dwóch tablic złożonych z trzech elementów. Z całą pewnością można argumentować, że nie powinien on zawierać zer, lecz wartości brzegowe, ale należy zauważyć, że żadna strategia graniczna nie będzie idealna; idealny sposób radzenia sobie z problemami granic zależy od konkretnego sygnału.

Jeśli widzisz Wikipedia's description of median filters, rozciągają one sygnał na każdej krawędzi, wypełniając go wartością na krawędziach, co również wydaje się uzasadnione. Zwracają również uwagę na te trzy inne sposoby radzenia sobie z problemami brzegowymi:

  • Unikaj przetwarzania granic, z przycięciem granicy sygnału lub później.
  • Pobieranie wpisów z innych miejsc w sygnale. W przypadku obrazów można wybrać na przykład wpisy z daleko poziomej lub pionowej granicy.
  • Zmniejszenie okna w pobliżu granic, tak aby każde okno było pełne (tak jak zostało zrobione.)

W końcu naprawdę trzeba wypróbować różne opcje i zobaczyć, co działa najlepiej dla sygnału. Podstawowym założeniem tego rodzaju filtrowania jest to, że twój sygnał będzie dość duży, a kwestia graniczna nigdy nie powinna być tak krytyczna (ponieważ większość sygnału nie istnieje na granicy). Byłoby miło, gdyby SciPy pozwoliło ci wybrać, co powinien robić na granicach!

+0

Wystarczy rozwinąć trochę na tej odpowiedzi, którzy szukają alternatywnych tocznych funkcji mediany może zajrzeć do: pandy toczenia mediany: http://pandas.pydata.org/pandas-docs/stable/computation.html# ruchome statystyki-chwile i scipy.ndimage: http://docs.scipy.org/doc/scipy-0.15.1/reference/generated/scipy.ndimage.filters.median_filter.html – ConnectedSystems