5.31. Elmozdulás-illesztés¶
A sablonillesztés arra a kérdésre válaszol, hogy hol van ez a folt a képkockán belül; a hasonlósági pontozás arra, hogy mennyire hasonlít ez a két kép összességében. Egy másik kérdés helyezkedik el közöttük: a két képkocka ugyanazt a jelenetet mutatja, de a kamera (vagy a jelenet) elmozdult közöttük – mennyivel? Ez az elmozdulás problémája, és az image modul egyetlen fáziskorrelációs metódussal oldja meg.
5.31.1. Fáziskorrelációs elmozdulás¶
A find_displacement() fáziskorreláció segítségével becsüli meg a merev igazítást két azonos méretű kép között – ez egy frekvenciatartománybeli módszer, amely mindkét képen gyors Fourier-transzformációt (FFT) futtat, keresztkorrelálja a fázisaikat, és megkeresi a csúcsot az eredményben. A csúcspozíció az az eltolás, amely a két képet igazítja:
d = img.find_displacement(template)
print("shift:", d.x_translation, d.y_translation,
" response:", d.response)
A visszaadott Displacement hordozza az x_translation és y_translation értékeket – a képpontbeli eltolást mindegyik tengely mentén – valamint a response értéket, egy 0.0-tól 1.0-ig terjedő megbízhatósági pontszámot, ahol az 1.0 egy tökéletes csúcs. A response > 0.3 alatti észlelések kiszűrése elveti azokat a hamis eredményeket, amelyeknél a fáziskorreláció soha nem talált tiszta csúcsot.
A rotation és a scale az alapértelmezett módban 0.0, illetve 1.0; valódi értékeket csak akkor vesznek fel, ha logpolar=True (lásd alább).
A metódusnak két gyakorlati megkötése van. Az első a kettő hatványú méretek: a fáziskorreláció szívében lévő FFT a leggyorsabb – és a kamerán csak teljesen támogatott – olyan méreteknél, mint a 32×32, 64×64 és 128×128. A legtisztább megoldás közvetlenül ezen méretek egyikén rögzíteni, a felbontást egy tuple-ként átadva a framesize() metódusnak:
csi0.framesize((64, 64))
Egy olyan alkalmazás, amelynek nagyobb képkockából van szüksége elmozdulásra, ehelyett kivág egy kettő hatványú foltot abból a területből, amely érdekli, és azon futtatja az illesztőt.
A második a azonos méretű bemenetek: a roi és a template_roi azonos szélességet és magasságot kell hogy kijelöljön, különben az illesztő visszautasítja a hívást. Két felvétel ugyanattól a kamerától, azonos konfigurációban automatikusan teljesíti ezt; egy rögzített képkocka, amelyet egy betöltött referenciához hasonlítunk, mindkettő illeszkedő kettő hatványú folttá való körülvágását igényli előbb.
5.31.2. Forgatás és skála log-polár segítségével¶
Az alapértelmezett mód csak eltolást talál. Amikor a két képkocka egy kiválasztott középpont körüli forgatásban vagy ugyanazon középpont körüli skálában is különbözik, a fáziskorrelációnak mindegyik kép log-polár újravetületén való futtatása ezeket a paramétereket eltolássá alakítja a log-polár koordináta-rendszerben – amelyet ugyanaz a fáziskorrelációs illesztő képes visszanyerni:
d = img.find_displacement(template, logpolar=True)
print("rotation rad:", d.rotation,
" scale:", d.scale,
" response:", d.response)
A logpolar=True esetén a metódus ugyanazt az illesztési feldolgozósort futtatja a log-polár vetített képeken az eredetiek helyett. Az eredmény rotation és scale mezői kitöltve térnek vissza: a rotation a két képkocka közötti szög radiánban, a scale pedig a köztük lévő skálatényező. Az x_translation és y_translation ebben a módban értelmetlenné válik (a log-polár tengelyek menti eltolás nem felel meg egy lineáris eltolásnak a forrásban).
A fix_rotation_scale=True kulcsszó a közbenső esetet fedi le: a két kép mind eltolásban, mind forgatásban/skálában különbözik, és az alkalmazásnak csak eltolásra van szüksége a forgatás és a skála korrigálása után. Az illesztő először lefuttatja a log-polár menetet a forgatás és a skála visszanyeréséhez, alkalmazza az inverzet az egyik képre, majd lefuttatja az eltolási menetet a fennmaradó eltolás visszanyeréséhez. A jelző csak akkor van jelentőséggel, ha logpolar=False – arra kéri az eltolás-módú illesztőt, hogy először távolítsa el a forgatást/skálát.
A Polár transzformációkból ismert minta – Descartes → polár → illesztés – pontosan az, amit a find_displacement() logpolar=True esetén egyetlen hívásban végez. Az alkalmazás indításkor tárol egy referencia log-polár foltot, rögzíti és log-polár transzformálja minden élő képkockát, a metódus pedig visszanyeri a köztük lévő forgatás- és skálakülönbséget. Azokhoz az alkalmazásokhoz, amelyeknek forgatás- és skálainvariáns követőre van szükségük – egy dokkoló robot, amelynek kamerája megdől és nagyít, ahogy egy célpont felé közelít, egy stabilizált kardán, amelynek tudnia kell, hogyan forog a kép egy referenciához képest – ez a szabványos felépítés.
5.31.3. A klasszikus felhasználás¶
A find_displacement() leggyakoribb felhasználása a képkockáról képkockára történő mozgásbecslés egy olyan feldolgozósorban, amely egy mozgó kamerát dolgoz fel. A kamera rögzít egy kis kettő hatványú foltot az N. képkockánál, rögzíti az azonos méretű foltot az N+1. képkockánál, lefuttatja a find_displacement() metódust a kettőn, és leolvassa a köztük lévő képpontbeli eltolást. Az eltolás a kamera (vagy a jelenet, attól függően, hogy kinek a vonatkoztatási rendszere számít) becsült mozgása a két felvétel között, ami hasznos a következőkhöz:
Optikai folyam jellegű érzékelés – egy lebegő drón egy lefelé mutató kamerával a képkockánkénti elmozdulást használja az oldalirányú mozgásának becslésére, és ezt visszacsatolja a repülésvezérlőbe.
Képstabilizálás – az egymást követő képkockák közötti elmozdulást kivonja a rendszer a rögzített képből, mielőtt rögzítenék vagy továbbítanák, ezzel simább videofolyamot hozva létre.
Vizsgálati igazítás – egy szállítószalag mentén mozgó pásztázó kamera a képkockánkénti elmozdulást használja arra, hogy minden képkockát a következőhöz illesszen, és összefűzött nézetet építsen az egész alkatrészről.
Ezen alkalmazások mindegyike ugyanazt a formát ölti: rögzítés, elmozdítás, felhalmozás egy folyamatos becslésbe, majd ismételt rögzítés.