# RemoveGrain

## Přehled

autor: Rainer Wittmann (aka kassandro)
verze: 0.9
stáhnout: http://www.removegrain.de.tf/
kategorie: Prostorové vyhlazovače
požadavky:

- YV12 & YUY2 Barevné prostředí
- AvsRecursion
- msvcp71.dll/msvcr71.dll
licence: GNU General Public License

Plugin a zdrojový kód jsou předmětem GNU General Public License. Navíc odpíráme jakákoli práva pro odvozování Photoshop pluginů ze zdrojového kódu RemoveGrain. Toto omezení bylo provedeno s ohledem na způsob jak Adobe zachází s filtry vývojářů třetích stran, který je absolutně nepřijatelný. Poslední změna 1.května 2005.

## Instalace

Binární balík obsahuje čtyři verze RemoveGrain, tři malé dynamicky připojované verze RemoveGrain.dll, RemoveGrainSSE2.dll, RemoveGrainSSE3.dll a velkou staticky připojovanou RemoveGrainS.dll. První vyžaduje jen integer SSE (Athlon a Pentium 3), druhý vyžaduje SSE2 kompatibilní cpu (Pentium 4 nebo Athlon 64) a třetí je jen pro Prescott P4. Pokud žádná z těchto dll nepracuje, protože chybí dll, musí se buď nakopírovat chybějící dll systémové složky windows nebo se musí použít RemoveGrainS.dll, který vyžaduje jen SSE. Vložte prosím jen jeden ze tří pluginů do složky Avisynth pluginů. RemoveGrain podporuje všechna barevná prostředí. YV12 je podporované přímo a YUY2, RGB24, RGB32 jsou podporovány v planární formě (viz kapitola Barevná prostředí). Počínaje verzí 0.6 byl přidán pomocný filtr Clense do RemoveGrain.dll a plugin Repair.dll byl vložen do svého binárního balíku. Znovu jsou čtyři verze tohoto pluginu. Přestože je Repair.dll odvozen ze stejného zdrojového kódu, je určen pro docela jiné účely. Tento plugin obsahuje filtry Repair a TemporalRepair. Všechny tři nové filtry jsou popsány níže. Posílejte prosím dotazy, problémy, komentáře atd. na vlákno RemoveGrain na fóru doom9 raději, než aby jste mi posílali email. V zásadě bych ocenil zprávy o artefaktech a kompresním zesílení různých režimů. S výběrem správného režimu mohou pomoci také ostatní.

## Jak pracuje

