Aby wykorzystać
dowolną z opisanych tu metod należy zainstalować AviSynth 2.5.x oraz wyposażyć się w odpowiednie wtyczki
dostępne tutaj (ściągając każdą z nich należy wybrać
wersję dla AviSynth 2.5.x). Pliki *.dll z archiwów *.zip
poszczególnych wtyczek należy skopiować do katalogu wtyczek
AviSynth (domyślnie C:Program FilesAviSynth 2.5plugins)
- wówczas będziemy mogli się nimi posługiwać bez użycia LoadPlugin().
Zakłada się, że czytelnik zna podstawy AviSynth oraz obsługę
programu VirtualDubMod (który w dalszych rozważaniach będziemy
określać skrótem VDM).
Słowo wstępne
W zależności od źródła jego pochodzenia, możemy wyróżnić
dwa rodzaje przeplotu: "naturalny" i "sztuczny".
Przeplot "naturalny" (którego dotyczy niniejsze
opracowanie) powstaje już w trakcie filmowania - kamera nie
filmuje pełnych klatek, lecz najpierw jeden półobraz, zaś
chwilę później drugi (w ten sposób pracują kamery
telewizyjne a także amatorskie kamery cyfrowe DV). Przeplot
"sztuczny" powstaje wskutek wykonania procesu telecine,
czyli dostosowania filmu progresywnego (filmowanego
pełnowymiarowymi klatkami) do emisji w telewizji.
Dokładne omówienie wszystkich parametrów każdej opisywanej
funkcji przekracza możliwości tego opracowania. Niniejszy
artykuł ma umożliwić "szybki start" osobom chcącym
zapoznać się z metodami usuwania przeplotu w AviSynth.
Dokładnych opisów poszczególnych funkcji należy szukać na polskiej stronie AviSynth oraz na stronach dotyczących poszczególnych
wtyczek.
Przetwarzając w AviSynth materiał zawierający przeplot należy
pamiętać, że większość jego funkcji jest przystosowana do
materiałów progresywnych, zatem usuwanie przeplotu należy
zastosować jak najwcześniej w skrypcie.
UWAGA: Niedopuszczalna jest zmiana
rozdzielczości pionowej obrazu przed usunięciem przeplotu (zmiana
rozdzielczości poziomej też nie jest polecana).
1. Określanie
prawidłowej kolejności półobrazów
Działanie niektórych funkcji i wtyczek AviSynth opisywanych w
tym artykule jest uzależnione od kolejności półobrazów w
materiale żródłowym, toteż musimy ją prawidłowo określić.
Wprawdzie AviSynth sam stara się ją rozpoznać i dysponuje
wbudowaną funkcją GetParity() (zwracającą true
dla materiału TFF, zaś false dla materiału BFF), lecz
często informacja ta okazuje się nieprawdziwa.
Aby "ręcznie" określić prawidłową kolejność
półobrazów, piszemy skrypt postaci:
AVISource("ścieżkaplik.avi")
AssumeTFF()
SeparateFields()
Następnie otwieramy go w VirtualDubMod i przewijamy suwakiem
obserwując ruch. Jeśli ruch przebiega tylko w jednym kierunku (z
ewentualnymi przestojami spowodowanymi półobrazami
pochodzącymi z tej samej klatki) bez żadnych cofnięć, oznacza
to, że znaleźliśmy właściwą kolejność półobrazów -
jest to TFF, czyli półobraz górny jest zapisany jako pierwszy.
Jeśli ruch jest szarpany (po półobrazie zawierającym ruch w
prawidłowym kierunku następuje półobraz z cofnięciem),
czynność powtarzamy dla skryptu:
AVISource("ścieżkafilm.avi")
AssumeBFF()
SeparateFields()
Teraz ruch powienien już być prawidłowy, a kolejność
półobrazów to BFF - dolny półobraz jest zapisany jako
pierwszy.
Kolejność półobrazów należy zapamiętać, gdyż będziemy
ją podawać jako argument funkcjom używanym w kolejnych
przykładach.
2. Wybór metody
(a) metody "bezmyślne"
Stosowanie tych metod nie jest polecane, jednak warto o nich
wspomnieć. Ich najważniejszą zaletą jest całkowite
usunięcie artefaktów przeplotu.
odrzucenie półobrazów
Clip=AVISource("ścieżkaplik.avi")
Clip=AssumeTFF(Clip) # jeśli stwierdziliśmy TFF w punkcie
pierwszym
# Clip=AssumeBFF(Clip) jeśli stwierdziliśmy BFF w punkcie
pierwszym
Clip=SeparateFields(Clip)
Clip=SelectEven(Clip) # jeśli chcemy zachować półobrazy
parzyste
# Clip=SelectOdd(Clip) jeśli chcemy zachować półobrazy
nieparzyste
Return Clip
Metoda ta rozdziela klatki na półobrazy, po czym odrzuca co
drugi z nich. Ponieważ każdy z półobrazów pochodzi z innego
momentu w czasie, ruch w filmie straci płynność - podczas
odtwarzania będą widoczne "zacięcia". Poza tym
tracimy połowę rozdzielczości pionowej.
dwukrotne zmniejszenie w pionie
Clip=AVISource("ścieżkaplik.avi")
Clip=AssumeTFF(Clip) # jeśli stwierdziliśmy TFF w punkcie
pierwszym
# Clip=AssumeBFF(Clip) jeśli stwierdziliśmy BFF w punkcie
pierwszym
Clip=VerticalReduceBy2(Clip) # albo
# Clip=XXXResize(Width(Clip),Height(Clip)/2)
# gdzie XXX to metoda zmiany
rozdzielczości,
# np. Bilinear, Bicubic, Lanczos, Lanczos4, Point
Return Clip
Podobnie jak w przypadku poprzedniej metody, tu również tracimy
połowę rozdzielczości pionowej. Tym razem jednak klip
pozostaje w miarę płynny, jednak w dynamicznych scenach mogą
być widoczne duchy.
"głupi" bobbing
Clip=AVISource("ścieżkaplik.avi")
Clip=AssumeTFF(Clip) # jeśli stwierdziliśmy TFF w punkcie
pierwszym
# Clip=AssumeBFF(Clip) jeśli stwierdziliśmy BFF w punkcie
pierwszym
Clip=Bob(Clip)
Return Clip
Bobbing to zbiorcze określenie metod usuwania przeplotu,
które z każdego półobrazu tworzą osobną klatkę. "Głupi"
bobbing (w przeciwieństwie do "mądrego") nie
bierze w tym procesie pod uwagę informacji z innych
półobrazów. Funkcja Bob() w
AviSynth rozdziela półobrazy klipu (jeśli przedtem nie
zostały rozdzielone funkcją SeparateFields()), a następnie powiększa je metodą
analogiczną do BicubicResize() (patrz dokumentacja AviSynth). Dolne półobrazy są w tym procesie
podnoszone o jedną linię, aby zapobiec efektowi skakania obrazu,
jednak niewielkie drżenie wciąż jest widoczne. Domyślnie Bob() powiększa każdy półobraz dwukrotnie
nadając mu wysokość pełnej klatki klipu, jednak możemy to
zmienić ustawiając parametr height:
Clip=AVISource("ścieżkaplik.avi")
Clip=AssumeTFF(Clip) # jeśli stwierdziliśmy TFF w punkcie
pierwszym
# Clip=AssumeBFF(Clip) jeśli stwierdziliśmy BFF w punkcie
pierwszym
Clip=Bob(Clip,height=448)
Return Clip
Bob() umożliwia też zmianę parametrów b i c
funkcji BicubicResize(). Jeśli chcemy użyć tzw. "neutral
bicubic" zamiast domyślnego "soft bicubic",
piszemy:
Clip=AVISource("ścieżkaplik.avi")
Clip=AssumeTFF(Clip) # jeśli stwierdziliśmy TFF w punkcie
pierwszym
# Clip=AssumeBFF(Clip) jeśli stwierdziliśmy BFF w punkcie
pierwszym
Clip=Bob(Clip,b=0,c=0.5)
Return Clip
Zamiast wbudowanej w AviSynth funkcji Bob() możemy użyć IBob() Kevina Atkinsona:
LoadCPlugin("ścieżkaIBob.dll")
Clip=AVISource("ścieżkaplik.avi")
Clip=AssumeTFF(Clip) # jeśli stwierdziliśmy TFF w punkcie
pierwszym
# Clip=AssumeBFF(Clip) jeśli stwierdziliśmy BFF w punkcie
pierwszym
Clip=IBob(Clip)
Return Clip
IBob() nie ma dodatkowych parametrów i (w
przeciwieństwie do Bob())
nie zmienia linii pochodzących ze źródłowego półobrazu (nie
dotyczy to YV12, gdzie wartość chrominancji ulega zmianie),
ponieważ używa interpolacji liniowej do stworzenia brakujących
linii. Należy pamietać, że IBob.dll jest wtyczką
napisaną w języku programowania C i w przeciwieństwie do
"zwykłych" wtyczek AviSynth (pisanych w C++) musi być
ładowana "ręcznie" przy użyciu funkcji LoadCPlugin() z wtyczki AviSynth_C.dll.
Wadą "głupiego" bobbingu jest podwojenie
ilości klatek na sekundę (FPS) oraz strata rozdzielczości
pionowej (ponieważ każda klatka takiego klipu to powiększony
półobraz).
"zlewanie" półobrazów
#
LoadPlugin("ścieżkampeg2dec.dll") jeśli używamy
nowszej wersji,
# np. mpeg2dec3.dll lub dgdecode.dll
Clip=AVISource("ścieżkaplik.avi")
Clip=AssumeTFF(Clip) # jeśli stwierdziliśmy TFF w punkcie
pierwszym
# Clip=AssumeBFF(Clip) jeśli stwierdziliśmy BFF w punkcie
pierwszym
# ConvertToYUY2(interlaced=true) jeśli materiał jest w YV12
Clip=BlendFields(Clip)
Return Clip
Metoda polega na "zlaniu" obu półobrazów w jedną
klatkę. Wyobraźmy sobie trzy poziome linie obrazu:
a1 a2 a3 a4
a5 ...
b1 b2
b3 b4 b5 ...
c1 c2
c3 c4 c5 ...
Wartość b1 zostanie zastąpiona przez 0.25*a1 + 0.5*b1 + 0.25*c1.
Proces ten zostanie powtórzony dla każdego piksela linii b, zaś później w ten sam sposób
zostaną potraktowane pozostałe linie obrazu.
Metoda ta powoduje widoczną utratę ostrości obrazu oraz "duchy"
w dynamicznych scenach podobne do tych powstających przy
dwukrotnym zmniejszeniu rozdzielczości pionowej. Funkcja BlendFields() pochodzi z przestarzałej wtyczki mpeg2dec.dll
i nie obsługuje przestrzeni kolorów YV12.
(b) metody "inteligentne"
"Inteligentne" metody usuwania przeplotu starają się
wykryć i usunąć artefakty przeplotu obecne w klatce
zachowując bez zmian te obszary klatki, w których takich
artefaktów nie wykryły. Pomaga to zachować dużą
rozdzielczość pionową i ostrość obrazu.
TomsMoComp()
Clip=AVISource("ścieżkaplik.avi")
Clip=AssumeTFF(Clip) # jeśli stwierdziliśmy TFF w punkcie
pierwszym
# Clip=AssumeBFF(Clip) jeśli stwierdziliśmy BFF w punkcie
pierwszym
Clip=TomsMoComp(Clip,?,15,1)
# parametr ? ustawiamy na 1 dla TFF, 0 dla BFF
Return Clip
Filtr TomsMoComp() odtwarza brakujące linie w obszarach
zawierających artefakty przeplotu poprzez poszukiwanie i
kompensację ruchu w tych obszarach. Pełna lista parametrów to TomsMoComp(TopFirst,SearchEffort,VerticalFilter), gdzie TopFirst to kolejność półobrazów w źródle (1 to TFF,
0 to BFF, patrz punkt 1), SearchEffort to dokładność algorytmu poszukiwania ruchu (dozwolone
wartości to 0, 1, 3, 5, 9, 11, 13, 15, 19, 21, 30, im wyższa
wartość tym bardziej dokładne poszukiwanie ruchu, wartości
powyżej 15 nie zalecane ze względu na duże zapotrzebowanie na
moc procesora), zaś VerticalFilter to decyzja o użyciu filtra zlewającego dwie
sąsiednie poziome linie w celu usunięcia resztek artefaktów
przeplotu (1 - używamy filtra, 0 - nie używamy).
GreedyHMA()
Pojęcie grupy algorytmów "zachłannych" wykracza poza
ramy tego tekstu, przejdźmy więc od razu do rzeczy: idea polega
na wykorzystaniu algorytmu tego typu w procesie poszukiwania
obszarów zawierających artefakty przeplotu oraz podczas
interpolacji brakujących danych (linii jednego z półobrazów)
w tych obszarach. Taką metodę usuwania przeplotu implementuje
filtr GreedyHMA() Toma Barry'ego. Jego możliwości są
znacznie większe, niż zwykły deinterlacing i obejmują
również odwracanie skutków procesu telecine, jednak w
niniejszym artykule ograniczymy się do omówienia jego
zastosowania podczas obróbki materiałów zawierających "naturalny"
przeplot.
Clip=AVISource("ścieżkaplik.avi")
Clip=AssumeTFF(Clip) # jeśli stwierdziliśmy TFF w punkcie
pierwszym
# Clip=AssumeBFF(Clip) jeśli stwierdziliśmy BFF w punkcie
pierwszym
# ConvertToYUY2(interlaced=true) jeśli materiał nie jest w YUY2
Clip=GreedyHMA(Clip,?,1,0,0,0,0,0,0)
# parametr ? ustawiamy na 1 dla TFF, 0 dla BFF
Return Clip
Pełna lista parametrów funkcji GreedyHMA() to:
TopFirst - jak w opisie TomsMoComp().
SwapFields - każe filtrowi zamienić linie parzyste
(0, 2, 4, ...) z nieparzystymi (1, 3, 5, ...). Służy to do
naprawy błędów powodowanych przez wadliwe dekompresory, które
nieprawidłowo ustawiają linie obrazu podczas dekompresji (półobraz
górny wyświetlają jako dolny, zaś dolny jako górny).
Dozwolone wartości to 0 (nie zamieniaj) i 1 (zamień).
AutoPullDown - mówi filtrowi, czy ma traktować
materiał wejściowy jak klip wideo (zawierający "naturalny"
przeplot) czy klip progresywny (zawierający "sztuczy"
przeplot wskutek telecine). Dozwolone są wartości od 0
do 5, jednak nas interesuje tylko wartość 0 (każąca
traktować przeplot jako "naturalny").
MedianFilter - parametr jest ignorowany w aktualnej
wersji GreedyHMA(). Dotyczy on odszumiania poprzez
filtrowanie czasowe. Funkcja ta jest obecnie wyłączona.
VerticalFilter - jak w opisie TomsMoComp().
EdgeEnhance - wzmocnienie krawędzi w celu
wyostrzenia obrazu. Dozwolone wartości to 2-100 (imi wyższa,
tym silniejsze filtrowanie), 0 (wyłączone), 1 (użyj domyślnej
wartości siły filtrowania, czyli 50).
GoodPullDownLvl - wartość związana z odwracaniem
procesu telecine. Nie interesuje nas, ponieważ jest
ignorowana dla AutoPullDown=0.
BadPullDownLvl - wartość związana z odwracaniem
procesu telecine. Nie interesuje nas, ponieważ jest
ignorowana dla AutoPullDown=0.
Należy wiedzieć, że GreedyHMA() pracuje tylko w przestrzeni kolorów YUY2 oraz
zakłada, że klatki nie są rozdzielone na półobrazy. Jeśli
wykonaliśmy SeparateFields() w celu rozdzielenia półobrazów, musimy
posłużyć się Weave()
aby znów je "spleść". Do konwersji materiału do
przestrzeni kolorów YUY2 wykorzystujemy ConvertToYUY2(interlaced=true).
FieldDeinterlace()
Filtr FieldDeinterlace() Donalda Grafta wyszukuje artefakty
przeplotu i usuwa je metodą wybraną przez użytkownika (poprzez
zlewanie lub interpolację). Jako jedyny umożliwia on
wykorzystanie pliku z podpowiedziami dotyczącymi poszczególnych
klatek oraz potrafi nałożyć na obraz mapę "przeplecionych"
obszarów klatki aby pomóc w ustaleniu optymalnych wartości
niektórych parametrów.
Najprostszym sposobem użycia FieldDeinterlace() jest skrypt postaci:
Clip=AVISource("ścieżkaplik.avi")
Clip=AssumeTFF(Clip) # jeśli stwierdziliśmy TFF w punkcie
pierwszym
# Clip=AssumeBFF(Clip) jeśli stwierdziliśmy BFF w punkcie
pierwszym
Clip=FieldDeinterlace(Clip)
Return Clip
Najlepsze rezultaty uzyskamy jednak dostosowując wartości
poszczególnych parametrów do konkretnego źródła.
full - wartość true (domyślna)
sprawia, że wszystkie klatki są przetwarzane. Wartość false
powoduje, że przetwarzane są tylko klatki uznane za
zawierające artefakty przeplotu (patrz parametr threshold). Użycie false może być
uzasadnione, gdy klip zawiera fragmenty progresywne (patrz artykuł o IVTC).
threshold - dozwolone są wartości 0-255 (domyślnie
20). Jest to próg wykrywania artefaktów przeplotu stosowany,
gdy full=false (inaczej jest ignorowany).
Dostosowanie wartości tego parametru do źródła może znacznie
polepszyć rezultat końcowy (im wyższa wartość, tym więcej
artefaktów klatka musi zawierać, aby została uznana za "przeplecioną").
dthreshold - dozwolone są wartości 0-255 (domyślnie
7). Jest to próg usuwania artefaktów przeplotu z klatki (im
wyższy, tym bardziej widoczne muszą być artefakty, aby
zostały usunięte). Należy pamiętać, że gdy full=false, przeplot jest usuwany tylko
z klatek uznanych za "przeplecione" na podstawie
parametru threshold. Dostosowanie dthreshold do źródła ma duże znaczenie dla
efektu końcowego (domyślna wartość 7 może się okazać za
niska).
blend - wartość true (domyślna)
oznacza, że w obszarach, w których wykryto artefakty przeplotu
zostanie zastosowane "zlewanie" linii. Wartość false
każe zastosować w tych obszarach interpolację. "Zlewanie"
wykorzystuje informacje z danej linii poziomej oraz dwóch
sąsiadujących z nią i przetwarza w ten sposób każdą z linii
- tworzy to "duchy" w przetwarzanym obszarze.
Interpolacja pozostawia parzyste linie bez zmian, zaś w
nieparzystych odrzuca informacje ze źródła i używa wartości
średniej obliczonej na podstawie dwóch linii parzystych
sąsiadujących z nieparzystą. Wykorzystanie interpolacji jest
wskazane, gdy w klipie nie ma bardzo dynamicznych scen (interpolacja
może spowodować w nich niewielkie "zacięcia" podczas
odtwarzania), zaś "zlewanie" zachowuje trochę
większą płynność.
map - wartość true każe nałożyć
na obraz mapę obszarów, w których wykryto artefakty przeplotu,
zaś wartość false (domyślna) zapobiega temu. Mapa jest
bardzo użyteczna podczas ustalania optymalnych wartości
parametrów threshold i dthreshold dla klipu. Gdy seledynowe plamy mapy pojawiają
się w obszarach nie zawierających widocznego przeplotu,
wskazane jest zwiększenie dthreshold, zaś gdy widzimy artefakty przeplotu w obszarach
nie zaznaczonych kolorem seledynowym, zmniejszamy dthreshold.

