× Aktuálně z oboru

Vychází Game Ready ovladače pro Far Cry 5 [ clanek/2018040603-vychazi-game-ready-ovladace-pro-far-cry-5/ ]
Celá zprávička [ clanek/2018040603-vychazi-game-ready-ovladace-pro-far-cry-5/ ]

Realizace filtrů FIR a IIR v programovacím jazyce C#

[ http://programujte.com/profil/90-ondrej-karas/ ]Google [ ?rel=author ]       [ http://programujte.com/profil/14523-martin-simecek/ ]Google [ ?rel=author ]       7. 5. 2010       34 748×

S rozvojem digitální techniky a zvláště té počítačové se objevily nové možnosti při zpracování signálů, a to i v oblastech, kde dříve kralovala pouze technika analogová. Jednou z takových oblastí je i filtrace signálů. Základními stavebními kameny jsou filtry FIR a IIR.

Ty se realizují ve velkém množství variant, přesto princip zůstává vždy stejný. Ačkoliv hlavní platformou pro jejich využití jsou digitální signálové procesory a obvody FPGA, jejich principu využívá i velké množství softwaru, ať už profesionálního, či vytvořeného „na koleni“. Ačkoliv v dalším textu předpokládám alespoň minimální znalost z oblasti digitálního zpracování signálů, jistě neškodí si připomenout některé základní vlastnosti digitálních filtrů.

Filtry FIR

Filtry FIR jsou matematicky jednoduše popsatelné filtry, které ale v analogové technice nemají ekvivalent (na rozdíl od filtrů IIR). Jsou tvořeny zpožďovacími linkami, kterých je vždy o 1 méně, než je řád filtru. Musíme si ale říci, že řád filtru FIR v tomto případě není totéž co řád filtru analogového. V digitálním filtru FIR musíme volit řád několikanásobně větší. Za zpožďovacími linkami následují násobičky s koeficienty filtru a součtový člen.

Filtry FIR mají oproti IIR několik výhod. Nemění fázi s ohledem na přenášenou frekvenci signálů a tím jsou vhodné i pro signály s větší šířkou pásma. S tím souvisí i skupinové zpoždění signálu. Jsou také jednodušší na pochopení. Ovšem zásadní nevýhodou je velký počet zpožďovacích linek a násobiček, které obsahují. Navíc, než dojde k plné inicializaci filtru, musíme vyhodit prvních několik vzorků. Pokud tedy chceme použít filtr pro „vyčištění“ naměřených dat, FIR filtr nebude tím pravým.

Filtry IIR

Realizace a matematický popis IIR filtru již nejsou tak jednoduché, jako tomu bylo v předchozím případě. IIR filtr obsahuje i zpětnou vazbu. Oproti FIR filtru ale není třeba tak velkého počtu zpožďovacích linek, a proto je možné jej použít i na kratší data (inicializace není tak dlouhá). Nevýhodou tohoto filtru je závislost fáze výstupního signálu na frekvenci. Nehodí se proto na širokopásmové signály. Naproti tomu filtrování pomalu měřených dat lze IIR filtru svěřit zcela bez obav.

Koeficienty filtrů, ať už FIR, nebo IIR, lze bez problémů spočítat například v Matlabu nebo v jiném k tomu určeném softwaru. Existuje také mnoho zdrojů, kde lze zjistit, jakým způsobem koeficienty odhadnout nebo spočítat. Zdroje jsou uvedeny na konci článku.

Realizace FIR filtru v jazyce C#

Následující zdrojový kód představuje jednu z možností, jak realizovat FIR filtr jazyce C#. Kód je dále komentován.

// aplikuje FIR filtr
public static void ApplyFIR(ArrayList coef, ArrayList x, out ArrayList y)
{
    y = new ArrayList();
    int n_x = x.Count;
    int n_c = coef.Count;

    double[] x_field = new double[n_c];
    double sum = 0;

    // provede konvoluci dat a koeficientu
    for (int a = 0; a < n_x; a++)
    {
        // provadi plneni pole x_field, jehoz polozky se nasobi s koeficienty 1:1
        for (int b = 0; b <= a; b++)
        {                   
            double test = (double)x[a-b];
            if (b <= (n_c - 1)) x_field[b] = test;
        }
        // provadi samotnou MAC operaci (vypocet y(b) )
        sum = 0;
        for (int b = 0; b < n_c; b++)
        {
            sum += x_field[b] * (double)coef[b];
        }
        // ulozeni jednoho y(n)
        y.Add(sum);
    }
}

Vstupními parametry filtru jsou jeho koeficienty „coef“ a vstupní vzorky „x“. Nejprve je vytvořeno pole „y“ pro výstupní vzorky a spočítána velikost vstupních vzorků a velikost koeficientů. Následně je vytvořeno pole „x_field“ o velikosti totožné s velikostí pole koeficientů. V poli „x_field“ bude v každé iteraci filtrační smyčky posloupnost vstupních vzorků posunuta o jeden vzorek směrem k nejmladšímu vzorku. Následným násobením „x_field[b]*coef[b]“ je zajištěno ono násobení vzorků koeficienty uvedené v popisu FIR filtru výše. Po kompletním vynásobení polí „x_field“ a „coef“ jsou součiny sečteny a výsledek uložen do pole „y“. Popsaný proces se nazývá konvoluce.

Uvedený příklad je velmi jednoduchý. Na konec článku jsou doplněny plné zdrojové kódy spolu s ukázkou využití této operace v praxi. Je jasné, že v prostředí C# není možné filtrovat data nějakou zázračnou rychlostí, nicméně pro zpracování dat off-line se to může hodit.

Realizace IIR filtru v jazyce C#

Následující zdrojový kód představuje jednu z možností, jak realizovat IIR filtr jazyce C#. Kód je dále komentován.

// aplikuje IIR filtr
public static void ApplyIIR(double[] coefA, double[] coefB, ArrayList data, out     ArrayList y)
{            
    y = new ArrayList();   // incializace vystupu
    int cn = coefA.Length; // pocet koeficientu fitru, rad filtru = cn-1
    double[] xn = new double[cn]; // pole pro dopredny smer
    double[] yn = new double[cn]; // pole pro zpetny smer
    
    // inicializace dat
    for (int i = 0; i < cn; i++) xn[i] = yn[i] = (double)data[0];

    // vypocet filtru
    for (int i = 0; i < data.Count; i++)
    {
        
        // posuv dat
        for (int ii = 1; ii < cn; ii++)
        {
            xn[cn - ii] = xn[cn - (ii + 1)];
            yn[cn - ii] = yn[cn - (ii + 1)];
        }
        
        // inicializace vypoctu jedne iterace
        xn[0] = (double)data[i];
        yn[0] = 0;

        // dopredny smer = SUM(x_i,b_i)
        for (int ii = 0; ii < cn; ii++)
            yn[0] += coefB[ii] * xn[ii];

        // zpetny smer = SUM(y_i,a_i)
        for (int ii = 1; ii < cn; ii++)
            yn[0] -= coefA[ii] * yn[ii];

        // ulozeni vysledku
        y.Add(yn[0]);
    }
}

Uvedený zdrojový kód je přímým přepisem matematické formulace IIR filtru, uvedené v popisu výše. V první části jsou opět zjištěny délky koeficientů. Protože se předpokládá, že koeficienty pro přímý i zpětný směr mají stejnou délku, počítá se jen první z nich. Následně je inicializována zpožďovací linka. Je vhodné ji inicializovat prvním vzorkem vstupních dat, aby se ve výstupu neprojevila odezva na jednotkový skok.

Poté je již pouze zajišťována správa zpožďovací linky a výpočet dle matematického vzorce uvedeného v definici IIR filtru výše. Nejprve je počítán dopředný směr, poté směr zpětný a výsledek opět uložen do výstupního pole y(n).

Na následujících grafech jsou uvedeny průběhy vstupního a vyfiltrovaného signálu s mezní frekvencí 0,2 fvz. Prvním signálem je vždy Diracův impulz, druhým pak logaritmus vloženým Diracovým impulzem. V případě IIR filtru byl zvolen filtr o 59 koeficientech a také z grafu je jasné, že zpoždění filtru je 59/2 (tedy 29) vzorků. V případě IIR filtru byl zvolen filtr o 4 koeficientech a zpoždění je tedy výrazně menší.

Modře jsou označeny vstupní signály, červeně signály výstupní. 

Závěr

Uvedené grafy potvrzují, že realizace digitálních filtrů v jazyce C# je velice jednoduchou záležitostí. V některém z dalších článků se budeme věnovat filtraci dvourozměrných dat. Tyto metody se často uplatňují pro filtraci a vylepšování obrazu, tak jak je známe například z programů typu Photoshop.


Článek stažen z webu Programujte.com [ http://programujte.com/clanek/2010050400-realizace-filtru-fir-a-iir-v-programovacim-jazyce-c/ ].