5.23. Perspektíva-korrekció¶
Figyelem
A tetszőleges 3-szor-3-as transform mátrix csak az OpenMV Cam N6-on támogatott – a kulcsszót minden más kártyán csendben figyelmen kívül hagyja. Az olyan alkalmazásoknak, amelyeknek máshol is futniuk kell, a kész rotation_corr() metódust (a corners= formájával) kell használniuk, vagy a korrigált képet a kártyán kívül kell előre kiszámítaniuk.
A kész rotation_corr() metódus a perspektíva-torzítások egy adott családját csomagolja egy kis paraméterkészlet mögé, és minden támogatott kártyán fut. Egyes alkalmazásoknak olyan torzításra van szükségük, amely nem illik ehhez a formához: egy tetszőleges projektív átleképezés az egyik négyszögből a másikba, egy kalibrált korrekció egy ismert rögzítéshez, amelyet már offline kidolgoztak, egy torzítási mátrix, amelyet valamilyen korábbi algoritmus készen ad át. Ezekhez a draw_image() – a copy(), crop() és scale() mellett – elfogad egy transform kulcsszót, amely egy kézzel felépített 3-szor-3-as mátrixot vesz át, amely közvetlenül leírja a torzítást.
5.23.1. Affin és projektív transzformációk¶
A geometriai torzításokat homogén koordinátákban fejezzük ki: a (x, y) képpontpozíciót, egy hozzáfűzött 1 értékkel, megszorozva egy 3-szor-3-as mátrixszal.
Az affin forma a kiindulópont. Az alsó sora rögzítve van a \((0, 0, 1)\) értéken:
Kifejtve minden kimeneti koordináta a bemeneti koordináták lineáris kombinációja plusz egy konstans:
amely lefedi a skálázást, forgatást, nyírást és eltolást bármilyen kombinációban – és mindegyik alatt a párhuzamos vonalak párhuzamosak maradnak.
A projektív (perspektíva) forma felszabadítja az alsó sort:
Kifejtve:
A \(w' = g x + h y + 1\) szerinti osztás teszi a transzformációt projektívvé, nem pedig pusztán affinná. Amikor \(g\) és \(h\) egyaránt nulla, \(w'\) egynek marad, és az osztás nem csinál semmit – ismét az affin forma. Amikor bármelyik nem nulla, \(w'\) a bemeneti pozícióval változik, és a különböző pozíciókban lévő képpontok különböző mértékben rövidülnek meg, ami már nem tartja párhuzamosan a párhuzamos vonalakat – pontosan ez a trapéztorzítás, amely egy lapos sík ferde szögből való nézéséből ered. A projektív transzformáció a legáltalánosabb geometriai torzítás, amely az egyenes vonalakat egyenes vonalakká alakítja; a skálázás, tükrözés, transzponálás, forgatás és a négysarkú forgáskorrekció mind ennek egy-egy speciális esete.
A megnevezett transzformációk közvetlenül az affin formából adódnak. Az identitás-transzformáció az egységmátrix, és:
A legtöbb kézzel felépített transzformációhoz egy alkalmazás ezek egyikéből indul ki alapként, és további mátrixokkal szoroz be minden egyes további művelethez, egyetlen 3-szor-3-as mátrixszal zárva, amely leírja az összetett torzítást. A mátrixok jobbról balra alkalmazódnak: a \(M = T R S\) először a skálázást futtatja, majd a forgatást, majd az eltolást. Az összetett művelet, amelyre mindenkinek előbb-utóbb szüksége van, a kép középpontja körüli forgatás – egy önmagában álló forgatási mátrix a képet a bal felső sarokban lévő képpont-origó körül pörgeti, így a központosított változat a \((c_x, c_y)\) középpontot az origóba mozgatja, forgat, majd visszamozgatja:
5.23.2. A transform kulcsszó¶
A mátrix egy transform kulcsszón keresztül kerül be, egy 3-szor-3-as ulab.numpy.ndarray formájában megadva. A használandó metódus a draw_image(), amely a forrást a mátrixon keresztül torzítja, miközben egy célra rajzolja – az eredmény egy alkalmazás által vezérelt pufferben landol, és a torzítás komponálódik minden mással a híváson: a skálázással, az alfa-keveréssel, a maszkolással.
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)
A példa az img képet a canvas képre torzítja mindkét irányban 1,2-szeresére skálázva, és balra, illetve felfelé 20, illetve 15 képponttal eltolva – egy affin torzítás, amely közvetlenül a fent leírt mátrixelemekből épül fel. Ugyanaz a kulcsszó a copy(), crop() és scale() metódusokon a torzítást magára a képre alkalmazza.