chroma - wartość true powoduje, że
informacje z płaszczyzny chrominancji (koloru) są brane pod
uwagę przy podejmowaniu decyzji, czy klatka zawiera artefakty
przeplotu (gdy używamy full=false,
bo w przeciwnym wypadku parametr chroma jest ignorowany). Wartość false każe
ignorować chrominację w tym procesie decyzyjnym. Bez względu
na wartość tego parametru artefakty przeplotu są usuwane z
płaszczyzny chrominancji.
ovr - wartość to nazwa pliku tekstowego
zawierającego podpowiedzi dla FieldDeinterlace(). Plik musi znajdować się w tym samym
katalogu, co skrypt, zaś jego nazwę musimy ująć w cudzysłów,
np. ovr="override.fd". Plik
zawiera numery klatek oraz (po spacji) symbol + (oznaczający, że klatka zawiera
artefakty przeplotu) lub - (każący
uznać klatkę za pozbawioną takich artefaktów). Jeśli na
przykład chcemy powiedzieć FieldDeinterlace(), że klatki 200-300 oraz klatka 450 nie
są "przeplecione", zaś klatki 350-400 zawierają
artefakty, tworzymy edytorem tekstowym (np. Notatnikiem) plik override.fd
postaci:
200-300 -
350-400 +
450 -
a następnie używamy skryptu:
Clip=AVISource("ścieżkaplik.avi")
Clip=AssumeTFF(Clip) # jeśli stwierdziliśmy TFF w punkcie
pierwszym
# Clip=AssumeBFF(Clip) jeśli stwierdziliśmy BFF w punkcie
pierwszym
Clip=FieldDeinterlace(Clip,full=false,ovr="override.fd")
Return Clip
show - wartość true każe
wyświetlać na każdej klatce Clean frame (jeśli klatka
została uznana za "czystą" - nie zawierającą
artefaktów przeplotu) lub Combed frame! (jeśli klatka
została uznana za "splecioną"). Dzieje się tak tylko
dla full=false, zaś dla full=true zobaczymy napis Deinterlacing
all frames. Parametr show ma
nam pomóc w ustaleniu odpowiedniej wartości threshold - gdy "splecione" klatki
zawierają napis Clean frame należy obniżyć threshold, zaś gdy na "czystych"
klatkach jest napis Combed frame!, zwiększamy threshold.

