2018-01-09

Návrat barevné princezny

V roce 2014 jsem se tady pustil do výkladu, proč není možné automaticky vyrobit barevnou verzi černobílého filmu a vytvořil jsem na ukázku jeden barevný obrázek z pohádky Pyšná princezna. Už tehdy jsem byl v pokušení vyrobit i nějaké kratší video, ale od toho mě spolehlivě odradila představa, kolik by s tím bylo práce.

Myšlenka ve mně ale stále hlodala, a tak jsem později podnikl kratší pokus o kolorování v programu Adobe After Effects, který však nesplnil moje očekávání. Barvy se tam definují v jednotlivých barevných složkách jako změny od původní šedé, takže je dost obtížné trefit správný odstín. Navíc každá barevná oblast je definovaná pomocí uzavřených křivek a řídicích bodů, což sice umožňuje tvar oblastí v animaci mezi několika políčky poměrně snadno interpolovat (tj. není nutné oblast upravovat úplně pro všechna políčka), ale současně to komplikuje tvorbu jemnějších barevných odstínů, protože každý barevný odstín musí mít definovanou samostatnou barevnou oblast - i kdyby to měl být jen bod o velikosti jednoho pixelu. Stále jsem měl pocit, že by mělo být možné dosáhnout mnohem lepšího výsledku v nějakém bitmapovém editoru, ale to by bylo nutné postupovat doslova políčko po políčku...

Loni jsem konečně zaregistroval existenci programu FFMPEG, který mimo jiné umí z videa exportovat jednotlivá políčka, a znovu mi to připomnělo Pyšnou princeznu. Pár sekund videa bych takhle obarvit mohl, ne?

Akce se bohužel nevyhnutelně vymkla kontrole a tohle je výsledek... Slovy klasika: "Tolik práce a přitom taková blbost." =)

Pokud náhodou trpíte nadbytkem volného času a chtěli byste si něco podobného taky zkusit, tak dále následují technické podrobnosti a "veselé příhody z natáčení":

Pro celý pokus bylo důležité vybrat z filmu vhodnou scénu. Chtěl jsem aby byla dostatečně ikonická a současně dost statická, protože jsem tušil, že čím méně bude ve scéně pohybu, tím snáze se bude kolorovat. Nakonec tedy padla volba na scénu, kdy Krasomila pod Miroslavovým dohledem vybrnkává písničku Rozvíjej se poupátko. Celá má 55 vteřin, ale předpokládal jsem, že z ní použiju jen část.

FFMPEG umí snímky exportovat ve formátu BMP a JPEG, z nichž mi ani jeden nevyhovoval. JPEG používá ztrátovou kompresi, takže při exportu snímků dojde nevyhnutelně k jejich zkreslení, a BMP nepoužívá žádnou kompresi, takže soubory jsou zbytečně velké a komplikují tak jakýkoliv přenos dat. FFMPEG by měl umět i export do formátu PNG (24 bit, bezztrátová komprese), ale ten mi z neznámých důvodů nefungoval, takže jsem nakonec místo pátrání po příčinách nejprve provedl export do BMP a získal tak necelých 1400 obrázků v rozlišení 1920x1080, které dohromady zabíraly zhruba 9 GB. Pyšná princezna ale nebyla natočena ve formátu 16 x 9, ale 1,37 x 1, takže na bocích byly černé pruhy. Pomocí masové konverze (FastStone Image Viewer) jsem tedy obrázky nechal ořezat a zkonvertovat do formátu PNG a dostal se tak na únosnějších 1,5 GB v rozlišení 1490 x 1080. (Teoreticky to mělo být 1480 x 1080, ale horní a dolní okraje byly zřejmě trochu ořezány při digitalizaci.)

Pak jsem se s vervou pustil do díla ve Photoshopu. Začal jsem od políčka, které už jsem měl hotové z roku 2014, trochu ho doladil a pokračoval na následující. Šlo to *poměrně* dobře, protože po sobě jdoucí políčka si jsou dost podobná, takže stačilo vzít barevné vrstvy z předchozího políčka, odpovídajícím způsobem s nimi trochu pohnout, opravit nepřesnosti na krajích barevných ploch, které nevyhnutelně vznikají, a výsledek uložit. Za večer jsem tímhle způsobem vyčistil a obarvil asi deset políček, takže kdybych chtěl stejným způsobem pokračovat dále, tak by mi minutová scéna zabrala zhruba půl roku.

Bylo zřejmé, že podobným postupem dokážu obarvit skutečně maximálně pár sekund filmu, což mě od dalšího pokračování stejným způsobem odradilo.

Místo toho jsem začal přemýšlet jiným směrem. Změny mezi jednotlivými políčky jsou často poměrně malé a sám jsem postupoval tak, že jsem srovnal dvě černobílá políčka a pak odpovídajícím způsobem upravil barevnou masku prvního políčka do podoby toho druhého. Kdyby existoval program, který dokáže poznat, jak se první černobílé políčko změnilo na to druhé (co se kam pohnulo), tak by měl být schopen stejným způsobem změnit i tu barevnou masku...