RemoveGrain je čistě prostorový odšumovač pro Avisynth. Nicméně, v kombinaci s Clense a Repair pluginem výkonnějšími prostorově časovými odšumovači a odstraňovači prokládání (deinterlacery) mohou být sestaveny Avisynth funkce (viz příklady níže). Režimy 1-10,17,18 jsou jen pro skutečně progresivní vstup, zatímco režimy 13-16 jsou primárně pro prokládaný vstup a jsou použity pro konstruktivní odstraňovače prokládání. Zatímco režimy 1-10,17,18 mohou být použity pro prokládaný a telecine materiál jejich použitím na oddělená pole, kvalita je horší, protože sousední pixely mají dvojnásobnou vertikální vzdálenost, což má jasně negativní dopad na kvalitu. S RemoveGrain nelze odstraňovat velké skvrny nebo škrábance z klipu. Byl navržen spíše pro velmi malé skvrny - ne o moc větší než pixel. Ačkoliv změny provedené RemoveGrain jsou těžko viditelné, dopad na kompresi může být docela velký. V režimech 1-10,17,18 je hodnota středového pixelu nahrazena hodnotou jednoho z jeho osmi sousedů. To se aplikuje na jas (luma) i na barevnost (chroma). Přesněji, pro daný pixel x se RemoveGrain dívá na osm prostorových sousedů tohoto pixelu a vybírá dva z těchto sousedů, řekněme, a,b pro minmax oříznutí, t.j. x je nahrazeno min(max(x, min(a,b)), max(a,b)). Výběr a,b silně závisí na proměnné mode . Pokud 1 <= mode <= 4 minmax oříznutí je provedeno v a(mode), a(9-mode), kde a(1) <= a(2) <= a(3) <= a(4) <= a(5) <= a(6) <= a(7) <= a(8) je posloupnost sousedů seřazených podle jasu. Tak, pokud je počet sousedů s jasem (luma) >= x větší než hodnota proměnné mode a pokud je počet sousedů s jasem (luma) <= x větší než mode , pak jas tohoto pixelu je ponechán nezměněn. Samozřejmě má tato metoda smysl jen pro 1 <= mode <= 4. Pokud je mode=1, pak RemoveGrain(mode=1) je identický s trbarryho Undot (dokonce rychlost SSE verze je téměř identická jako u Undot, ale SSE2 a zvlášť SSE3 verze jsou výrazně rychlejší). S hodnotami barevnosti je pracováno podobně, ale místo proměnné mode , je použita proměnná modeU pro plochu U a modeV je použito pro plochu V. Nicméně, hodnota proměnné mode je výchozí hodnotou pro proměnnou modeU a hodnota proměnné modeU je výchozí hodnotou pro proměnnou modeV . Podívejme se na příklad: předpokládejme, že pixel má jasovou hodnotu 32 a že osm sousedů má jasové hodnoty 21, 122, 77, 25, 56, 200, 133, 45. Při mode <= 2, pak pixel zůstává nezměněný, protože existují dva sousedi s menším jasem a šest s větším jasem. Pokud je mode=3, pak je jas pixelu zvýšen na 45. Nakonec, pokud je mode=4, tak je jas zvýšen na 56. Při mode=1,2 je filtr docela bez artefaktů. Tenké čáry jsou těmito režimy zachovány včetně dvou koncových bodů. Pokud je mode=3 nebo 4, pak mohou být tenké čáry působením RemoveGrain zničeny. Proto může být RemoveGrain(mode=3 nebo mode=4) použito jen s určitou opatrností. Slušná hodnota bez rizika mode=2 je výchozí. Stále dělá výrazně silnější odšumění než Undot, t.j. mode= 1. Čím větší hodnota mode (jen mezi 1 a 4), tím měkčeji vypadá výstup a tím vyšší je kompresní poměr. Smart mode (chytrý režim) 17, uvedený ve verzi 0.8, má zvláštní význam. Je to varianta režimu mode 4. Nicméně, na rozdíl od mode 4, zachovává tenké čáry, ačkoli pixely na dvou koncích tenké čáry se mohou ztratit. Kdykoli mode= 4 nezničí tenké čáry přes pixel, pak mode 17 zpracuje pixel právě jako mode 4, jinak se použije mírně agresivnější režim než mode 2. Narozdíl od režimů <= 4, režimy mezi 5-9,17,18 jsou citlivé k hranám . Zatímco v mode <= 4 jakýkoli pár sousedů je možnou volbou pro minmax oříznutí, v režimech 5-9,18 jsou použity jen páry řádků. Existují čtyři takové páry: první horizontální pár sestávající z levého a pravého souseda pixelu, druhý vertikální pár sestávající z horního a spodního souseda, třetí diagonální pár sestávající ze spodního levého a horního pravého souseda a nakonec diagonální pár sestávajcí z horního levého a spodního pravého souseda. Při mode=9, vybíráme jednoduše ten pár řádků (a,b) pro minmax oříznutí, pro které je |a - b| minimální (jako obvykle |y| = max(y,-y) označuje absolutní hodnotu čísla y) . Tedy RemoveGrain(mode= 9) je prostě čistě prostorová varianta trbarryho filtru ST Median . Při mode=5, je tento pár řádků (a,b) zvolen pro minmax oříznutí, pro které je |x - y| minimální (zde je x původní jasová hodnota pixelu a y=min(max(x, min(a,b)), max(a,b)) je hodnota získaná při minmax oříznutí). Režimy 6,7,8 jsou střední režimy mezi mode=5 a mode=9. mode=6 je blíže mode=5 zatímco mode=8 je bližší mode=9 a mode=7 je právě ve středu mezi mode=5 a mode =9. Mode 5 zachovává tenké čáry včetně dvou posledních bodů. Mode 6-8 také zachovává tenké čáry, ale koncové body se mohou ztratit (pravděpodobnost takové ztráty se zvyšuje s číslem režimu). Fizick rozšířil mode 5-9 do časové (temporal) oblasti ve svém pluginu DeGrainMedian. Protože nyní existuje 26 místo 8 sousedních pixelů, je toto rozšíření nutně pomalejší. Přesto má časové rozšíření velký smysl. Mode 18 (přidaný ve verzi 0.9) zachová tenké čáry často také se dvěma koncovými body, ale mělo by to být horší než v mode 17 pokud se týká komprese.