debug - wartość true powoduje
wysyłanie informacji na temat działania FieldDeinterlace() przeznaczonych dla programu DebugView.
Podczas normalnej pracy są one nieprzydatne - mają wartość
jedynie dla programistów.
Wartą zauważenia cechą FieldDeinterlace() jest możliwość zastosowania podpowiedzi
dotyczących każdej klatki, czego nie udostępniają inne
funkcje. Możliwość wyboru pomiędzy zlewaniem a interpolacją
oraz pomijanie klatek w których nie wykryto artefaktów
przeplotu czynią ten filtr jeszcze bardziej atrakcyjnym.
KernelDeint()
Clip=AVISource("ścieżkaplik.avi")
Clip=AssumeTFF(Clip) # jeśli stwierdziliśmy TFF w punkcie
pierwszym
# Clip=AssumeBFF(Clip) jeśli stwierdziliśmy BFF w punkcie
pierwszym
Clip=KernelDeint(Clip,order=?)
# parametr ? ustawiamy na 1 dla TFF, 0 dla BFF
Return Clip
W przeciwieństwie do FieldDeinterlace(), KernelDeint() interpoluje brakujące informacje używając
sąsiednich linii tej samej klatki oraz tej samej linii z
poprzedniej klatki (a także z następnej, jeśli użyjemy twoway=true), dzięki czemu lepiej
imituje efekt rozmazania ruchu obecny w filmach kinowych.
Pełna lista parametrów to:
order - kolejność półobrazów w źródle (1
to TFF, 0 to BFF, patrz punkt 1). Ustawienie tego
parametru jest konieczne, ponieważ filtr używa informacji z
poprzednich i następnych klatek (w przeciwieństwie do FieldDeinterlace()).
threshold - działa jak dthreshold w FieldDeinterlace(). Wartości to 0-255, domyślnie 10.
sharp - wartość true sprawia, że
filtr stosuje dodatkowe wyostrzanie obrazu i stara się lepiej
zachować rozdzielczość pionową. Domyślna wartość to false.
twoway - wartość true każe użyć
informacji zarówno z poprzedniej, jak i nastepnej klatki, co
może spowolnić pracę i spowodować bardziej rozmazany obraz w
przetwarzanych obszarach. Domyślna wartość to false.
map - analogicznie jak w FieldDeinterlace(). Pomaga przy dobieraniu optymalnej
wartości threshold.

