ConditionalFilter
(clip testclip, clip source1, clip source2,
string expression1, string operator, string expression2, bool "show")
ConditionalFilter
(podmínkový filtr) vrací source1 , když
je splněna podmínka ''expression1+operator+expression2'' pro aktuální snímek, jinak vrací source2. Pokud není žádná funkce
v expression1 nebo v expression2 jasně použita na nějaký klip, použije se filtr
na testclip . Audio se bere ze source1.
Příklad. Vybereme snímky z klipu vid_blur když je střední jas snímku menší než 20, jinak bereme snímky z výchozího klipu.
vid = AviSource("file") vid_blur = vid.Blur(1.5) ConditionalFilter(vid, vid_blur, vid, "AverageLuma()", "lessthan", "20")
Přidáním show= "true" zobrazíme aktuální hodnoty parametru na obrazovce.
Řetězce expression1 a expression2 mohou být jakékoliv číselné nebo logické výrazy, a smí zahrnovat vnitřní nebo uživatelské funkce, stejně tak některé přídavné funkce,
které jsou předdefinovány ( Runtime Funkce) a speciální runtime proměnnou current_frame (číslo žádaného snímku).
Řetězec
operator může
být
"equals", "greaterthan" nebo "lessthan". Nebo lze
použít odpovídající symboly "=", ">" nebo "<" .
ScriptClip
(clip, string function, bool "show", bool
"after_frame")
ScriptClip
vrací klip vrácený funkcí function
použité na každý snímek. Řetězec filter může
být libovolný vnitřní filtr, ale mohou to být také některé preferované
filtry, které jsou předdefinovány ( Runtime Funkce). Přidáním
show= "true" zobrazíme aktuální hodnoty parametru na obrazovce.
# Toto tiskne rozdíl mezi předchozím a aktuálním snímkem: clip = AviSource("c:\file.avi") ScriptClip(clip, "Subtitle(String(YDifferenceFromPrevious))") # Toto používá rozmazání každého snímku v závislosti na rozdílu od předchozího snímku. # Toto také zobrazí jaké chyby se oznamují na některých snímcích:) clip = AviSource("c:\file.avi") ScriptClip(clip, "Blur(YDifferenceFromPrevious/20.0)") # Toto použije časové změkčení značně statické scény a proměnné rozmazání na pohyblivé scény. # Také rozmazání je zde řádně uzavreno. Také přiřadíme proměnnou - a proto je vloženo přerušení řádku: function fmin(float f1, float f2) { return (f1<f2) ? f1 : f2 } clip = AviSource("c:\file.avi") T = clip.TemporalSoften(2, 7, 7, 3, 2) ScriptClip(clip, "diff = YDifferenceToNext()"+chr(13)+"diff>2.5 ? Blur(fmin(diff/20, 1.5)) : T") #Zobrazí číslo snímku v klipu: ScriptClip("subtitle(string(current_frame))") #Zobrazí řetězec 'frame = the frame-number': ScriptClip("""subtitle("frame = " + string(current_frame))""")
Ve v2.55 je přidán parametr after_frame=true/false . Určuje má li skript vyhodnocovat před (což je základní nastavení) nebo až potom, kdy bude snímek doručen od výše stojících filtrů.
"Omezení": Výstup skriptu musí být stejného formátu jako vstup
do filtru ScriptClip
(stejné barevné prostředí, šířka a výška). Vracený klip může
mít jinou délku, ale bude použita délka výchozího klipu "clip". Audio ze vstupu "clip" zustává
nedotknuto. Pro dva velmi rozdílné zdroje (MPEG2DEC3 a AviSource) - může nastat nesoulad
barevných prostredí. To je známý špek.
FrameEvaluate
(clip clip, script filter, bool "after_frame")
Podobný jako ScriptClip
, kromě toho, že výstup z filter
je ignorován. To může být užitečné například pro přiřazení proměnných, atd. Vrací se
snímky přímo ze vstupního klipu.
Ve
v2.53 je přidán parametr after_frame=true/false
. Určuje má li skript vyhodnocovat před (což
je základní nastavení) nebo až potom, kdy bude snímek doručen od výše stojících filtrů.
Tento filtr umožní import libovolné informace ze souboru do některé funkce.
Viz stránky o ConditionalReader .
Jsou vnitřní funkce, vyhodnocované na každém snímku.
Tyto vrací střední hodnotu pixelu na ploše - jasové, nebo barevné (vyžaduje YV12,
ISSE):
AverageLuma
(clip)
AverageChromaU
(clip)
AverageChromaV
(clip)
Tyto vrací desetinnou hodnotu mezi 0 a 255 absolutního rozdílu mezi plochami (jasovými,
nebo barevnými) dvou klipů (vyžaduje YV12, ISSE):
RGBDifference
(clip1, clip2)
LumaDifference
(clip1, clip2)
ChromaUDifference
(clip1, clip2)
ChromaVDifference
(clip1, clip2)
Při použití těchto funkcí je aktivní "implicit last" (pokud není specifikován první parametr), takže za první parametr je dosazen testclip (což je poslední zmíněný klip), předávaný filtrům ConditionalFilter, ScriptClip, FrameEvaluate.
Tyto filtry jsou užitečné pro stanovení změny scény:
RGBDifferenceFromPrevious
(clip)
YDifferenceFromPrevious
(clip)
UDifferenceFromPrevious
(clip)
VDifferenceFromPrevious
(clip)
RGBDifferenceToNext
(clip)
YDifferenceToNext
(clip)
UDifferenceToNext
(clip)
VDifferenceToNext
(clip)
# Nahrazuje poslední snímek před změnou scény # prvním snímkem z nové scény ConditionalFilter(last, last, last.trim(1,0), "YDifferenceToNext()", ">", "10", true)
YPlaneMax
(clip, float threshold)
UPlaneMax
(clip, float threshold)
VPlaneMax
(clip, float threshold)
YPlaneMin
(clip, float threshold)
UPlaneMin
(clip, float threshold)
VPlaneMin
(clip, float threshold)
YPlaneMedian
(clip)
UPlaneMedian
(clip)
VPlaneMedian
(clip)
YPlaneMinMaxDifference
(clip, float threshold)
UPlaneMinMaxDifference
(clip, float threshold)
VPlaneMinMaxDifference
(clip, float threshold)
Threshold je v procentech, určuje jaký procentuální podíl pixelů může být větší nebo menší než dané minimum. Threshold (prahová hodnota) je volitelná a její výchozí hodnota je 0.
Pokud rozumíte předchozímu oddílu, můžete přejít ke kapitole "rozšířeného podmíněného filtrování", ve které se dozvíte trochu víc o podmíněném filtrování.
Pro pochopení této kapitoly je
potřeba vědět jak pracuje AviSynth:
Skripty se vytváří od shora dolů, ale když videoeditor
žádá snímek, jeho vyhodnocení začíná od posledního snímku a pokračuje k
prvnímu nahoru po řetězci filtrů. Například:
AviSource("myfile.avi") ColorYUV(analyze=true) Histogram()Při otevření skriptu ve VirtualDubu se stane následující:
Tedy řetězec filtrů pracuje v zásadě pozpátku (výstup je spíše 'vytažen' ze spodu než 'protlačen' z hora) což dává možnost použít několik snímků i z výše položených filtrů pro obdržení žádaného snímku.
Nicméně Podmíněné filtry, potřebují vyhodnocovat skripty před tím, než žádají o snímky z výše položených filtrů, proto potřebují vědět, který filtr volat. Další důležitá zvláštnost spočívá v tom, že pouze globální proměnné v 'prostředí' podmíněného filtru, lze použít uvnitř i vně podmíněného filtru . Podívejte se na následující skript
v = AviSource("E:\Temp\Test3\atomic_kitten.avi").ConvertToYV12 function g(clip c) { global w = c c2 = ScriptClip(c, "subtitle(t)") c3 = FrameEvaluate(c2, "t = String(text)") c4 = FrameEvaluate(c3, "text = YDifferenceFromPrevious(w)") return c4 } g(v)Tento řetězec filtrů pracuje následovně:
v = AviSource("E:\Temp\Test3\atomic_kitten.avi").ConvertToYV12 function g(clip c) { global w = c c2 = ScriptClip(c, "subtitle(t)") c3 = FrameEvaluate(c2, "me()") c4 = FrameEvaluate(c3, "global text = YDifferenceFromPrevious(w)") return c4 } function me() { global t = String(text) } g(v)Toto je pouze ilustrace pro demonstraci r;zm7ch mo6nost9. Většina skriptu je napsána zbytečně, a může být odstraněna. Následující dvaskripty dají stejný výstup.
v = AviSource("c:\clip.avi") # ScriptClip přijímá víceřádkové skripty: scriptclip(v," text = YDifferenceFromPrevious() t = string(text) subtitle(t) ")
v = AviSource("c:\clip.avi") ScriptClip(v, "Subtitle(String(YDifferenceFromPrevious))")V následující kapitole se naučíme zapisovat do textového souboru informace, patřící ke snímku.
V následujícím příkladu, se do textového souboru
zapisují některé informace, patřící ke snímku. První proměnná "a" říká,
že snímek je prokládaný-zjistí se použitím filtru IsCombed z balíku Decomb
(pro
určitou mezní hodotu (threshold)). Druhá proměnná "b"
říká kolik je ve snímku pohybu.
global sep="." global combedthreshold=25 function IsMoving() { global b = (diff < 1.0) ? false : true } function CombingInfo(clip c) { file = "F:\interlace.log" global clip = c c = WriteFile(c, file, "a", "sep", "b") c = FrameEvaluate(c, "global a = IsCombed(clip, combedthreshold)") c = FrameEvaluate(c, "IsMoving") c = FrameEvaluate(c,"global diff = 0.50*YDifferenceFromPrevious(clip) + 0.25*UDifferenceFromPrevious(clip) + 0.25*VDifferenceFromPrevious(clip)") return c } v = mpeg2source("F:\From_hell\from_hell.d2v").trim(100,124) CombingInfo(v)
Můžeme upravit tyto dvě funkce, a odstranit globální proměnné, jejich následujícím zápisem:
function IsMoving(float diff) { return (diff >= 1.0) } function CombingInfo(clip c) { file = "F:\interlace.log" c = WriteFile(c, file, "a", "sep", "b") c = FrameEvaluate(c," diff = 0.50*YDifferenceFromPrevious() + 0.25*UDifferenceFromPrevious() + 0.25*VDifferenceFromPrevious() b = IsMoving(diff) a = IsCombed(combedthreshold) ") return c }
V následující kapitole si prohlédneme příklad adaptivní pohybové filtrace zvětšní (resizing).
Na fórech se objevilo několik pohybově adaptivních filtrů
pro zvětšování a vyhlazování. Tyto filtry rozlišují malé, střední a velké množství
pohybu v klipu (na základě srovnání snímků). Podle toho mohou být použity různé druhy filtrů pro
různý druh pohybu. Obecně, časové vyhlazování se použije pro statické scény s malým pohybem, prostorové
vyhlazení se použije pro scény s velkým pohybem a ve scénách
se středním pohybem se používají prostorově-časové vyhlazovače.
Níže se nahází zjednodušená verze filtru QUANTIFIED MOTION FILTER v1.5
b1 (10/07/2003) by HomiE FR, :
---------------------------------------------------- # QUANTIFIED MOTION FILTER v1.3 # NAČÍTÁME PLUGIN AVISYNTHU LoadPlugin("C:\PROGRA~1\GORDIA~1\mpeg2dec3.dll") LoadPlugin("C:\PROGRA~1\GORDIA~1\TemporalCleaner.dll") LoadPlugin("C:\PROGRA~1\GORDIA~1\FluxSmooth.dll") LoadPlugin("C:\PROGRA~1\GORDIA~1\UnFilter.dll") # NAČÍTÁME SKRIPT - QUANTIFIED MOTION FILTER Import("E:\temp\QMF\qmf.avs") # FILTRACE PRO MÁLO POHYBU # -> ZMĚNA VELIKOSTI SE ZOSTŘENÍM + ČASOVÁ FILTRACE function Low_Motion_Filter(clip c) { c = TemporalCleaner(c, 5, 10) c = LanczosResize(c, 512, 272) return c } # FILTRACE PRO STŘEDNÍ MÍRU POHYBU # -> NEUTRÁLNÍ BIKUBICKÁ ZMĚNA VELIKOSTI + ČASOVÁ & PROSTOROVÁ FILTRACE function Medium_Motion_Filter(clip c) { c = FluxSmooth(c, 7, 7) c = BicubicResize(c, 512, 272, 0.00, 0.50) return c } # FILTRACE PRO VELKÉ MNOŽSTVÍ POHYBU # -> ZMĚKČOVACÍ ZMĚNA VELIKOSTI + PROSTOROVÁ FILTRACE function High_Motion_Filter(clip c) { c = FluxSmooth(c, -1, 14) c = UnFilter(c, -30, -30) c = BilinearResize(c, 512, 272) return c } # OTEVÍRÁNÍ VIDEO ZDROJE AviSource("E:\temp\QMF\britney-I_love_rock_'n_roll.avi") ConvertToYV12(interlaced = true) Telecide(0) # POUŽITÍ ADAPTIVNÍHO FILTRU PRO ZMĚNU VELIKOSTI (S POUŽITÍM QMF) QMF() ---------------------------------------------------- text souboru gmf.avs ---------------------------------------------------- # QUANTIFIED MOTION FILTER (17/08/2003) by HomiE FR (homie.fr@wanadoo.fr) # FUNKCE URČENÍ MÍRY POHYBU function ME() { # NASTAVUJEME MÍRU POHYBU V SOULADU SE STŘEDNÍM ROZDÍLEM SNÍMKŮ [1] global motion_level = (diff < threshold_lm) ? 0 : motion_level global motion_level = (diff >= threshold_lm && diff <= threshold_hm) ? 1 : motion_level global motion_level = (diff > threshold_hm) ? 2 : motion_level } # FUNKCE ADAPTIVNÍ FILTRACE function QMF(clip c, float "threshold_lm", float "threshold_hm", bool "debug") { # NASTAVUJEME PRAHOVÉ HODNOTY PRO MNOŽSTVÍ POHYBU[2] threshold_lm = default(threshold_lm, 4.0) threshold_hm = default(threshold_hm, 12.0) global threshold_lm = threshold_lm global threshold_hm = threshold_hm # POVOLUJEME/ZAKAZUJEME VÝSTUP LADÍCÍ INFORMACE[3] debug = default(debug, false) # INICIALIZUJEME PROMĚNNOU, OBSAHUJÍCÍ MNOŽSTVÍ POHYBU global motion_level = 0 # NASTAVENÍ PŘÍTOMNÉHO KLIPU[4] global clip = c # DOSTÁVÁME VÝSTUPNÍ ROZLIŠENÍ[5] width = Width(Low_Motion_Filter(c)) height = Height(Low_Motion_Filter(c)) global c_resized = PointResize(c, width, height) # POUŽÍVÁME POHYBOVÝ FILTR V SOULADU S MNOŽSTVÍM POHYBU[6] c = ConditionalFilter(c, Low_Motion_Filter(c), c_resized, "motion_level", "=", "0") # [6a] c = ConditionalFilter(c, Medium_Motion_Filter(c), c, "motion_level", "=", "1") # [6b] c = ConditionalFilter(c, High_Motion_Filter(c), c, "motion_level", "= ", "2") # [6c] # TISKNEME LADÍCÍ INFORMACE [7] c = (debug == true) ? ScriptClip(c, "Debug()"): c # DOSTÁVÁME MÍRU POHYBU Z ANALÝZY SNÍMKŮ [8] c = FrameEvaluate(c, "ME()") # DOSTÁVÁME ROZDÍL MEZI PŘEDCHOZÍM A SOUČASNÝM SNÍMKEM [9] c = FrameEvaluate(c, "global diff = 0.50*YDifferenceFromPrevious(clip) + 0.25*UDifferenceFromPrevious(clip) + 0.25*VDifferenceFromPrevious(clip)") return c } # FUNKCE LADÍCÍ INFORMACE function Debug(clip c) { # INFORMACE O VERZI[10] c = Subtitle(c, "Quantified Motion Filter", x=20, y=30, font="lucida console", size = 18, text_color = $FFFFFF) c= Subtitle(c,"by HomiE FR(homie.fr@wanadoo.fr)", x=20, y =45, font= "lucidaconsole", size= 14, text_color= $FFFFFF) # TISK INFORMACE O MÍŘE POHYBU [11] c = Subtitle(c, "motion estimation", x=20, y=85, font="lucida console", size=18, text_color=$FFFFFF) c = Subtitle(c, "diff = "+string(diff ),x=20,y=110, font="lucidaconsole", size= 16, text_color=$FFCCCC) # TISK INFORMACE O REŽIMU PRÁCE Quantified Motion Filter [12] c = Subtitle(c, "quantified motion filter", x=20, y=135, font="lucida console", size=18, text_color=$FFFFFF) c = (motion_level == 0) ? Subtitle(c, "scene type = low motion", x=20, y=160, font="lucida console", size=16, text_color=$66FF66) : c c = (motion_level == 1) ? Subtitle(c, "scene type = medium motion", x=20, y=160, font="lucida console", size=16, text_color=$66FF66) : c c = (motion_level == 2) ? Subtitle(c, "scene type = high motion", x=20, y=160, font="lucida console", size=16, text_color=$66FF66) : c return c } ----------------------------------------------------Tento řetězec filtrů pracuje následovně:
Některé detaily byly vynechány, ale je to ukázka jak skript v podstatě pracuje.
$English Date: 2008/12/21 09:23:02 $
Český překlad:12.2.2009