Od verze 0.6 jsme také přidali rychlou implementaci nejdůležitějších 3x3 konvolucí jako mode 11. Pokud y(i,j) označuje jas pixelu se souřadnicemi i,j, pak mode 11 nahradí y(i,j) tímto (4*c(i,j) + 2*(c(i-1,j) + c(i+1,j) + c(i,j-1) + c(i,j+1)) + (c(i-1,j-1) + c(i-1,j+1) + c(i+1,j-1) + c(i+1,j+1)) + 8)/16 (+8 je nezbytné pro správné zaokrouhlení). Tak jsou všechny pixely vertikálně a horizontálně rozmazány s (1/4,1/2,1/4) jádrem. Vestavěný Blur(1) vyžaduje dělat to samé, ale ve skutečnosti to nedělá. Mode 12 (přidaný ve verzi 0.7) je výrazně rychlejší verzí režimu mode 11, který je trochu méně přesný (rozdíl mezi oběma je vždy <=1). Tedy, pokud nejste pedanti, měli by jste vždy použít mode 12 místo 11. Ve verzi 0.7 byly přidány dva režimy bob 13 a 14 . Mode 13 nechává spodní pole nezměněné a interpoluje horní pole. Mode 14 nechává horní pole nezměněné a interpoluje spodní pole. Interpolace v mode 13, 14 je podobná jako u Trbarryho weird bobu, který je částí Trbarryho Tomsmocomp. Nicméně, místo optimalizování přes 5 párů řádků optimalizujeme jen každé 3 páry řádků. Přesněji, c(i,j) je nahrazeno buď (c(i-1,j-1) + c(i +1,j+1)+1)/2 or (c(i-1,j+1) + c(i +1,j-1)+1)/2 nebo (c(i,j-1) + c(i,j+1)+1)/2, podle toho, která ze tří vzdáleností |c(i-1,j-1) - c(i +1,j+1)|, |c(i-1,j+1) - c(i +1,j-1)|, |c(i,j-1) - c(i,j+1)| je minimální. V Trbarryho weird bobu (c(i-2,j-2) + c(i +2,j+2)+1)/2 a (c(i-2,j+2) + c(i +2,j-2)+1)/2 jsou možné interpolační hodnoty. Tedy weird bob je k hranám citlivější, ale také je vyšší pravděpodobnost smart edge artefaktů a samozřejmě je pomalejší. Vzetí jen 3 párů řádků se zdá být nejlepším kompromisem pro nás. Spolu s filtrem TemporalRepair, popsaným níže, může být použit pro sestavení pohybově adaptivního deinterlaceru (odstraňovače prokládání). Od verze 0.8 jsme přidali režimy 15, 16. Mají stejnou citlivost k hranám jako režimy 13,14 , ale kvalita je o něco vyšší a rychlost o něco nižší.

Který režim je nejlepší pro odšumění? Pokud se jedná o kompresi, mé dosavadní testy dávají následující pořadí režimů: 4,17,9,8,3,7,6,2,5,1, ale režimy 4 a 17 opravdu vynikají. Pokud se jedná o artefakty, máme naneštěstí téměř obrácené pořadí režimů: 1,5,2,18,6,7,8,17,3,4,9. Režimy 1,5,2 jsou bezpečné (bez rizika artefaktů), režimy 18,6,7,8,17 ukazují nízké až střední riziko artefaktů (obvykle nějaké změkčení) a režimy 3,4,9 mají kruté problémy s tenkými čárami. Režim 9 má méně artefaktů než mode 4, ale když se objeví vypadají mnohem ošklivěji. Režim 17 je čistě můj osobní favorit. Co se týká komprese je blízko vedoucímu režimu , mode 4, a já jsem viděl jen nějaké změkčení ale stěží nějaké viditelné artefakty. Šířka snímku vstupního klipu musí být > 36 (SSE verze) nebo > 68 (SSE2 verze).

## Optimální použití

1. Jak už bylo řečeno, RemoveGrain neumí měnit pixely okrajů. Aby jste se toho zbavili, měli by jste provést oříznutí po RemoveGrain. Na druhou stranu, pro RemoveDirt by mělo být ořezání provedeno předem tak aby DCT bloky a bloky RemoveDirt byly stejné. Tedy, pokud je RemoveGrain kombinován s RemoveDirt, ořezání by mělo být provedeno nejlépe mezi RemoveGrain a Removedirt.

2. Přestože RemoveGrain,vždy dělá hodně nezarovnaných přístupů do paměti , zarovnané snímky mají kladný dopad na výkon. Tedy ořezávejte s align=true, pokud potřebujete oříznout před RemoveGrain.

3. Když je mode=0 (resp. modeU=0, resp. modeV=0), pak plocha Y (resp. plocha U, resp. plocha V) je jednoduše zkopírována ze vstupu do výstupu. Dokonce když je mode < 0 (resp. modeU < 0, resp. modeV < 0) tak se na příslušných plochách vůbec nic nedělá (dokonce ani kopírování). To může být použito pro rychlejší zpracování černobílých klipů. Například RemoveGrain(mode=8, modeU= -1). RemoveDirt(grey= true) je nejrychlejší způsob zpracování černobílého klipu pomocí kombinace RemoveGrain/RemoveDirt. Protože modeV dědí hodnotu -1 z modeU, RemoveGrain nezpracuje plochy barevnosti (chroma) a RemoveDirt postupně nastavuje plochy barevnosti rovnoměrně na 128. Pokud používáte modeU=-1, musíte přidat barevnost později přes vestavěné filtry MergeChroma nebo GreyScale.