debug - analogicznie jak w FieldDeinterlace().
Brak możliwości pomijania klatek nie zawierających artefaktów
przeplotu oraz użycia pliku z podpowiedziami trochę
zmniejszają atrakcyjność tej funkcji w stosunku do FieldDeinterlace(). Należy też wiedzieć, że czasem
wskutek jego zastosowania klatka po zmianie sceny może zawierać
"duchy". Na korzyść KernelDeint() świadczy fakt, że efekt jego zastosowania jest
zbliżony do rozmazania ruchu typowego dla filmów progresywnych.
DGBob()
Trzeci z kolei filtr Donalda Grafta oraz pierwszy w tym
zestawieniu, który stosuje "mądry" bobbing.
Różni się on od "głupiego" tym, że zamiast po
prostu powiększyć każdy półobraz do rozmiaru pełnej klatki,
używa informacji z drugiego półobrazu tej samej klatki tam,
gdzie nie powoduje to artefaktów przeplotu, co daje wysoką
rozdzielczość pionową obrazu (zachowuje więcej jego
szczegółów).
Clip=AVISource("ścieżkaplik.avi")
Clip=AssumeTFF(Clip) # jeśli stwierdziliśmy TFF w punkcie
pierwszym
# Clip=AssumeBFF(Clip) jeśli stwierdziliśmy BFF w punkcie
pierwszym
Clip=DGBob(Clip,order=?)
# parametr ? ustawiamy na 1 dla TFF, 0 dla BFF
Return Clip
Pełna lista parametrów to:
order - analogicznie jak w KernelDeint()
mode - określa tryb postępowania po
wykonaniu "mądrego" bobbingu. Wartość 0 każe
zachować pierwotną ilość klatek na sekundę poprzez
odrzucenie nieparzystych klatek (odpowiednik DGBob(mode=1).SelectEven()), wartość 1 (domyślna) zachowuje
podwójny FPS, zaś wartość 2 przywraca pierwotny FPS poprzez
dwukrotne spowolnienie klipu (odpowiednik DGBob(mode=1).AssumeFPS(FrameRate()/2)).
thresh - próg usuwania artefaktów przeplotu.
Im wyższy, tym częściej DGBob()
będzie zachowywać informacje z drugiego półobrazu tej samej
klatki zamiast interpolować brakujące linie wykorzystując
aktualny półóbraz. Dozwolone wartości to 0-255, domyślna 12.
Wyższe wartości thresh
zachowują więcej szczegółów obrazu, lecz zwiększają ryzyko
pozostania w nim artefaktów przeplotu. Niższe wartości
zapobiegają występowaniu artefaktów przeplotu, lecz wzmagają
drżenie obrazu w obszarach zawierających linie poziome nie
spowodonane przeplotem, szczególnie w znakach graficznych (takich
jak logo stacji telewizyjnej) nałożonych na obraz. W celu
uzyskania najlepszego efektu optymalną wartość tego parametru
należy ustalić eksperymentalnie.
ap - wartość true uruchamia
dodatkowe procedury wykrywania artefaktów. Korzystamy z tej
opcji tylko, gdy jest to absolutnie konieczne, gdyż może ona
zwiększać drżenie obrazu. Domyślnie false.
Zaletą "mądrego" bobbingu jest bardzo dobra
płynność ruchu przy jednoczesnym zachowaniu dużej ilości
szczegółów obrazu. Problem może stanowić podwojona ilość
klatek na sekundę, która znacznie zwiększa zapotrzebowanie na
bity podczas kompresji. Nie można też zapomnieć o tym, że
wymagania wobec procesora podczas dekodowania takiego klipu
będą duże, zatem warto pomyśleć o użyciu mniejszej
rozdzielczości.
SmoothDeinterlace()
Kolejna funkcja stosująca "mądry" bobbing.
Clip=AVISource("ścieżkaplik.avi")
Clip=AssumeTFF(Clip) # jeśli stwierdziliśmy TFF w punkcie
pierwszym
# Clip=AssumeBFF(Clip) jeśli stwierdziliśmy BFF w punkcie
pierwszym
# ConvertToYUY2(interlaced=true) jeśli materiał jest w YV12
Clip=SmoothDeinterlace(Clip,tff=?,doublerate=true)
# parametr ? ustawiamy na true dla TFF, false dla BFF
Return Clip
Parametry:
tff - ustawiamy true dla TFF, false
dla BFF (patrz punkt 1 artykułu). Domyślnie jest to
wartość rozpoznana przez AviSynth (ta, która jest zwracana
przez GetParity()).
doublerate - wartość true każe zastosować
prawdziwy "mądry" bobbing (zwrócenie
podwojonej ilości klatek na sekundę), false (domyślna)
usuwa artefakty przeplotu z obszarów, w których zostały
wykryte bez zmiany FPS.
blend - analogiczny do parametru o tej samej
nazwie w FieldDeinterlace(), z ta różnicą, że tu domyślną
wartością jest false.
lacethresh - odpowiednik dthreshold z FieldDeinterlace(). Domyślna wartość to 24.
edgethresh - próg rozróżniania pomiędzy
prawdziwymi brzegami, a artefaktami przeplotu. Im wyższy, tym
więcej brzegów pozostawiamy bez zmian. Wartości 0-255,
domyślnie 20.
staticthresh - próg wykrywania obszarów statycznych.
Wartość ta określa, jak bardzo punkt musi się różnić od
swojego otoczenia, aby nie można juz go było uznawać za
statyczny. Należy użyć najniższej wartości, przy której nie
widać artefaktów przeplotu (dla klipów dobrej jakości oraz
nie zawierających nałożonego logo można uzywac bardzo niskich
wartości). Dozwolone są wartości 0-255, domyślna to 35.
Wartości powyżej 50 nie są polecane.
staticavg - określa ilość danych pochodzących z
poprzednich klatek przechowywanych w celu ustalania, czy dany
punkt jest statyczny. Niska wartość może szybciej znaleźć
statyczne obszary, lecz decyzja ta może się okazać niepoprawna
i spowodować pozostanie artefaktów przeplotu w obrzie. Wysoka
wartość może spowodować drżenie w obszarach statycznych oraz
opóźnić reakcję na powstanie ruchu w uprzednio statycznym
obszarze. Dozwolone wartości to 0-100, domyślnie 80. Zalecane
jest, aby staticavg był równy lub większy od 2*staticthresh.
showlace - wartość true nakłada na obraz
mapę służącą do ustalania optymalnych wartości parametrów lacethresh, edgethresh, staticthresh i staticavg.
Kolorem czerwonym zaznaczone są obszary, z których są usuwane
artefakty przeplotu. Niebieskie są obszary uznane za statyczne,
z których artefakty przeplotu zostaną usunięte, jeśli
zostaną tam wykryte. Kolor jaskrawozielony oznacza obszar
statyczny, w którym wykryto artefakty przeplotu, lecz ich nie
usunięto. Miejsca statyczne bez artefaktów przeplotu zaznaczone
są barwą szarozieloną. Naszym celem jest zredukowanie do
minimum występowania obszarów jaskrawozielonych poprzez
stopniowe zwiększanie lacethresh i edgethresh zdając jednocześnie, aby obszary zawierające
artefakty przeplotu wciąż były zaczerwienione.

