ConditionalFilter
(clip testclip, clip source1, clip source2,
string filter, string operator, string value, bool "show")
ConditionalFilter
retorna source1 quando a condição formada por
''filter+operator+value '' é conhecida, caso contrário retorna source2.
Se filter não é aplicado explicitamente a um clipe, será
aplicado em testclip. O áudio é pego de source1.
Um exemplo. Isto escolherá quadros de vid_blur quando o valor luma médio de um quadro é menos que 20. Caso contrário serão retornados os quadros vid.
vid = AviSource("file") vid_blur = vid.Blur(1.5) ConditionalFilter(vid, vid_blur, vid, "AverageLuma()", "lessthan", "20")
Incluindo show="true" exibirá os valores atuais na tela.
A string filter pode ser qualquer filtro interno, mas também
alguns filtros pré-definidos (funções Runtime).
A string operator pode ser "equals", "greaterthan"
ou "lessthan". Ou "=", ">" ou "<" respectivamente.
ScriptClip
(clip, string function, bool "show", bool
"after_frame")
ScriptClip
retorna o clipe devolvido pela função avaliada
em cada quadro. A string filter pode ser qualquer filtro interno, mas também
alguns filtros pré-definidos (funções Runtime).
Incluindo show="true" exibirá os valores atuais na tela.
# Isto imprimirá a diferença do quadro prévio sobre o atual: clip = AviSource("c:\file.avi") ScriptClip(clip, "Subtitle(String(YDifferenceFromPrevious))") # Isto aplicará borrado em cada quadro baseado na diferença do prévio. # Isto também mostrará como os erros são informados em alguns quadros :) clip = AviSource("c:\file.avi") ScriptClip(clip, "Blur(YDifferenceFromPrevious/20.0)") # Isto aplicará temporalsoften a cenas muito estáticas e aplica um _variable_ blur em cenas de movimento. # O borrado agora fica corretamente coberto. Também designamos uma variável - e por que uma quebra de linha é inserida: function fmin(float f1, float f2) { return (f1<f2) ? f1 : f2 } clip = AviSource("c:\file.avi") ScriptClip(clip, "diff = YDifferenceToNext()"+chr(13)+"diff > 2.5 ? Blur(fmin(diff/20,1.5)) : TemporalSoften(2,7,7,3,2)") # Exibe o número do quadro em um clipe: ScriptClip("subtitle(string(current_frame))") # Exibe 'frame = the frame-number' em um clipe: ScriptClip("""subtitle("frame = " + string(current_frame))""")
Na v2.55 está incluída uma opção after_frame=true/false. Isto determina se o escrito deve ser avaliado antes (operação padrão) ou depois que o quadro viesse dos filtros acima.
"Restrições": a produção do escrito DEVE ser exatamente como o clipe entregue ao ScriptClip (mesma largura e altura de colorspace). Seu clipe retornado pode ter comprimento diferente - mas o comprimento do "clipe" sempre é usado. O áudio do "clipe" é passado intacto. Para duas fontes muito diferentes (MPEG2DEC3 e AviSource) - você pode colidir com colorspace. Este truque é conhecido.
FrameEvaluate
(clip clip, script function, bool "after_frame")
Semelhante a ScriptClip
, exceto que a produção do filtro é ignorada.
Isto pode ser usado para designar variáveis, etc. Os quadros são passados diretamente do clipe dado.
Na v2.53 uma opção after_frame=true/false
está incluída. Isto determina se o escrito deve
ser avaliado antes (operação padrão) ou depois que o quadro viesse dos
filtros acima.
Este filtro permite importar informação arbitrária em uma variável selecionável.
Veja a página dedicada ConditionalReader.
Estas são as funções internas nas quais todo quadro é avaliado.
Estes retornarão média do valor do píxel de um
plano (requer YV12, ISSE):
AverageLuma
(clip)
AverageChromaU
(clip)
AverageChromaV
(clip)
Estes retornarão um valor flutuante entre 0 e
255 da diferença absoluta entre dois planos (requer YV12, ISSE):
RGBDifference
(clip1, clip2)
LumaDifference
(clip1, clip2)
ChromaUDifference
(clip1, clip2)
ChromaVDifference
(clip1, clip2)
Ao usar estas funções há um último clipe "implícito" (o primeiro parâmetro não precisa ser especificado), assim o primeiro parâmetro é substituído pelo testclip.
Estes devem ser muito úteis para detecção de
transições de mudanças de cena:
RGBDifferenceFromPrevious
(clip)
YDifferenceFromPrevious
(clip)
UDifferenceFromPrevious
(clip)
VDifferenceFromPrevious
(clip)
RGBDifferenceToNext
(clip)
YDifferenceToNext
(clip)
UDifferenceToNext
(clip)
VDifferenceToNext
(clip)
# Isto substituirá o último quadro antes de uma mudança de cena # com o primeiro quadro depois dessa mudança: 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 é uma porcentagem, em quanto por cento de píxeis é permitido acima ou abaixo do mínimo. O percentual é opcional e o padrão é 0.
Se você entendeu os materiais acima, pode prosseguir com "Filtragem Condicional Avançada", que vai lhe contar um pouco mais.
Você terá que saber alguns coisas sobre a funcionalidade do AviSynth para entender esta seção:
Os escritos são analisados de cima para baixo, mas quando um quadro é pedido o último filtro é invocado antes, para pedir os quadros de cima, na cadeia de filtro. Por exemplo:AviSource("myfile.avi") ColorYUV(analyze=true) Histogram()Ao abrir o escrito no Vdub acontece o seguinte
Os filtros condicionais porém, devem avaliar os escritos antes deles pedirem quadros do filtro acima, porque precisam saber qual filtro chamar. Um outro assunto importante é que só variáveis globais definidas no filtro condicional 'environment' podem ser usados fora (e vice-versa). Dê uma olhada neste escrito:
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)Esta cadeia de filtro trabalha assim:
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)Muito do escrito acima é redundante e pode ser removido. O escrito seguinte produz o mesmo
v = AviSource("c:\clip.avi") ScriptClip(v, "Subtitle(String(YDifferenceFromPrevious))")Na seção seguinte alguma info do quadro dependente será escrita a um arquivo de texto.
No exemplo seguinte, alguma info do quadro dependente será escrita num arquivo de texto.A primeira variável "a" indica se o quadro é pente (a um certo percentual). Note que IsCombed é um filtro do plugin Decomb. A segunda variável "b" indica se há muito movimento no quadro.
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)
Na seção seguinte um exemplo de "adaptive motion/resizing filter" - filtro de movimento / redimensionar adaptável - será considerado.
Alguns filtros de motion/resizing adaptáveis
apareceram nos foros. Estes filtros distinguem movimento em baixo, médio e alto
num clipe (em base de quadro). Ao fazer, diferentes filtros podem ser usados
para cada tipo diferente de movimento no clipe. Em geral, deve-se usar suavização
temporal em cenas de pouco movimento, espacial em cenas de grande movimento e
espacial-temporal em cenas de movimento médio.
Abaixo, uma versão simplificada de FILTRO de
MOVIMENTO QUANTIFICADO v1.5 b1 (10/07/2003) por HomiE FR, é dado:
---------------------------------------------------- # FILTRO DE MOVIMENTO QUANTIFICADO V1.3 # CARREGANDO PLUGINS DO AVISYNTH 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") # CARREGANDO ESCRITO DE FILTRO DE MOVIMENTO QUANTIFICADO Import("E:\temp\QMF\qmf.avs") # FUNÇÃO DE FILTRO DE POUCO MOVIMENTO # -> REDIMENSIONAMENTO AGUÇADO + SÓ TEMPORAL function Low_Motion_Filter(clip c) { c = TemporalCleaner(c, 5, 10) c = LanczosResize(c, 512, 272) return c } # FUNÇÃO DE FILTRO DE MÉDIO MOVIMENTO # -> REDIMENSIONAMENTO BICÚBICO NEUTRO + TEMPORAL & ESPACIAL function Medium_Motion_Filter(clip c) { c = FluxSmooth(c, 7, 7) c = BicubicResize(c, 512, 272, 0.00, 0.50) return c } # FUNÇÃO DE FILTRO DE GRANDE MOVIMENTO # -> REDIMENSIONAMENTO SUAVE + SÓ ESPACIAL function High_Motion_Filter(clip c) { c = FluxSmooth(c, -1, 14) c = UnFilter(c, -30, -30) c = BilinearResize(c, 512, 272) return c } # ABRINDO FONTE DE VÍDEO AviSource("E:\temp\QMF\britney-I_love_rock_'n_roll.avi") ConvertToYV12(interlaced=true) Telecide(0) # APLICANDO FILTRO DE REDIMENSIONAMENTO ADAPTÁVEL (USANDO QMF) QMF() ---------------------------------------------------- # FILTRO DE MOVIMENTO QUANTIFICADO (17/08/2003) por HomiE FR (homie.fr@wanadoo.fr) # FUNÇÃO DE ESTIMAÇÃO DE MOVIMENTO function ME() { # FIXANDO NÍVEL DE MOVIMENTO DE ACORDO COM A DIFERENÇA DA MÉDIA [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 } # FUNÇÃO DO FILTRO DE MOVIMENTO QUANTIFICADO function QMF(clip c, float "threshold_lm", float "threshold_hm", bool "debug") { # FIXANDO PERCENTUAIS DE NÍVEIS DE MOVIMENTO [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 # ATIVANDO/DESATIVANDO INFORMAÇÃO DE DEBUG [3] debug = default(debug, false) # INICIALIZANDO NÍVEL DE MOVIMENTO global motion_level = 0 # FIXANDO PRESENTE CLIPE [4] global clip = c # PEGANDO A RESOLUÇÃO DA PRODUÇÃO [5] width = Width(Low_Motion_Filter(c)) height = Height(Low_Motion_Filter(c)) global c_resized = PointResize(c, width, height) # APLICANDO O FILTRO DE MOVIMENTO DE ACORDO COM O NÍVEL DE MOVIMENTO [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] # IMPRIMINDO A INFORMAÇÃO DE DEBUG [7] c = (debug == true) ? ScriptClip(c, "Debug()") : c # PEGANDO O NÍVEL DE MOVIMENTO POR ESTIMAÇÃO DE MOVIMENTO [8] c = FrameEvaluate(c, "ME()") # PEGANDO DIFERENÇAS ENTRE QUADROS PASSADOS/PRESENTES [9] c = FrameEvaluate(c, "global diff = 0.50*YDifferenceFromPrevious(clip) + 0.25*UDifferenceFromPrevious(clip) + 0.25*VDifferenceFromPrevious(clip)") return c } # FUNÇÃO DE INFORMAÇÃO DE DEBUG function Debug(clip c) { # IMPRIMINDO A INFORMAÇÃO DA VERSÃO [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="lucida console", size=14, text_color=$FFFFFF) # IMPRIMINDO A INFORMAÇÃO DA ESTIMAÇÃO DE MOVIMENTO [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="lucida console", size=16, text_color=$FFCCCC) # IMPRIMINDO A INFORMAÇÃO DO FILTRO DE MOVIMENTO QUANTIFICADO [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 } ----------------------------------------------------Esta cadeia de filtro trabalha assim:
Foram omitidos alguns detalhes, mas isto é basicamente como o escrito trabalha.
$Date: 2006/03/26 18:11:19 $ Portuguese translation by RoLon