Próbuję zrobić filtr średniej ruchomej w języku C, dostosowałem program matlab, który działa poprawnie, wejście mojego filtra to archiwum. pcm (sygnał dźwiękowy zamiatania), problemem jest dla mnie archiwum wyjściowe ruchu średnia w języku C, wyjście idzie źle, sygnał tylko maleje wraz z upływem czasu (nie filtter). Poniżej kodu C: Obraz poniżej jest wynikiem programu matlab do średniej ruchomej o długości 16: Ten obraz jest wynikiem w języku C ze średnią ruchomą o długości 16: Ktoś wie, co może być Poniżej kodu w matlab, który Ive adaptacja: Aktualizacja 1 (Korzystanie z odpowiedzi powyżej): Początek sygnału nadal z zakłóceniami, ale od środka do końca sygnału jest poprawnie. Pobierz movAv. m (zobacz również movAv2 - zaktualizowana wersja umożliwiająca ważenie) Opis Matlab obejmuje funkcje zwane movavg i tsmovavg (średnia ruchoma serii czasowej) w Przyborniku finansowym, movAv ma na celu odtworzenie ich podstawowej funkcjonalności. Kod tutaj stanowi dobry przykład zarządzania indeksami wewnątrz pętli, co może być mylące na początek. Rozmyślnie trzymałem kod krótki i prosty, aby ten proces był jasny. movAv wykonuje prostą średnią ruchomą, która może być używana do odzyskiwania hałaśliwych danych w niektórych sytuacjach. Działa poprzez przyjmowanie średniej wartości wejściowej (y) na przesuwanym oknie czasowym, którego rozmiar jest określony przez n. Im większy n, tym większa jest ilość efektu wygładzania efektu n względem długości wektora wejściowego y. i skutecznie (no, w pewnym sensie) tworzy filtr dolnoprzepustowy - patrz rozdział Przykłady i zagadnienia. Ponieważ ilość wygładzania zapewniona przez każdą wartość n jest względna względem długości wektora wejściowego, zawsze warto testować różne wartości, aby zobaczyć, co jest właściwe. Pamiętaj również, że n punktów są tracone po każdej średniej, jeśli n wynosi 100, pierwsze 99 punktów wektora wejściowego nie zawiera wystarczających danych dla średniej wartości 100pt. Można to uniknąć poprzez ułożenie średnich, na przykład poniższy kod i wykres porównują różne średnie okna długości. Zwróć uwagę, jak gładki 1010pt jest porównywany z pojedynczą średnią 20pt. W obu przypadkach 20 punktów danych są tracone w całości. Utwórz xaxis x1: 0.01: 5 Wygeneruj szum hałasuReps 4 repmat szumu (randn (1, ceil (numel (x) noiseReps)), noiseReps, 1) noise shape (noise, 1, length (noise) noiseReps) Generuj ydata noise yexp ( x) 10noza (1: długość (x)) Od średnich: y2 movAv (y, 10) 10 pkt y3 movAv (y2, 10) 1010 pkt y4 movAv (y, 20) 20 pkt y5 movAv (y, 40) 40 pkt y6 movAv (y, 100) 100 pkt Opis wykresu wykresu (x, y, y2, y3, y4, y5, y6) (dane surowe, średnia ruchoma 10pt, 1010pt, 20pt, 40pt, 100pt) xlabel (x) ylabel y) tytuł (Porównanie średnich kroczących) wartość wyjściowa funkcji movAv. m movAv (y, n) Pierwsza linia definiuje nazwę funkcji, wejścia i wyjścia. Wejście x powinno być wektorem danych do wykonania średniej na, n powinna być liczbą punktów do wykonania średniej ponad wyjście będzie zawierać uśrednione dane zwracane przez funkcję. Prealocate output output NaN (1, numel (y)) Znajdź punkt środkowy rundy midpoint (n2) Główna praca funkcji odbywa się w pętli for, ale przed rozpoczęciem przygotowuje się dwie rzeczy. Po pierwsze, wyjście jest wstępnie alokowane jako NaN, to służyło dwóm celom. Po pierwsze, wstępna alokacja jest ogólnie dobrą praktyką, ponieważ redukuje ona żonglowanie pamięcią Matlaba, a po drugie bardzo ułatwia umieszczanie uśrednionych danych na wyjściu o takim samym rozmiarze jak wektor wejściowy. Oznacza to, że te same xaxis mogą być później użyte dla obu, co jest wygodne do wykreślania, alternatywnie NaN można później usunąć w jednym wierszu kodu (wyjście wyjściowe (Zmienna midPoint będzie używana do wyrównania danych w wektorze wyjściowym. n 10, 10 punktów zostanie utraconych, ponieważ dla pierwszych 9 punktów wektora wejściowego nie ma wystarczającej ilości danych, aby uzyskać średnią z 10 punktów, ponieważ dane wyjściowe będą krótsze niż dane wejściowe, muszą być odpowiednio wyrównane. być użyte, aby na początku i na końcu utracić taką samą ilość danych, a dane wejściowe są utrzymywane w zgodności z danymi wyjściowymi przez bufory NaN utworzone podczas wstępnego przydzielania danych wyjściowych dla 1: length (y) - n Znajdź zakres indeksów, aby uzyskać średnią over (a: b) bana Obliczyć średnią wartość wyjściową (amidPoint) średnia (y (a: b)) koniec W pętli for, średnia jest brana na każdy kolejny segment wejścia. Pętla będzie działać dla a., która jest zdefiniowane jako 1 do długości wejścia (y), minus dane, które zostaną utracone (n).Jeżeli wejście jest równe 100 punktom ng i n wynosi 10, pętla będzie działać z (a) od 1 do 90. Oznacza to, że pierwszy indeks segmentu ma być uśredniony. Drugi indeks (b) jest po prostu-1. Więc na pierwszej iteracji, a1. n10. więc b 11-1 10. Pierwsza średnia jest pobierana przez y (a: b). lub x (1:10). Średnia tego segmentu, który jest pojedynczą wartością, jest przechowywana w wynikach w indeksie amidPoint. lub 156. Podczas drugiej iteracji, a2. b 210-1 11. więc średnia jest brana pod x (2:11) i zapisywana na wyjściu (7). W ostatniej iteracji pętli dla wejścia o długości 100, a91. b 9010-1 100, więc średnia jest brana na x (91: 100) i zapisywana na wyjściu (95). Pozostawia to wynik w sumie n (10) wartości NaN na indeksie (1: 5) i (96: 100). Przykłady i rozważania Średnie kroczące są przydatne w niektórych sytuacjach, ale nie zawsze są najlepszym wyborem. Oto dwa przykłady, w których niekoniecznie są one optymalne. Kalibracja mikrofonu Ten zestaw danych reprezentuje poziomy każdej częstotliwości wytwarzanej przez głośnik i rejestrowane przez mikrofon ze znaną reakcją liniową. Moc wyjściowa głośnika zmienia się z częstotliwością, ale możemy skorygować tę zmianę danymi kalibracyjnymi - moc wyjściową można regulować na poziomie, aby uwzględnić fluktuacje w kalibracji. Zwróć uwagę, że surowe dane są hałaśliwe - oznacza to, że niewielka zmiana częstotliwości wydaje się wymagać dużego, niepoprawnego, zmian poziomu w celu uwzględnienia. Czy jest to realistyczne? Czy jest to produkt środowiska nagrywającego? Rozsądne w tym przypadku jest zastosowanie średniej ruchomej, która wygładza krzywą częstotliwości, aby uzyskać krzywą kalibracji, która jest nieco mniej błędna. Ale dlaczego nie jest to optymalne w tym przykładzie? Więcej danych byłoby lepsze - uśrednione wielokrotne kalibracje zniszczyłyby hałas w systemie (tak długo jak jego losowe) i zapewnią krzywiznę z mniejszą ilością subtelnych szczegółów. Średnia ruchoma może tylko przybliżać tę sytuację i może usunąć niektóre z wyższych częstotliwości i szczytów z krzywej, która naprawdę istnieje. Sine waves Wykorzystanie średniej ruchomej na falach sinusoidalnych podkreśla dwa punkty: Ogólny problem polegający na wybraniu rozsądnej liczby punktów do osiągnięcia średniej. To proste, ale istnieją skuteczniejsze metody analizy sygnału niż uśrednione sygnały oscylacyjne w dziedzinie czasowej. Na tym wykresie oryginalna fala sinusoidalna jest naniesiona na niebiesko. Hałas jest dodawany i wykreślany jako krzywa pomarańczowa. Średnia ruchoma jest wykonywana z różną liczbą punktów, aby sprawdzić, czy można odzyskać oryginalną falę. 5 i 10 punktów daje rozsądne wyniki, ale nie usuwaj hałasu w całości, gdzie jako większa liczba punktów zaczynają tracić szczegóły amplitudy, ponieważ średnia rozciąga się na różne fazy (pamiętaj, że fala oscyluje wokół zera, a średnia (-1 1) 0) . Alternatywnym podejściem byłoby skonstruowanie filtra dolnoprzepustowego, niż można zastosować do sygnału w dziedzinie częstotliwości. Nie będę wchodził w szczegóły, ponieważ wykracza poza zakres tego artykułu, ale ponieważ szum jest znacznie większą częstotliwością niż częstotliwość podstawowa fal, w tym przypadku byłoby dość łatwo skonstruować filtr dolnoprzepustowy, niż usunąć wysoką częstotliwość hałas. Musię obliczyć średnią ruchomą w serii danych, w pętli for. Muszę uzyskać średnią kroczącą powyżej N9 dni. Tablica Im computing in to 4 serie 365 wartości (M), które same są wartościami średnimi innego zestawu danych. Chcę wykreślić średnie wartości moich danych z średnią ruchoma w jednym wykresie. I googled nieco o ruchu średnich i conv polecenia i znalazłem coś, co próbowałem wdrożyć w moim kodzie .:. Więc w zasadzie obliczyć moje średnie i spróbować to z (zła) średnia ruchoma. Wybrałem wartość wts tuż przy matematyce, więc jest to błędne. (źródło: mathworks. nlhelpeconmoving-average-trend-estimation. html) Mój problem polega jednak na tym, że nie rozumiem, co to jest. Ktoś mógłby wyjaśnić, jeśli ma coś wspólnego z wagami wartości: w tym przypadku jest to nieważne. Wszystkie wartości są ważone tak samo. A jeśli robię to całkowicie złe, mogę uzyskać pomoc z nim moje najszczersze podziękowania. pytanie 23 września 14 o 19:05 Korzystanie z conv to doskonały sposób na wprowadzenie średniej kroczącej. W kodzie, którego używasz, wts jest tym, ile ważysz każdej wartości (jak zgadłeś). suma tego wektora powinna zawsze być równa. Jeśli chcesz równomiernie wyważyć każdą wartość i zrobić filtr rozmiaru N, to chcesz to zrobić Używając prawidłowego argumentu w conv będzie powodować mniejsze wartości Ms niż masz w M. Użyj tego samego, jeśli nie masz nic przeciwko efektom zero padding. Jeśli masz zestaw narzędzi do przetwarzania sygnałów, możesz użyć cconv, jeśli chcesz wypróbować średnią ruchomą kołową. Coś, co chcesz przeczytać dokumentację conv i cconv, aby uzyskać więcej informacji, jeśli już nie masz. Możesz użyć filtru, aby znaleźć średnią ruchu bez użycia pętli for. W tym przykładzie znajdziemy średnią bieżącej wektora 16-elementowego, przy użyciu rozmiaru okna 5. 2) gładka jako część przybornika do dopasowywania krzywych (która jest dostępna w większości przypadków) yy gładka (y) wygładza dane wektora kolumny y przy użyciu filtra średniej ruchomej. Wyniki są zwracane w wektorze kolumny yy. Domyślna rozpiętość średniej kroczącej wynosi 5. Podwójna średnia ruchoma Opis filtru DoubleMovingAverageFilter implementuje filtr o podwójnej średniej ruchomej z niskim przebiegiem. DoubleMovingAverageFilter jest częścią modułów preprocessingu. Przykład sygnału (losowy szum fali sinusoidalnej) przefiltrowany za pomocą filtra średniej ruchomej. Czerwony sygnał to hałas sygnału pierwotnego, zielony sygnał jest filtrowanym sygnałem przy użyciu średniej ruchomych filtrów o wielkości okna 5, a niebieski sygnał jest filtrowanym sygnałem przy użyciu średniej ruchomych filtrów o rozmiarze okna 20. DoubleMovingAverageFilterExampleImage1. jpg Zalety DoubleMovingAverageFilter jest dobry do usuwania niewielkiej ilości hałasu wysokiej częstotliwości z sygnału N wymiarowego. Wady Główną wadą DoubleMovingAverageFilter jest to, że aby odfiltrować znacznie szumy o wysokiej częstotliwości, rozmiar okna filtra musi być duży. Problem z dużym oknem filtra polega na tym, że wywoła to duże opóźnienie w dowolnym sygnale przechodzącym przez filtr, co może nie być korzystne dla aplikacji działających w czasie rzeczywistym. Jeśli okaże się, że potrzebujesz dużego okna filtra, aby odfiltrować szum wysokiej częstotliwości, a opóźnienie wywołane tym rozmiarem okna nie jest odpowiednie dla aplikacji czasu rzeczywistego, możesz zamiast tego wypróbować filtr dolnoprzepustowy. Przykładowy kod GRT DoubleMovingAverageFilter Przykład Ten przykład demonstruje sposób tworzenia i używania modułu wstępnego przetwarzania GRT DoubleMovingAverageFilter. DoubleMovingAverageFilter implementuje filtr z podwójnie ruchomym filtrem dolnoprzepustowym. W tym przykładzie tworzymy wystąpienie DoubleMovingAverageFilter i używamy go do filtrowania niektórych fałszywych danych, generowanych z przypadkowego szumu fali sinusoidalnej. Sygnał testowy i filtrowane sygnały są następnie zapisywane w pliku (dzięki czemu można wydrukować wyniki w programie Matlab, Excel itd.). W tym przykładzie pokazano, jak: - Utworzyć nową instancję DoubleMovingAverageFilter z określonym rozmiarem okna dla sygnału 1-wymiarowego - Filtruj niektóre dane za pomocą DoubleMovingAverageFilter - Zapisz ustawienia DoubleMovingAverageFilter w pliku - Załaduj ustawienia DoubleMovingAverageFilter z pliku obejmują quotGRT. hquot przy użyciu obszaru nazw GRT int main 40 int argc. const char argv 91 93 41 123 Utwórz nową instancję filtra o podwójnej ruchomej średniej z rozmiarem okna 5 dla sygnału 1 wymiarowego Filtr DoubleMovingAverageFilter 40 5. 1 41 Utwórz i otwórz plik, aby zapisać plik pliku danych fstream. otwórz 40 quotDoubleMovingAverageFilterData. txtquot. fstream. 41 Generuj dane (szum fal sinusoidalnych) i filtruj podwójne x 0 const UINT M 1000 Losowo losowo dla 40 UINT i 0 i lt M i 41 123 double signal sin 40 x 41 losowo. getRandomNumberUniform 40 - 0.2. 0,2 41 podwójnie filtrowany filtr wartości. filtr 40 sygnał 41 plik ltlt sygnał ltlt quot t quot ltlt filterValue ltlt endl x TWOPI double 40 M 41 10 125 Zamknij plik pliku. close 40 41 Zapisz ustawienia filtru w pliku filtra. saveSettingsToFile 40 quotDoubleMovingAverageFilterSettings. txtquot 41 Możemy następnie załadować ustawienia później, jeśli to konieczne, filtrować. loadSettingsFromFile 40 quotDoubleMovingAverageFilterSettings. txtquot 41 return EXITSUCCESS 125 DoubleMovingAverageFilter działa również z dowolnym N-wymiarowym sygnałem: Utwórz nowe wystąpienie DoubleMovingAverageFilter z oknem o rozmiarze 10 dla sygnału trójwymiarowego DoubleMovingAverageFilter filter 40 10. 3 41 Wartość, którą chcesz filtrować wektor lt dane gt podwójne 40 3 41 dane 91 0 93 0. Pobierz wartość z danych czujników 91 1 93 0. Uzyskiwanie wartości z danych czujników 91 2 93 0. Pobieraj wartość z czujnika Filtr wektora sygnału Filtrowanie podwójnie filtremWalue. filtruj 40 danych 41
No comments:
Post a Comment