O žádném takovém programu jsem nevěděl, ale experimentální pokušení nakonec zvítězilo a pustil jsem se do programování (Visual Studio a C#). Výsledkem byl jednoduchý program Frankensteiner (na jméno jsem obzvlášť hrdý ;) spouštěný z příkazové řádky, který načetl dva stejně velké obrázky ve formátu PNG, rozdělil je na čtverečky o rozměrech 10 x 10 pixelů a snažil se druhý obrázek sestavit ze čtverečků prvního obrázku tak, aby byl výsledek co nejpodobnější. První verze obsahovala ve výpočtech podobnosti dost chyb, ale i tak vypadaly první pokusné výsledky mnohem lépe, než jsem se obával, a tak jsem v pokusech pokračoval.

Zhruba o týden později jsem měl opravenou a lépe vyladěnou verzi (výpočet jednoho políčka obvykle trval méně než minutu), jejíž výsledky vypadaly mnohem lépe, než jsem doufal, a tak jsem přidal i transformaci barevné masky. Ta bohužel vypadala o něco hůře (na okrajích barevných ploch se barevné pixely vždy trochu promíchaly), ale i tak jsem výsledek zhodnotil jako uspokojivý a rozhodl se, že obarvím celou brnkací scénu. Postup měl vypadat tak, že vždy nechám spočítat sekvenci několika obrázků dopředu, zkontroluju výsledek a až dorazím k obrázku, kde barevné chyby přesáhnout nějakou únosnou mez, tak vygenerovanou barevnou masku ručně upravím a nechám od tohohle políčka spočítat další sekvenci. Podle prvních testů to vypadalo, že "klíčový snímek" bude třeba udělat přibližně jednou za 10 až 20 políček, což vypadalo dost optimisticky.

Brzy jsem ale narazil na další komplikace. Původní film je starý a dost poškrábaný a škrábance nevyhnutelně zvyšovaly nespolehlivost spočítaných výsledků, takže bylo třeba se jich nejprve zbavit. Na každém políčku bylo podobných obrazových chyb několik (malá zrnka prachu, větší fleky zřejmě z laboratoře, svislé škrábance z promítačky a podobně), takže v celé sekvenci bylo celkem několik tisíc (!) chyb, které volaly po nápravě.

Pro opravu podobných chyb na fotografiích se obvykle používá algoritmus, který hledá náhlé ostré přechody barvy nebo jasu a trochu je změkčí, čímž se ale nevyhnutelně změní i spousta míst, která by se změnit neměla. Tomu jsem se ale chtěl vyhnout, a tak jsem si napsal další jednoduchý program jménem Duster, který opravoval chyby na základě předchozího a následujícího snímku. Vždy nejprve mezi sebou porovnal sousední snímky a oblasti, ve kterých se příliš nelišily, si označil jako "spolehlivé" a s jejich průměrem pak srovnával a případně upravoval prostřední snímek. Abych zabránil nežádoucím "opravám", jsem "spolehlivé" oblasti vždy preventivně ještě trochu zmenšil a projel jsem programem všechny černobílé snímky. Tím se mi povedlo opravit přibližně 75 % původních kazů, ale zbývalo ještě dost chyb, které byly příliš velké (algoritmus nebyl schopen rozlišit velký flek od skutečného objektu), škrábance táhnoucí se přes několik políček, málo kontrastní skvrny nebo kazy v částech snímku, kde se ve filmu něco pohybovalo).

Další část chyb jsem eliminoval pomocí kombinace Frankensteineru a Dusteru. Všechna políčka jsem nechal rekonstruovat z jejich sousedů, čímž v rekonstruovaných verzích zmizely drobné chyby, a tyhle hybridy jsem pak použil jako falešné sousedy pro druhý průchod Dusterem. Tím jsem se zbavil zhruba poloviny zbývajících chyb (většinou těch menších v pohyblivých oblastech) a na ty zbývající (cca 10-15 % původního počtu) už jsem bohužel musel nasadit individuální přístup a opravovat je ručně, což zabralo několik dnů.

Během oprav a srovnávání různých metod opravy jsem měl bohužel dost času jednotlivá políčka porovnat a všimnout si všech nedostatků, kterými vstupní materiál trpí. Je jich dost: během digitalizace došlo k nějakému přepočtu políček (původní film má pravděpodobně 24 FPS, televizní vysílání 25 FPS (50i)), což způsobilo kolísání zrnitosti a překopírování některých kazů původního filmu z jednoho filmového políčka na dvě digitální.