log - wartość true powoduje
zapisywanie numerów klatek i procentu obszarów zawierających
artefakty przeplotu z pliku (w katalogu, w którym znajduje się
skrypt), którego nazwę określamy parametrem logfile. Zapisywane są tylko numery klatek, w
których odsetek obszarów "przeplecionych" jest
większy od wartości parametru logpercent. Domyślnie false.
logpercent - wartości zmiennoprzecinkowe 0.0-100.0
(domyślnie 0.0). Jest to odsetek obszarów zawierających
artefakty przeplotu, który musi zostac przekroczony w danej
klatce, aby jej numer został zanotowany w pliku opisywanym
wyżej przy parametrze log.
logfile - nazwa pliku opisywanego przy parametrze
log (ujęta w cudzysłów). Domyślnie "SmoothDeinterlace.log".
Plik ten powstaje w katalogu, w którym znajduje się nasz skrypt.
SmoothDeinterlace() ma przewagę nad DGBob(), jeśli chodzi o ilość dostępnych
parametrów, których dostosowanie polepsza rezultat końcowy
oraz umozliwa zastosowanie wielokolorowej mapy ułatwiającej to.
Jedynym mankamentem tego filtra jest brak możliwości pracy w
przestrzeni kolorów YV12 (patrz też GreedyHMA()).
Epilog
Niniejsze zestawienie filtrów AviSynth usuwających artefakty
przeplotu nie jest kompletne - pominięte zostały przestarzałe
wersje niektórych z nich, np. SmartDeinterlace() i MaskedDeinterlace() Donalda Grafta, które zostały zastąpione przez FieldDeinterlace().
Ponieważ materiały wideo zawierają półobrazy pochodzące z
różnych chwil w czasie, najkorzystniejszą metodą usuwania
artefaktów wydaje się "mądry" bobbing, jednak
gdy musimy liczyć się z ograniczoną mocą procesora, warto
rozważyć wykorzystanie jednej z metod zachowujących
oryginalną ilość klatek na sekundę. Użycie metod "bezmyślnych"
(nieadaptacyjnych) zasadniczo nie jest polecane - nawet gdy
brakuje nam czasu na odnalezienie optymalnych wartości
parametrów metod "inteligentnych" (adaptacyjnych),
warto wykorzystać jedną z nich pozostawiając domyślne
wartości parametrów.
Artykuł dostępny jest również w formie dokumentu PDF
Aby ściągnąć plik skorzystaj z menu kontekstowego myszy i opcji Zapisz element docelowy jako... |