4. RemoveGrain je slušně rychlý. Má velký smysl iterovat ho pro lepší odšumění. Například, RemoveGrain(mode=2). RemoveGrain(mode=2) je stále slušně defenzivní odšumovač, který nezničí tenké čáry.

5. Pokud je zrnění příliš hrubé, RemoveGrain ho může odstranit jen částečně nebo ho nemůže odstranit vůbec. Protože v takovém případě je zdroj ostatně dost slabý, je dobrý nápad ho zmenšit. Tak se stane také zrnění menší a RemoveGrain může být schopen ho smazat. Obecně, zmenšování by mělo být prováděno před RemoveGrain zatímco zvětšování by mělo být prováděno po RemoveGrain.

6. Jak je napsáno výše, některé režimy, zvlášť mode 3,4,9, mají problémy s tenkými čárami. Nyní má YUY2 a zvláště YV12 problém s tenkymi čárami u barevnosti, protože několik pixelů sdílí jednu hodnotu barevnosti. Tento problém je zesílen pokud je RemoveGrain použit na barevnost (chroma). Měli by jste mít na paměti, že RemoveGrain má zhruba čtyřnásobnou sílu, pokud je aplikován na YV12 chroma než na jas (luma). To je hlavní důvod změkčení hran způsobeného více konzervativními režimy 18,6,7,8,17. Tedy pro vyhnutí se zesilování problému s tenkými čarami je dobrý nápad použít režimy bez problému s tenkými čarami pro barevnost dokonce i když je režim 3,4,9 použit na jas. Například RemoveGrain(mode=4, modeU=2) používá vysoce kompresní režim 4 pro jas a režim s málo artefakty mode 2 pro barevnost. Na druhou stranu je barevnost často detailně zašumělá (zvláště, když klip pochází z videokazety), což znovu mluví pro použití konzervativnějšího režimu pro barevnost.

## Clense

Clense používá jednoduchou čistící techniku jako RemoveDirt, ale bez jakékoli ochrany proti artefaktům. Takže pokud p[i,j],c[i,j],s[i,j] označuje jas pixelu se souřadnicemi i,j v předchozím, aktuálním a následném snímku, pak c[i,j] je nahrazeno min(max(c[i,j], min(p[i,j],s[i,j])), max(p[i,j],s[i,j]))), t.j. časové (temporal) minmax oříznutí. Je to velmi brutální čistič a nemůže být použit bez Repair nebo některého jiného odstraňovače artefaktů. Nicméně pokud se špína nebo zrnění překrývají s podobnou špínou nebo zrněním pouze v jednom sousedním snímku, toto překrytí nemůže být vyčištěno. Tato poznámka je zvláště důležitá pro zrnění (dokonce neviditelné zrnění může mít velmi významně negativní dopad na kompresi). Tak to docela zlepšuje kompresi pro odstranění těchto zbytků. Zbytky z Clense jsou obvykle výrazně menší než původní zrnění, takže Clense + RemoveGrain je podstatně efektivnější a je schopno odstranit hrubší zrnění než RemoveGrain sám, ale jsou zde samozřejmě problémy s některými zbytkovými artefakty.

Clense přijímá dva argumenty. Prvním je vstupní klip a druhým je logická proměnná grey (grey=false je výchozí). Pokud je grey=true, Pak se neprovádí žádné zpracování barevnosti, t.j. barevnostní plochy obsahují náhodné hodnoty a v některém z posledních stádií musí být použit černobílý filtr. Proměnná gray je ignorována pro klipy s barevným prostředím jiným než YV12.

Od verze 0.9 existují také filtry BackwardClense a ForwardClense. Ty jsou primárně pro čištění ostrých změn scén ve skriptové funkci RemoveDirt. ForwardClense je pro první snímek nové scény a BackwardClense je pro poslední snímek scény. Použití je stejné jako u Clense.

## Repair

Od verze 0.6 jsme přidali plugin Repair. Je generován ze stejného zdrojového kódu jako RemoveGrain, ale zajišťuje velmi odlišnou činnost. Místo odstraňování zrnění by měl Repair odstraňovat artefakty uvedené v předchozích filtrech. Dělá to porovnáváním videa před těmito použitými fitry s videem po aplikováním těchto filtrů. Tedy Repair vyžaduje dva klipy jako vstup. První klip je filtrovaný a druhý je nefiltrovaný klip. Jinak Repair používá stejné proměnné jako RemoveGrain, ale režimy 11-17, které nemají smysl pro Repair, jsou vypnuty. Tedy, v současnosti existuje pro Repair 10 režimů.