Kromě toho je patrné, že při digitalizaci nebyl film vždy dokonale rovný, takže se obraz v některých místech mírně deformuje a vlní a zřejmě není náhoda, že je u těchhle prohnutých políček často patrný i svislý škrábanec. A to nemluvím o drobných otřesech kamery, které jsou zřejmě zaznamenané už na původním negativu...

Část těchhle chyb jsem se pokusil opravit nebo alespoň zkorigovat, ale ne vždy to bylo možné. Pro "seriózní" výsledek by samozřejmě bylo třeba začít novým nascanováním původního filmu ve velkém rozlišení skutečně políčko po políčku a nedělat žádný přepočet snímkovací frekvence. Ještě lepší by asi bylo zkombinovat několik distribučních kopií (neměly by mít škrábance na stejných místech), ale to jsem v amatérských podmínkách samozřejmě neměl k dispozici.

V dalším kroku bylo třeba spojit černobílá políčka s barevnou maskou, což by bylo u 1400 políček ručně dost ubíjející, a tak vznikl další jednoúčelový program jménem Colorizer. Původně jsem chtěl, aby používal naprosto stejný způsob výpočtu jako Photoshop (což jsem samozřejmě trefoval experimentálně), ale během pokusů jsem se dobral parametrické křivky, která byla trochu jiná, ale zdálo se mi, že u tmavých odstínů dává věrohodnější (méně saturované) výsledky, takže jsem u ní nakonec zůstal.

Po vytvoření prvních sekvencí jsem si uvědomil, že mi ještě zbývá jeden problém a to byly poměrně ostré změny v místech klíčových snímků. Ty bylo třeba vyhladit, a tak jsem se rozhodl, že mezi klíčovými snímky bude potřeba přidat lineární interpolaci mezi políčky spočítanými vzestupně a sestupně. Pokud jsem měl například klíčové snímky 1 a 5, tak jsem si nechal spočítat vzestupně sekvenci 1-4 (a vznikly snímky 2a, 3a a 4a) a sestupně sekvenci 5-2 (snímky 4b, 3b a 2b). Výsledná políčka pak vznikla jejich smícháním v proměnlivém poměru (tj. 2 = 75% 2a + 25% 2b, 3 = 50% 3a + 75% 3b a 4 = 25% 4a + 75% 4b), což dostal na starost další vlastní program Blender.

A protože tohle všechno se ovládalo z příkazové řádky a znamenalo to mnoho psaní a kopírování textu (Notepad a Excel), tak jsem programovací část uzavřel napsáním několik skriptů (.js), které vždy prohledaly adresář s klíčovými snímky, poznamenaly si změny a vygenerovaly nové dávkové soubory (.cmd), které pak dopočítaly všechna políčka, která byla těmi provedenými změnami ovlivněna.

Tím bohužel skončila ta zajímavější a optimističtější část, kdy jsem si ještě představoval, že dál to půjde snadno, a nastoupila rutina, kdy bylo třeba postupně vytvářet a upravovat klíčové snímky. Původně jsem odhadoval, že mi to zabere zhruba dva týdny, ale nakonec to trvalo zhruba třikrát déle, což bylo způsobeno částečně mým zbytnělým puntičkářstvím a částečně nepozorností. Například teprve někde u políčka 240 jsem si všimnul, že Miroslav má vlastně světlé plátěné kalhoty, u políčka 720 jsem zjistil, že část Krasomiliných šatů je ve skutečnosti opěradlo židle, a podobné perličky, které pak vyžadovaly opravy na mnoha předchozích klíčových snímcích. Mým největším oblíbencem se stala kožešina, která se skrývá ve stínu za oběma hrdiny a kterou jsem dodatečně opravoval téměř všude.

Kromě toho mi úplně nevyšel odhad, že klíčové snímky budou potřeba přibližně každých 10-20 políček. To poměrně slušně fungovalo v klidnějších pasážích, ale když došlo k nějakému rychlejšímu pohybu rukou nebo nedejbože k pohybu kamery, tak Frankensteiner začal lapat po dechu (výpočet jednoho políčka se natáhl až na několik minut a barevná maska se stejně začala rozjíždět) a klíčové snímky pak bylo v takových místech třeba udělat pro každé druhé políčko. Klíčových snímků tak nakonec bylo potřeba 163 (tedy v průměru každých 8,5 políček) a v některých pasážích by stále ještě bylo vhodné přidat další.

Když jsem měl konečně ke všem políčkům spočítané kolorované verze, tak jsem to vše pomocí starého přítele FFMPEG spojil do jednoho videa, přidal upravenou zvukovou stopu, orientační titulky a bylo konečně hotovo.

Pokud by se snad našel šílenec, který by chtěl pokračovat jinou scénou nebo zkusit štěstí s jiným filmem, tak tady přikládám zip se všemi prográmky, skripty i pracovní adresářovou strukturou.

Vedlejším produktem celé akce se stal font Krasomila, který vychází z ručně psaných titulků původního filmu.