5.31. Siirtymän sovitus¶
Mallin sovitus vastaa kysymykseen missä tämä lappu on kehyksen sisällä; samankaltaisuuden pisteytys vastaa kysymykseen kuinka samanlaisia nämä kaksi kuvaa ovat kokonaisuutena. Niiden välissä on toisenlainen kysymys: kaksi kehystä näyttää saman näkymän, mutta kamera (tai näkymä) liikkui niiden välissä – kuinka paljon? Tämä on siirtymän ongelma, ja image-moduuli ratkaisee sen yhdellä vaihekorrelaatiometodilla.
5.31.1. Vaihekorrelaatiosiirtymä¶
find_displacement() arvioi kahden samankokoisen kuvan jäykän kohdistuksen käyttäen vaihekorrelaatiota – taajuusalueen menetelmää, joka ajaa nopean Fourier-muunnoksen (FFT) kummallekin kuvalle, ristikorreloi niiden vaiheet ja paikantaa huipun tuloksesta. Huipun sijainti on siirtymä, joka kohdistaa kaksi kuvaa:
d = img.find_displacement(template)
print("shift:", d.x_translation, d.y_translation,
" response:", d.response)
Palautettu Displacement kantaa kentät x_translation ja y_translation – pikselisiirtymän kummallakin akselilla – sekä kentän response, joka on luottamuspistemäärä välillä 0.0–1.0, jossa 1.0 on täydellinen huippu. Niiden tunnistusten suodattaminen pois, jotka ovat raja-arvon response > 0.3 alapuolella, hylkää virheelliset tulokset, joissa vaihekorrelaatio ei koskaan löytänyt puhdasta huippua.
Sekä rotation että scale ovat oletustilassa 0.0 ja 1.0 vastaavasti; ne saavat todellisia arvoja vain, kun logpolar=True (katso alla).
Metodiin liittyy kaksi käytännön rajoitusta. Ensimmäinen on kahden potenssin mukaiset mitat: vaihekorrelaation ytimessä oleva FFT on nopein – ja kamerassa vain täysin tuettu – kokoluokissa kuten 32 kertaa 32, 64 kertaa 64 ja 128 kertaa 128. Siistein järjestely on kaapata suoraan jossakin näistä koista välittämällä resoluutio metodille framesize() monikkona:
csi0.framesize((64, 64))
Sovellus, joka tarvitsee siirtymän suuremmasta kehyksestä, rajaa sen sijaan kahden potenssin mukaisen lapun siltä alueelta, josta se välittää, ja ajaa sovittimen sille.
Toinen on samankokoiset syötteet: roi ja template_roi täytyy valita identtiset leveydet ja korkeudet, tai sovitin kieltäytyy kutsusta. Kaksi kaappausta samasta kamerasta samalla konfiguraatiolla täyttää tämän automaattisesti; kaapattu kehys, jota verrataan ladattuun viitteeseen, tarvitsee molemmat ensin rajattuna täsmääviin kahden potenssin mukaisiin lappuihin.
5.31.2. Kierto ja skaala log-polaarisen muunnoksen kautta¶
Oletustila löytää vain siirtymän. Kun kaksi kehystä eroavat myös kierrossa valitun keskipisteen ympäri tai skaalassa saman keskipisteen ympäri, vaihekorrelaation ajaminen kunkin kuvan log-polaariselle uudelleenprojektiolle muuntaa nuo parametrit siirtymäksi log-polaarisessa koordinaatistossa – jonka sama vaihekorrelaatiosovitin voi palauttaa:
d = img.find_displacement(template, logpolar=True)
print("rotation rad:", d.rotation,
" scale:", d.scale,
" response:", d.response)
Asetuksella logpolar=True metodi ajaa saman sovituksen liukuhihnan log-polaarisesti projisoituja kuvia vastaan alkuperäisten sijaan. Tuloksen kentät rotation ja scale palautuvat täytettyinä: rotation on kahden kehyksen välinen kulma radiaaneina, scale on niiden välinen skaalauskerroin. x_translation ja y_translation menettävät merkityksensä tässä tilassa (siirtymä log-polaaristen akselien suuntaan ei vastaa lineaarista siirtymää lähteessä).
Avainsana fix_rotation_scale=True kattaa välitapauksen: kaksi kuvaa eroavat sekä siirtymässä että kierrossa/skaalassa, ja sovellus tarvitsee vain siirtymän kierron ja skaalan korjaamisen jälkeen. Sovitin ajaa ensin log-polaarisen vaiheen palauttaakseen kierron ja skaalan, soveltaa käänteismuunnoksen toiseen kuvista ja ajaa sitten siirtymävaiheen palauttaakseen jäljelle jääneen siirtymän. Lippu on merkityksellinen vain, kun logpolar=False – se pyytää siirtymätilan sovitinta poistamaan ensin kierron/skaalan.
Napamuunnoksista tuttu malli – karteesinen → napakoordinaatit → sovitus – on se, mitä find_displacement() asetuksella logpolar=True tekee yhdellä kutsulla. Sovellus tallentaa käynnistyksessä log-polaarisen viitelappun, kaappaa ja log-polaarisesti muuntaa kunkin live-kehyksen, ja metodi palauttaa niiden välisen kierto- ja skaalaeron. Sovelluksille, jotka tarvitsevat kierto- ja skaalainvariantin seuraajan – telakoituva robotti, jonka kamera kallistuu ja zoomaa kohdetta lähestyessään, tai vakautettu kardaaninivel, jonka täytyy tietää, miten kuva kiertyy viitteeseen nähden – tämä on vakiorakenne.
5.31.3. Klassinen käyttö¶
Metodin find_displacement() yleisin käyttö on kehyksestä kehykseen tapahtuva liikkeen arviointi liukuhihnassa, joka käsittelee liikkuvaa kameraa. Kamera kaappaa pienen kahden potenssin mukaisen lapun kehyksessä N, kaappaa samankokoisen lapun kehyksessä N+1, ajaa find_displacement() näille kahdelle ja lukee niiden välisen pikselisiirtymän. Siirtymä on kameran (tai näkymän, riippuen siitä, kenen viitekehys on olennainen) arvioitu liike kahden kaappauksen välillä, hyödyllinen seuraaviin:
Optisen virtauksen tyylinen aistiminen – leijuva drooni alaspäin osoittavalla kameralla käyttää kehyskohtaista siirtymää arvioidakseen sivuttaisliikkeensä ja syöttää sen takaisin lennonohjaimeen.
Kuvan vakautus – peräkkäisten kehysten välinen siirtymä vähennetään kaapatusta kuvasta ennen sen tallentamista tai lähettämistä, mikä tuottaa tasaisemman videovirran.
Tarkastuksen kohdistus – kuljetinta pitkin liikkuva skannaava kamera käyttää kehyskohtaista siirtymää rekisteröidäkseen kunkin kehyksen seuraavaan nähden ja rakentaakseen koko osasta yhdistetyn näkymän.
Jokainen näistä sovelluksista ottaa saman muodon: kaappaa, siirrä, kerrytä jatkuvaan arvioon, kaappaa uudelleen.