5.23. Korekce perspektivy¶
Varování
Libovolná matice transform o rozměru 3 na 3 je podporována pouze na OpenMV Cam N6 – na každé jiné desce se toto klíčové slovo tiše ignoruje. Aplikace, které musí běžet kdekoli jinde, musí použít hotovou metodu rotation_corr() (s její formou corners=) nebo opravený obraz předpočítat mimo desku.
Hotová metoda rotation_corr() balí určitou rodinu perspektivních deformací za malou sadu parametrů a běží na každé podporované desce. Některé aplikace potřebují deformaci, která do této formy nezapadá: libovolné projektivní přemapování z jednoho čtyřúhelníku na druhý, kalibrovanou korekci pro známé uchycení, která už byla vypočtena off-line, deformační matici předanou hotovou od nějakého předřazeného algoritmu. Pro ně metoda draw_image() – spolu s copy(), crop() a scale() – přijímá klíčové slovo transform, které bere ručně sestavenou matici 3 na 3 popisující deformaci přímo.
5.23.1. Afinní a projektivní transformace¶
Geometrické deformace se vyjadřují v homogenních souřadnicích: pozice pixelu (x, y) s připojenou 1, vynásobená maticí 3 na 3.
Místem, kde začít, je afinní forma. Její spodní řádek je pevně dán jako \((0, 0, 1)\):
Rozepsáno, každá výstupní souřadnice je lineární kombinací vstupních souřadnic plus konstanta:
což pokrývá škálování, rotaci, zkosení a posun v jakékoli kombinaci – a při všech z nich zůstávají rovnoběžné čáry rovnoběžné.
Projektivní (perspektivní) forma uvolňuje spodní řádek:
Rozepsáno:
Dělení \(w' = g x + h y + 1\) je to, co činí transformaci projektivní, a nikoli pouze afinní. Když jsou \(g\) i \(h\) nulové, \(w'\) zůstává jedničkou a dělení nic nedělá – opět afinní forma. Když je některé z nich nenulové, \(w'\) se mění s pozicí na vstupu a pixely na různých pozicích se zkracují o různé hodnoty, což už neudržuje rovnoběžné čáry rovnoběžnými – je to přesně lichoběžníkový efekt pohledu na plochou rovinu ze šikmého úhlu. Projektivní transformace je nejobecnější geometrická deformace, která převádí rovné čáry na rovné čáry; škálování, převracení, transponování, rotace a korekce rotace pomocí čtyř rohů jsou všechny zvláštními případy jedné z nich.
Pojmenované transformace vyplývají přímo z afinní formy. Identická transformace je jednotková matice a:
Pro většinu ručně sestavených transformací aplikace začne s jednou z nich jako základem a pro každou další operaci přinásobí další matice, přičemž skončí s jedinou maticí 3 na 3, která popisuje složenou deformaci. Matice se aplikují zprava doleva: \(M = T R S\) spouští nejprve škálování, pak rotaci a nakonec posun. Složením, které nakonec každý potřebuje, je rotace kolem středu obrazu – holá rotační matice otáčí obraz kolem počátku pixelů v levém horním rohu, takže vystředěná verze přesune střed \((c_x, c_y)\) do počátku, otočí jej a přesune zpět:
5.23.2. Klíčové slovo transform¶
Matice se předává klíčovým slovem transform jako ulab.numpy.ndarray o rozměru 3 na 3. Metodou, po které sáhnout, je draw_image(), která deformuje zdroj skrz matici, když jej vykresluje do cíle – výsledek skončí v bufferu, který aplikace ovládá, a deformace se skládá se vším ostatním ve volání: se škálováním, alfa prolínáním i maskováním.
import ulab.numpy as np
M = np.array([[1.2, 0.0, -20.0],
[0.0, 1.2, -15.0],
[0.0, 0.0, 1.0]])
canvas.draw_image(img, transform=M)
Příklad deformuje img na canvas se škálováním 1,2 v každém směru a s posunem doleva a nahoru o 20, respektive 15 pixelů – afinní deformace sestavená přímo z prvků matice popsaných výše. Totéž klíčové slovo u copy(), crop() a scale() aplikuje deformaci na samotný obraz.