Repair pracuje velmi podobně jako RemoveGrain, ale na rozdíl od RemoveGrain, kde středový pixel a sousední pixely jsou oba ze stejného snímku klipu, v Repair je středový pixel (t.j. pixel který má být změněn) brán z prvního klipu (t.j. filtrovaný klip) a sousední pixely jsou brány z druhého klipu (t.j. nefiltrovaný původní klip). Například Repair(filtered, original, mode= 1) ořízne jas pixelu klipu "filtered", minimálním jasem a maximálním jasem sousedních pixelů pixelu v klipu "original". Tak Repair omezí množství změn z klipu "original" na klip "filtered". To je čistě nějaký druh odstraňování artefaktů. Čím vyšší režim (jen od 1 do 4) , tím silnější odstraňování artefaktů. S mode=4, Repair(filtered, original, mode=4) je slušně blízký k RemoveGrain(original, mode= 4, limit= 0). Jak je popsáno výše středový pixel původního klipu by byl ignorován. To nemá smysl. Proto jsme provedli změny pro začlenění také středového pixelu původního klipu pro všechny režimy Repair. Například, Repair(filtered, original, mode=1) ořízne středový pixel filtrovaného klipu minimem ze všech 8 sousedů a středového pixelu původního klipu na jedné straně a maximem všech 8 sousedů a středového pixelu původního klipu na druhé straně. Zvláště Repair(input, input, mode=1) vůbec nezmění klip input. Bez zahrnutí středového pixelu původního klipu, by byl Repair(input, input, mode= 1) identický s RemoveGrain(input, mode= 1) nebo Undot(input). Obecně máme RemoveGrain(input, mode=n) = Repair(input, input, n+1) pro n=0,1,2,3.

