Úloha 114: Přechod mezi dvěma obrázky

Úkolem je navrhnout algoritmus pro výpočet přechodové animace mezi dvěma rastrovými obrázky. Předpokládáme obrázky stejné velikosti a přechod trvající jednu sekundu (parametr t se pohybuje 0.0 <= t <= 1.0). V připraveném projektu jsou již implementovány mechanismy přepočítávání obrázků, Vám stačí definovat jednu nebo dvě přechodové funkce.

Screenshot

Základ

Základem poslouží projekt 114transition z repository grcis. Je připravena WinForm aplikace obsahující všechny potřebné pomocné funkce a příkazy včetně vlastního výpočtu mezisnímku. Vy budete mít možnost modifikovat třídu Transition (zejména funkce Transition.BlendingFunction() a Transition.MorphingFunction()) definující poměry míchání a/nebo geometrii přechodové animace. Uživatel může interaktivně zadávat čas t, aplikace v reálném čase obrázek přepočítává a na formuláři zobrazuje.

Vstupem výpočtu jsou dva různé rastrové obrázky (pokud nemají stejné rozlišení, bude přechodová animace počítat s průnikem obou obdélníků). Tlačítky "Image 1" resp. "Image 2" se tyto dva vstupy zadávají. Od okamžiku zadání druhého obrázku je na formuláři automaticky zobrazován přechodový obrázek pro aktuální hodnotu parametru t, který je možné měnit posuvníkem vpravo dole nebo parametrem v textovém poli Param:. Hotový obrázek je možné uložit na disk tlačítkem "Save image".

Blending vs. Morphing

Jsou implementovány dvě metody výpočtu přechodových obrázků: "Blending" a "Morphing":
Blending nemodifikuje geometrii vstupních obrázků, pouze se v daném poměru míchají, "mixují" ("blend") barvy odpovídajících pixelů z obou vstupů.
Morphing může navíc použít libovolnou geometrickou transformaci vstupů, která se aplikuje před mícháním barev pixelů.

Blending se použije při nastavení 'morph=false'. Vámi definovaná funkce Transition.BlendingFunction ( double t, int x, int y ) vrací poměr směsi dvou zdrojových pixelů pro souřadnici [x,y] a čas t. 0.0 znamená, že se použije pouze pixel z prvního obrázku, pro 1.0 se naopak do výstupu zapíše pixel z druhého vstupu; při ostatních hodnotách se barvy z prvního a druhého obrázku lineárně smíchají v daném poměru.

Morphing ('morph=true') je rozšířením předchozí metody: u každého výstupního pixelu a v každém zadaném čase můžete předepsat, ze kterých pozic se mají vzít barvy pro výslednou směs. Proto je hlavička funkce trochu složitější: Transition.MorphingFunction ( double t, int x, int y, out double srcX1, out double srcY1, out double srcX2, out double srcY2, out double blend). První tři parametry definují čas a polohu výsledku, další dvě dvojice parametrů určují polohu zdrojových pixelů v prvním a druhém vstupu, posledním parametrem se zadává míchací poměr.

Aplikace 114transition

Pilotní aplikace dále obsahuje několik užitečných funkcí:

  • Levé tlačítko myši slouží k prozkoumání příslušného pixelu obrázku - do titulku formuláře se vypíše rozměr obrázku, souřadnice a hodnota příslušného pixelu
  • Parametr 'par=true' umožňuje zapnout paralelní výpočet, což může celé přepočítávání několikanásobně urychlit - podle počtu vláken vašeho CPU
  • Vpravo pod obrázkem se nachází 'track-bar' pro nastavení času t. Zadaná hodnota se okamžitě použije k výpočtu a zobrazení výsledku ve formuláři
  • Tlačítko 'Run' slouží k vyvolání výpočtu po editaci parametrické řádky "Param:" (stejnou funkci má stisk klávesy Enter)
  • Nad několika prvky formuláře funguje obláčková nápověda ("Tool-tip"). V textovém poli "Param:" by měla ukázat, kterým parametrům program rozumí (pokud rozšíříte množinu příkazů, měli byste rozšířit i tuto nápovědu - viz parametr out string tooltip ve funkci Transition.InitParams()).

Technicky

Formulářová aplikace vytvoří instanci Vámi definované třídy Transition. Před každým výpočtem výsledného obrázku je volána funkce Transition.Reset ( int wid, int hei, string param ), tak se dozvíte rozměry obrázku a můžete případně reagovat na textový parametr od uživatele. Při výpočtu výsledného obrázku se pak již volá opakovaně (pro každý pixel výsledku) Vaše funkce Transition.BlendingFunction() nebo Transition.MorphingFunction().
Která z těchto variant se použije, i to ovlivníte Vy .. pomocí predikátu Transition.UseMorphing(). Implicitní implementace používá parametr morph=false|true z textového pole Params: předaného do funkce Transition.Reset(). Toto chování můžete zachovat nebo můžete napevno vracet false nebo true podle toho, který z přístupů jste implementovali.

Textový parametr string param slouží k přenosu libovolných dalších potřebných informací z formuláře do Vašeho kódu. V pilotní implementaci si všimněte pohodlné extrakce hodnot pomocí Util.ParseKeyValueList() a mnohých variant Util.TryParse(). Framework aplikace předpokládá použití parametrů morph a par, můžete si přidat další dle libosti..

Inicializace formuláře

Pro pohodlné ladění i pro odevzdání vhodného nastavení modifikujte inicializační proceduru Transition.InitParams(). Ta se zavolá vždy na začátku při inicializaci formuláře.
Do prvního parametru out string name napište své celé jméno. Usnadníte tím příp. automatické vyhodnocování výsledků.
Dále můžete nastavit implicitní hodnotu formulářového pole Param: a nápovědu pro toto textové pole (out string tooltip).

Rychlý přístup do bufferu obrázku

Projekt 114transition používá intenzivně rychlejšího přístupu do paměťových bufferů rastrových obrázků. Nemusíte (a ani nemůžete) to měnit, ale pokud vás to zajímá, prohlédněte si kód funkce Form1.transition(). Je zde též volitelně použit paralelismus (Parallel.For).

Co odevzdat

Jako řešení úlohy posílejte mailem modifikovaný zdrojový soubor Transition.cs.

Termín

Odevzdat do: 11. 11. 2018

Body

Můžete řešit jednu nebo obě varianty:
Jen blending: 6 bodů (jednoduché, ale originální řešení),
Jen morphing: 7 bodů (jednoduché, ale originální řešení),
Oba přístupy: 10 bodů,
Bonus až 6 bodů za invenci, zajímavý výsledek či implementaci, apod.

Projekt

Visual Studio projekt: 114tonemapping.

Zdrojový soubor

Modifikujte a odevzdejte soubor: Transition.cs
Do prvního parametru funkce InitParams() zadejte své celé jméno!

Vstupní data

Jakékoli rastrové obrázky se dají použít jako vstup. Pokud budou mít oba vstupy rozdílné rozlišení, použije se jejich průnik. Několik testovacích obrázků najdete v repository v adresáři data.


Copyright (C) 2018 J.Pelikán, last change: 2019-05-09 17:52:59 +0200 (Thu, 09 May 2019)