Thursday 14 December 2017

Przenoszenie średni filtr c kod źródła


Czy możliwe jest zaimplementowanie średniej ruchomej w C bez potrzeby okna z próbkami, które mogę zoptymalizować nieco, wybierając rozmiar okna, który ma potęgę dwóch, aby umożliwić przesunięcie bitowe zamiast dzielenia, ale niewymagające bufor byłby miły. Czy istnieje sposób wyrażenia nowego wyniku średniej kroczącej tylko jako funkcję starego wyniku i nowej próbki Zdefiniuj przykładową średnią ruchomą w oknie 4 próbek: Dodaj nową próbkę e: Średnia ruchoma może zostać zaimplementowana rekurencyjnie , ale do dokładnego obliczenia średniej ruchomej trzeba zapamiętać najstarszą próbkę wejściową w sumie (tj. a w twoim przykładzie). Dla długości N średniej ruchomej obliczamy: gdzie yn jest sygnałem wyjściowym, a xn jest sygnałem wejściowym. Eq. (1) może być napisany rekurencyjnie jako Więc zawsze musisz zapamiętać próbkę xn-N w celu obliczenia (2). Jak wskazał Conrad Turner, można zamiast tego użyć (nieskończenie długiego) okna wykładniczego, które pozwala obliczyć wyjście tylko z poprzedniego wyjścia i bieżącego wejścia: ale nie jest to standardowa (nieważona) średnia ruchoma, ale wykładniczo ważona średnia ruchoma, gdzie próbki w przeszłości mają mniejszą masę, ale (przynajmniej teoretycznie) nigdy niczego nie zapominasz (ciężary stają się mniejsze i mniejsze dla próbek daleko w przeszłości). Zaimplementowałem średnią ruchomą bez pamięci pojedynczych elementów dla programu do śledzenia GPS, który napisałem. Zaczynam od 1 próbki i dzielę przez 1, aby uzyskać aktualną średnią. Następnie dodaję próbkę anothe i dzielę przez 2 do aktualnej avg. To trwa, dopóki nie osiągnę długości średniej. Za każdym razem dodawam nową próbkę, otrzymuję średnią i usuwam tę średnią z całości. Nie jestem matematykiem, ale wydawało mi się, że to dobry sposób. Pomyślałem, że to zmieni żołądek prawdziwego matematyka, ale okazuje się, że jest to jeden z akceptowanych sposobów robienia tego. I działa dobrze. Pamiętaj tylko, że im większa długość, tym wolniej podążasz za tym, co chcesz obserwować. To może nie mieć większego znaczenia, ale gdy podążamy za satelitami, jeśli jesteś wolny, trasa może być daleko od aktualnej pozycji i będzie wyglądać źle. Możesz mieć przerwę między sob i końcowymi kropkami. Wybrałem długość 15 aktualizacji 6 razy na minutę, aby uzyskać odpowiednie wygładzenie i nie za bardzo oddalić się od faktycznej pozycji siedzącej z wygładzonymi kropkami. odpowiedziała 16 listopada 16 o 23:03 zainicjalizuj całość 0, count0 (za każdym razem, gdy zobaczysz nową wartość Następnie jedno wejście (scanf), jedno dodaj totalnewValue, jeden przyrost (count), jedna średnia dzieląca (totalcount) Byłaby to średnia ruchoma ponad wszystkie wejścia Aby obliczyć średnią tylko z ostatnich 4 wejść, wymagałyby 4 zmiennych wejściowych, być może skopiowania każdego wejścia do starszej zmiennej wejściowej, a następnie obliczenia nowej średniej ruchomej jako sumy 4 zmiennych wejściowych, podzielonej przez 4 (prawe przesunięcie 2 byłoby dobrze, jeśli wszystkie dane wejściowe były dodatnie, aby uzyskać średnią obliczoną odpowiedź 3 lutego 15 o 4:06 To faktycznie obliczyć całkowitą średnią, a NIE średnią ruchomą. Jak liczba staje się większa wpływ nowej próbki wejściowej staje się znikały małe ndash Hilmar lutego 3 15 at 13:53 Twoja wymiana stosów w 2017 r. Inc. Wiem, że jest to możliwe dzięki zwiększeniu liczby na: Ale naprawdę chciałbym uniknąć stosowania boost. Mam google i nie znalazłem żadnych odpowiednich lub czytelnych przykładów. Zasadniczo chcę śledzić w ruchu średnia z ciągłego strumienia strumienia liczb zmiennoprzecinkowych z wykorzystaniem najnowszych 1000 liczb jako próbki danych. Jaki jest najłatwiejszy sposób, aby to osiągnąć? Eksperymentowałem z użyciem okrągłej tablicy, wykładniczej średniej kroczącej i prostszej średniej ruchomej, i odkryłem, że wyniki z okrągłej macie najlepiej pasują do moich potrzeb. Zapytany 12 czerwca 12 o 4:38 Jeśli twoje potrzeby są proste, możesz po prostu spróbować użyć wykładniczej średniej kroczącej. Mówiąc prościej, tworzysz zmienną akumulatora, a ponieważ twój kod wygląda na każdą próbkę, kod aktualizuje akumulator o nową wartość. Wybierasz stałą alfa, która jest pomiędzy 0 a 1, i obliczasz to: Musisz tylko znaleźć wartość alfa, gdzie efekt danej próbki trwa tylko około 1000 próbek. Hmm, nie jestem właściwie pewien, czy ci to pasuje, teraz, kiedy go tu umieściłem. Problem polega na tym, że 1000 to dość długie okno dla wykładniczej średniej kroczącej Nie jestem pewien, czy istnieje alfa, które rozłożyłoby średnią z ostatnich 1000 liczb, bez dolnego limitu w obliczeniach zmiennoprzecinkowych. Ale jeśli chcesz mieć mniejszą średnią, na przykład około 30 numerów, jest to bardzo łatwy i szybki sposób na zrobienie tego. odpowiedź 12 czerwca 12 o 4:44 1 na twój post. Wykładnicza średnia ruchoma może pozwolić na zmienną alfa. Dzięki temu można go wykorzystać do obliczenia średniej podstawy czasu (na przykład bajtów na sekundę). Jeśli czas od ostatniej aktualizacji akumulatora jest dłuższy niż 1 sekunda, zezwalasz alfa na 1.0. W przeciwnym razie możesz pozwolić na alfa (usecs od ostatniej aktualizacji1000000). ndash jxh 12 czerwca 12 o 6:21 Zasadniczo chcę śledzić średnią ruchomą ciągłego strumienia strumienia liczb zmiennoprzecinkowych z wykorzystaniem najnowszych 1000 liczb jako próbki danych. Zauważ, że poniższe aktualizacje aktualizują sumę jako elementy dodane z powrotem, unikając kosztownego przejścia przez O (N) w celu obliczenia sumy - potrzebnej dla średniej - na żądanie. Total otrzymuje inny parametr od T do obsługi np. użycie długiej długości, gdy suma wynosi 1000 długich s, int dla char s lub double do total float s. Jest to trochę wadliwe, ponieważ liczba poprawek może przekroczyć INTMAX - jeśli chcesz, możesz użyć długiej długości bez znaku. lub użyj dodatkowego elementu danych typu bool, aby zarejestrować, kiedy pojemnik jest pierwszy wypełniony, podczas gdy liczba próbkowania w cyklu wokół tablicy (najlepiej wtedy przemianowana na coś nieszkodliwego jak pos). odpowiedź 12 czerwca 12 o 5:19 zakłada się, że quotvoid operator (T sample) quot jest w rzeczywistości quotvoid operatorltlt (T sample) quot. ndash oPless cze 8 14 o 11:52 o Bez ahhh. dobrze zauważył. faktycznie miałem na celu unieważnienie operatora () (próbka T), ale oczywiście można użyć dowolnej notacji, którą lubisz. Naprawię, dzięki. ndash Tony D Jun 8 14 at 14: 27Mean filter, or average filter Kategoria. Cyfrowe przetwarzanie sygnału i przetwarzania obrazu (DSP i DIP). Abstrakcyjny. Artykuł jest praktycznym przewodnikiem dla średniego filtra lub średniego zrozumienia i implementacji filtra. Artykuł zawiera teorię, kod źródłowy C, instrukcje programowania i przykładową aplikację. 1. Wprowadzenie do filtra średniego lub średni filtr Średni filtr. lub średni filtr to okienkowany filtr klasy liniowej, który wygładza sygnał (obraz). Filtr działa jako dolnoprzepustowy. Podstawową zasadą kryjącą się za filtrem jest to, że dowolny element sygnału (obrazu) przyjmuje średnią w swoim sąsiedztwie. Aby zrozumieć, jak to się robi w praktyce, zacznijmy od pomysłu okna. 2. Okno filtru lub maska ​​Wyobraźmy sobie, że powinieneś przeczytać literę i to, co widzisz w tekście ograniczonym przez otwór w specjalnym szablonie w ten sposób. Zatem wynikiem czytania jest dźwięk t. OK, odczytajmy list ponownie, ale przy pomocy innego szablonu: Teraz wynikiem czytania t jest dźwięk 240. Zróbmy trzecią próbę: Teraz czytasz literę t jako dźwięk 952. Co się tutaj dzieje Aby to powiedzieć w języku matematycznym wykonujesz operację (czytanie) nad elementem (litera t). A wynik (dźwięk) zależy od sąsiedztwa elementu (litery obok t). A ten szablon, który pomaga podnieść element sąsiedztwa, to okno Tak, okno to tylko szablon lub wzór, za pomocą którego wybierasz element sąsiedztwa 0151 zestaw elementów wokół danego 0151, aby pomóc Ci podjąć decyzję. Inną nazwą okna filtra jest maska ​​0151 to szablon, który ukrywa elementy, na które nie zwracamy uwagi. W naszym przykładzie element, na którym operujemy, znajduje się po lewej stronie okna, w praktyce jednak jego zwykła pozycja jest środkiem okna. Zobaczmy kilka przykładów okien. W jednym wymiarze. Rys. 4. Okno lub maska ​​wielkości 5 w 1D. W dwóch wymiarach. Ryc. 5. Okno lub maska ​​wielkości 3 x 3 w 2D. W trzech wymiarach. Pomyśl o budowaniu. A teraz mdash o pokoju w tym budynku. Pokój jest jak okno 3D, które wycina pewną podprzestrzeń z całej przestrzeni budynku. Możesz znaleźć przetwarzanie obrazu 3D w objętości okna (voxel). 3. Zrozumienie średniego filtru Zobaczmy teraz, jak podzielić średnią na elementy sąsiedztwa. Formuła to proste sumowanie elementów 0151 i podzielenie sumy przez liczbę elementów. Na przykład obliczmy średnią dla przypadku, przedstawioną na rys. 7. Ryc. 7. Średnia. I to wszystko. Tak, po prostu przefiltrowaliśmy sygnał 1D przez filtr średni. Spróbujmy wznowić i zapisz instrukcje krok po kroku dotyczące przetwarzania przez filtr średni. Średni filtr lub algorytm filtru średniego: Umieść okno nad elementem Zrób średnie sumowanie elementów 0151 i podziel sumę przez liczbę elementów. Teraz, gdy mamy już algorytm, nadszedł czas, aby napisać kod mdash, przejdźmy do programowania. 4. 1D programowanie filtrów W tym rozdziale rozwijamy filtr 1D z oknem o rozmiarze 5. Niech jako sygnał wejściowy mamy sygnał 1D o długości N. Pierwszym krokiem jest umieszczenie okna 0151, które robimy poprzez zmianę indeksu elementu wiodącego: Zwróć uwagę, że zaczynamy od trzeciego elementu i kończymy na ostatnim, ale dwóch. Problem polega na tym, że nie możemy zacząć od pierwszego elementu, ponieważ w tym przypadku lewa część okna filtra jest pusta. Omówimy poniżej, jak rozwiązać ten problem. Drugim krokiem jest uzyskanie średniej, ok: Zapiszmy teraz algorytm jako funkcję: Element typu można zdefiniować jako: 5. Traktowanie krawędzi Dla wszystkich filtrów okien istnieje pewien problem. To jest obróbka krawędzi. Jeśli umieścisz okno na pierwszym (ostatnim) elemencie, lewa (prawa) część okna będzie pusta. Aby wypełnić lukę, sygnał należy wydłużyć. W przypadku filtra średniego dobrym pomysłem jest symetryczne rozciągnięcie sygnału lub obrazu, w ten sposób: przed przekazaniem sygnału do naszej funkcji filtra średniego sygnał powinien zostać przedłużony. Zapiszmy opakowanie, które sprawia, że ​​wszystkie przygotowania. Jak widać, nasz kod uwzględnia pewne praktyczne problemy. Przede wszystkim sprawdzamy nasze parametry wejściowe Sygnał 0151 nie powinien mieć wartości NULL, a długość sygnału powinna być dodatnia: Krok drugi 0151 sprawdzamy przypadek N1. Ta sprawa jest wyjątkowa, ponieważ do rozbudowy potrzebujemy co najmniej dwóch elementów. Dla sygnału o długości 1 elementu wynikiem jest sam sygnał. Jak również należy zwrócić uwagę, nasz filtr średniej działa na miejscu, jeśli wynik parametru wynikowego jest NULL. Teraz przydzielmy pamięć do rozszerzenia sygnału. I sprawdź alokację pamięci.

No comments:

Post a Comment