Ve verzi 0.9 jsme přidali nové režimy Repair, které jsou odvozené od režimů RemoveGrain jiným způsobem. K tomuto účelu ať je "f" jasovou hodnotou středového pixelu filtrovaného klipu (který má být opraven) a "o" bude jasovou hodnotou stejného pixelu v původním klipu. Pak jako v odpovídajícím režimu RemoveGrain, dva sousední pixely s jasovými hodnotami, řekněme, "n1", "n2" jsou zvoleny a "f" je oříznut na min(n1,n2,o) a max(n1,n2,o). Samozřejmě, s barevností se pracuje stejným způsobem. Takový režim Repair lze odvodit od jakéhokoli režimu RemoveGrain kromě režimů 11-16. Udělali jsme to jen pro režimy 1-6, 17, 18. 11-18 jsou odpovídající opravné repair režimy. Tedy režimy Repair 11-16 odpovídají režimům RemoveGrain 1-6, zatímco režimy Repair 17,18 odpovídají režimům RemoveGrain 17,18. Pro mode 1 jsou obě metody pro odvození režimů Repair shodné, proto Repair(mode=1) a Repair(mode=11) jsou identické. (Repair mode 16 je zvláště důležitý. Obnovuje tenké čáry a je dobrá šance (ale negarantovaná) , že budou obnoveny dokonce i koncové body. Je to v současnosti primární režim Repair pro skript RemoveDirt.

Proberme si teď některé příklady pro Repair. Prvním je předběžná verze RemoveDust:

    function RemoveDust(clip input, int _mode)
    {
    	repmode = 16
    	clensed = Clense(input)
    	rep=Repair(clensed, input, mode=repmode)
    	return RemoveGrain(rep, mode=_mode)
    }

Nejprve Clense brutálně odstraní všechnu časovou špínu, ale také zanechává hodně artefaktů. Repair pak odstraní tyto artefakty, ale také obnoví všechny větší kusy špíny. Zatímco většina pohybových artefaktů z Clense je odstraněna pomocí Repair, pohyb se trochu rozmaže, ale statické oblasti jsou nedotčené. Nakonec RemoveGrain (doporučuji mode=8, 17 nebo mode=4 pro lepší kompresi) odstraní zbytky z Clense. Rozmazání pohybu má mnohem významnější dopad na kompresi, než rozmazání statických detailů. Na druhou stranu, lidské oko se ve skutečnosti neumí koncentrovat na pohyblivé detaily a může být dokonce "nervózní" z pohyblivých detailů. Proto z mého pohledu je RemoveDust mnohem lepší než obvyklý přístup "rozmazání všeho malého" většiny odšumovačů. Pokud chcete agresivnější Removedust, můžete zvolit repmode= 1 a/nebo použít RemoveGrain před Repair. Repair(mode= 9) je velmi zajímavý. Obnovuje všechny tenké čáry zničené v Clense. Přesto je komprese pozoruhodně dobrá (výstupní velikost je obvykle méně než o 5%-20% nad Repair(mode= 2) nebo Repair(mode= 5) . Doporučuji použít Repair jen s režimy 2, 5-9. Repair může být také použit pro mírné zostření:

    function ModerateSharpen(clip input, float amount)
    {
    	repmode = 16
    	sharpened = Sharpen(input, amount)
    	return Repair(sharpened, input, mode=repmode)
    }

Naneštěstí je už jméno LimitedSharpen použito. Takže budeme muset nazvat výše uvedenou skriptovou funkci ModerateSharpen. Sharpen(1.0) vypadá opravdu ošklivě a je noční můrou pro jakýkoli kodek. Získali jsme následující kompresní výsledky (5000 snímků, vysoce kvalitní zdroj, 696x448, xvid 1.0.1 s kvantizerem 5):

    19.260.837 Bajtů	bez jakéhokoli filtrování
    85.830.020 Bajtů	Sharpen(1.0)
    41.743.528 Bajtů	ModerateSharpen(1.0), repmode=1
    34.255.894 Bajtů	ModerateSharpen(1.0), repmode=2

Také ModerateSharpen(1.0) zvláště s repmode=9 vypadá mnohem lépe než Sharpen(1.0). Mode 10 není vhodný pro mírné zostřovače.

## TemporalRepair

Stejným způsobem jakým je Repair odvozen z RemoveGrain, je TemporalRepair odvozen od Clense. Zatímco Repair je prostorový filtr nejvhodnější pro odstraňování artefaktů časových (temporal) filtrů jako Clense, TemporalRepair je časový filtr, primárně užitečný pro obnovení statických (nepohybujících se) detailů prostorových (spatial) filtrů jako RemoveGrain. Zvláště RemoveGrain(mode= 4) ztrácí svůj "vypraný" vzhled, pokud se kombinuje s TemporalRepair:

    function RemoveTemporalGrain(clip input, int _mode)
    {
    	rg = RemoveGrain(input, mode=_mode)
    	return TemporalRepair(rg, input)
    }

mode=4 je rozhodně doporučen pro RemoveTemporalGrain. Samozřejmě komprese RemoveTemporalGrain(4) výsupu je horší než u RemoveGrain(mode= 4) ale je dostatečně nad více defenzivními režimy RemoveGrain a plně zachovají statické detaily. Pro RemoveDust je situace ještě lepší:

    function RemoveDust(clip input, int _mode)
    {
    	repmode = 2
    	clensed = Clense(input)
    	rep=Repair(clensed, input, mode=repmode)
    	rg = RemoveGrain(rep, mode=_mode)
    	return TemporalRepair(rg, rep)
    }

Všimněte si, že místo původního klipu "input", je nyní brán střední klip "rep" jako druhý klip. Při srovnání předchozí verze RemoveDust se současnou (ještě ne finální) verzí, byl RemoveGrain prostě nahrazen RemoveTemporalGrain a změkčení je významně sníženo, při mode=4. Statické detaily dokonce zůstávají nedotčeny a komprese moc neutrpí. Přesto jsou hrany objektů dokonce zostřeny, pokud nejsou tyto objekty příliš tenké, RemoveDust vypadá trochu měkce a tenké pohyblivé objekty mohou být whiped out, dobrá část měkkosti je jen psychologická, protože virtuálně všechno přírodní chvění ve filmu, které neobsahuje jakoukoli informaci, ale na které je lidské oko docela zvyklé je odstraněno. Pokud je takové chvění znovu uvedeno pomocí zostřovače po dekódování přehrávačem (s ffdshow například), pak RemoveDust klipy by měli vypadat znovu docela ostře (jiskrně).

TemporalRepair může být také použit pro sestavení rozumně rychlého odstranění prokládání s vysokou kompresí, bez prahových hodnot, bez změny pohybu:

    function RGDeinterlace(clip input)
    {
    	rg = RemoveGrain(input, mode=12)
    	return TemporalRepair(rg, input)
    }

Zatímco RemoveGrain(input, mode=12) odstraňuje prokládání z každého pixelu, TemporalRepair obnovuje statické oblasti. Je typické spíše pro TemporalRepair, když filtr zaneřádí statické části videa, které může být pěkně obnoveno - bez jakýchkoli artefaktů - pomocí TemporalRepair. RGDeinterlace je blur deinterlacer, který se chová podobně jako AlignFields(mode=2), ale bez jakéhokoli chvění, protože nemá prahové hodnoty. Pokud v jednom snímku "pohybová hodnota" oblasti je mírně nad prahovou hodnotou a v následujícím je mírně pod, pak je tato oblast deinterlována v jednom snímku a nezměněna v dalším. To se obvykle zobrazí jako blikání, což je typické pro pohybově adaptivní odstraňovače prokládání založené na prahových hodnotách. To má docela negativní efekty na kompresi. Naneštěstí, v této formě RGDeinterlace pracuje docela špatně na mé telegrafní testové pásce, protože TemporalRepair obnovuje příliš mnoho. Přestože artefakty na mé testovací telegrafní pásce jsou viditelné jen při 400% zvětšení ve VirtualDubu, ukazují, že deinterlacer není optimální pro kompresi, t.j. komprese je zbytečná bez zvýšení kvality obrazu. Pro vylepšení výkonu v tomto testu jsem přidal celočíselnou proměnnou smooth do TemporalRepair ve verzi 0.7. Pokud je smooth=0, výchozí hodnotě, pak TemporalRepair pracuje jako dříve. Pokud je smooth= 1 (v současnosti jsou povoleny jen hodnoty 0 a 1), tak TemporalRepair už není jen čistě časový (temporal), protože bere také časovou fluktuaci 8 sousedních pixelů. Následně pak TemporalRepair "opravuje" méně s smooth=1 než s smooth=0, ale stále výsledný deinterlacer nemůže zpracovat telegrafní testovací pásku uspokojivě (přestože je lepší). Tak jsme pro tento účel zavedli smooth=2,3 ve verzi 0.9 . Režim 2 obnovuje méně než mode 0,1,3 a je proto bezpečnějším režimem pro odstranění prokládání a dává celkem dobré kompresní výsledky. Režim 3 je také vhodný pro odstranění prokládání a měl by být zvolen, pokud uživatel chce zachovat maximální množství detailů. Na testovací telegrafní pásce pracuje režim 2 lépe než režim 3 a mnohem lépe než režim 1, stále není bez artefaktů. Nicméně, dobře soupeří s většinou pohybově adaptivních deinterlacerů (obvykle založených na prahových hodnotách) v tomto testu. Uživatel musí odstranit zbývající artefakty dalším aplikováním RemoveGrain. Tímto způsobem získá následující deinterlacer:

    function RGDeinterlace(clip input)
    {
    	rg = RemoveGrain(input, mode=12)
    	rg2 = TemporalRepair(rg, input, smooth=2)
    	return RemoveGrain(rg2, mode=2)
    }

Nicméně, tento odstraňovač prokládání se zřejmě nedrží principu žádný pohyb žádná změna. Jiná myšlenka pro vylepšení odstranění prokládání je iterovat TemporalRepair. Tímto způsobem získáme následující deinterlacer:

    function RGDeinterlace(clip input)
    {
    	rg = RemoveGrain(input, mode=12)
    	rg2 = TemporalRepair(rg, input, smooth=2)
    	return TemporalRepair(rg, rg2, smooth=2)
    }

Tato verze RGDeinterlace znovu ctí princip žádný pohyb žádná změna a pracuje lépe na telegrafní testové pásce. Nicméně, s smooth > 0 je TemporalRepair výrazně pomalejší než se smooth=0 a iterace nemá smysl se smooth=0. Také má smysl použít TemporalRepair(smooth=1) uvnitř skriptu RemoveDust.

Odstraňovače prokládání uvedené výše jsou všechny rozmazávací (blur) deinterlacery. Pro získání ostrých deinterlacerů musíte nejdříve použít RemoveGrain s novým režimem 14. Například

    function RGSDeinterlace(clip input)
    {
    	rg = RemoveGrain(input, mode=16).RemoveGrain(mode=12)
    	return TemporalRepair(rg, input, smooth=2)
    }

je ostrou verzí nejprimitivnější verze RGDeinterlace. Je důležité použít RemoveGrain s mode=12 po mode=14. Pokud se to neudělá, pak je zachováno horní pole a spodní pole bude interpolováno, což vždy vede ke spíše slabé kompresi, protože dvě pole se tolik liší (to lze pěkně zobrazit pomocí zostřovače).

## Rychlejší zpracování Černobílého videa

Clense a TemporalRepair mají volitenou proměnnou grey . Pokud je grey= true, pak Clense a TemporalRepair nechají barevnost zcela nezpracovanou. Není dokonce ani zkopírována. Takže se pak musí použít vestavěný filtr Greyscale v pozdější fázi pro vyčištění náhodných hodnot z barevnosti. Tato možnost je platná jen pro YV12 klipy a je ignorována pro ostatní barevná prostředí. Stejného efektu lze dosáhnout u filtrů RemoveGrain a Repair pokud se nastaví modeU= -1. Zde je filtr RemoveDust jak jej teď používám:

    function RemoveDust(clip input, int "repmode", int "_smooth", bool
    "_grey")
    	{
    	default(repmode, 16)
    	default(_smooth, true)
    	default(_grey, false)
    	clmode = 4
    	clensed = Clense(input, grey=_grey)
    	rep=Repair(clensed, input, mode=repmode, modeU=_grey ? -1 : repmode )
    	rg = RemoveGrain(rep, mode=clmode, modeU=_grey ? -1 : clmode)
    	return TemporalRepair(rg, rep, grey=_grey, smooth=_smooth)
    }

Zde je můj současný odstraňovač prokládání:

    function RGDeinterlace(clip input, bool _grey)
    {
    	rg = RemoveGrain(input, mode=12, modeU=_grey ? -1 : 12)
    	rg2 = TemporalRepair(rg, input, smooth=2, grey=_grey)
    	return RemoveGrain(rg2, mode=2, modeU=_grey ? -1 : 2)
    }

Zde je můj současný bob filtr (jen pro horní pole první):

    function RGBob(clip input, bool _grey)
    {
    	top = RemoveGrain(input, mode=16, modeU=_grey ? -1 : 16)
    	bottom = RemoveGrain(input, mode=15, modeU=_grey ? -1 : 15)
    	return Interleave(top, bottom)
    }

Pokud máte video se spodním polem prvním, musíte dosadit poslední řádek s "return Interleave(bottom, top)".

## Barevná prostředí

Do verze 0.7 filtry uvedené výše také podporovaly barevná prostředí YUY2, RGB24 a RGB32. Provádělo se to vnitřním převedením těchto prolínaných (interleaved) formátů na planární formáty, pak tyto planární střední (mezi)formáty byly zpracovány jako YV12 a nakonec střední planární formáty byly převedeny zpět do původních prolínaných formátů. Pokud se, jako v některých skriptech výše, používá hodně instancí výše uvedených filtrů, tyto převodní rutiny vedly k enormním režiím. Převodní rutiny nebyly také optimalizovány. Od verze 0.8 jsme vypustili podporu pro prolínaná barevná prostředí ve prospěch jejich planárních analogů. Pro Avisynth vypadají planární YUY2, RGB24 nebo RGB32 snímky právě jako obyčejné prolínané snímky těchto barevných prostředí. Nicméně, organizace dat v těchto snímcích je velmi odlišná. Ještě nevydaný plugin SSETools (předběžné verze jsou zahrnuty do balíku RemoveGrain) obsahuje základní filtry Interleaved2Planar a Planar2Interleaved. Pro YV12 tyto filtry nedělají absolutně nic. Pro ostatní barevná prostředí Interleaved2Planar převádí prolínané (interleaved) snímky na snímky s organizací planárních dat a Planar2Interleaved obrací tento převod. Tedy Interleaved2Planar().Planar2Interleaved a Planar2Interleaved.Interleaved2Planar(). nechají snímky nezměněné. Tak také Planar2Interleaved a Interleaved2Planar jsou bezeztrátové filtry. Pro YUY2 jsou filtry Interleaved2Planar() a Planar2Interleaved vysoce optimalizovány a neměli by stát o moc víc než jednoduchý bitblt. Nyní, abychom zakázali nezkušeným uživatelům použití filtrů uvedených výše na prolínaná barevná prostředí, přidali jsme logickou proměnnou planar do RemoveGrain, Repair a TemporalRepair. Pokud planar=false (výchozí hodnota), pak tyto filtry odmítnou YUY2, RGB24 a RGB32 snímky. Jen když je planar=true, tak tyto filtry akceptují YUY2, RGB24 a RGB32 vstup, ale vždy předpokládejte, že data jsou organizována planárním způsobem. Pokud použijete planar=true na obyčejný prolínaný vstup, získáte nesmysly. Clense a MCClense jako většina jiných čistě časových filtrů, pracují stejným způsobem s planárním i s prolínaným vstupem. Proto tyto filtry nemají proměnnou planar a pracují oba s planárním i prolínaným vstupem. TemporalRepair(smooth=0) je také čistě časový a tak přijímá YUY2, RGB24 a RGB32 vstup, dokonce i při planar=false. Na druhou stranu,TemporalRepair(smooth=1) má také prostorové aspekty a proto odmítá jakékoli YUY2, RGB24 a RGB32 vstupy při planar=false. V ne velmi vzdálen budoucnosti by měla existovat webová stránka www.PlanarYUY2.de.tf , která uvádí filtry a jejich kompatibilitu s planárními YUY2, RGB24, RGB32.

Jako příklad pro použití Planar2Interleaved a Interleaved2Planar uvedeme verzi RemoveDust, která pracuje pro YV12, a všechna prolínaná (interleaved) barevná prostředí (ale ne planární YUY2, RGB24, RGB32):

     function RemoveDust(clip input, bool grey, int "repmode", int "_smooth")
    {
    	default(repmode, 16)
    	default(_smooth, true)
    	clmode = 4
    	input = Interleaved2Planar(input)
    	clensed = Clense(input, grey=_grey)
    	rep=Repair(clensed, input, mode=repmode, modeU=_grey ? -1 : repmode )
    	rg = RemoveGrain(rep, mode=clmode, modeU=_grey ? -1 : clmode)
    	return TemporalRepair(rg, rep, grey=_grey, smooth=_smooth).Planar2Interleaved()
    }

`$English Date: 2005/05/01 $`

`Český překlad:19.5.2009`