5.22. Lins- och perspektivkorrigering¶
Två klasser av geometrisk korrigering förvränger bilden på sätt som en avbildning från rektangel till rektangel inte klarar. Linskorrigering upphäver den radiella förvrängning som en verklig vidvinkellins introducerar – den fiskögeutbuktning som böjer raka linjer i scenen till synliga kurvor nära bildrutans hörn. Perspektivkorrigering upphäver den stupande effekt (keystone) som uppstår när linsen inte är riktad vinkelrätt mot scenen – den trapetsformade förvrängning som förvandlar en känd rektangel i världen till en icke-rektangulär klump i bilden. Båda korrigeringarna upphäver, efter att tagningen är klar, effekter som har optiskt ursprung.
5.22.1. Radiell linsförvrängning¶
Materialet om verkliga linseffekter beskriver den tunnformade (barrel) förvrängning som billiga vidvinkellinser introducerar. Pixlar nära mitten av bildrutan ligger ungefär där hålkameramodellen förutsäger; pixlar nära kanterna är utböjda med ett belopp som växer med kvadraten på det radiella avståndet från den optiska axeln. En rak linje i scenen som löper nära bildrutans kant kröker sig synligt i den tagna bilden, och alla klassiska maskinseendealgoritmer som antar att raka linjer förblir raka – AprilTag-hörndetektering, kantföljning, linjeföljande navigering – ger fel svar nära hörnen.
lens_corr() upphäver förvrängningen. Metoden kör den inversa avbildningen: varje utdatapixel samplas från den position i indata som linsen skulle ha böjt ut den från, och resultatet är en geometriskt rak bild.
img.lens_corr(strength=1.8)
Parametern strength är kärnan i korrigeringen. Det är ett enda tal som beskriver hur kraftigt linsen böjer; ett värde nära 1.0 är en mild korrigering för en måttligt vid lins, och värden upp till omkring 2.0 är rimliga för ett kraftigt fiskögeobjektiv. Standardvärdet 1.8 är en rimlig utgångspunkt för OpenMV Cams standardlinser; det rätta värdet för en viss lins är en fråga om att prova några och titta på bilden.
De två sidoparametrarna fungerar oftast bra med sina standardvärden. zoom (standard 1.0) skalar utdatan – ett värde större än ett beskär utåt för att kompensera för hur linskorrigeringen trycker hörnen längre ut; mindre värden lämnar mer av den korrigerade scenen synlig till priset av tomma pixlar vid bildens kanter. x_corr och y_corr förskjuter korrigeringens centrum bort från bildens geometriska centrum, vilket är användbart när linsen inte är optiskt centrerad över sensorn (ett ovanligt fall men värt att känna till).
En typisk pipeline: ta bilden, kör lens_corr() en gång för att räta ut geometrin, och kör sedan vad applikationen faktiskt gör med resultatet.
5.22.2. 3D-rotationskorrigering¶
Den andra klassen av geometrisk förvrängning är den perspektiv-förvrängning som uppstår när sensorplanet inte är parallellt med scenplanet. Det klassiska fallet är en skylt eller en registreringsskylt sedd underifrån: skyltens överkant är längre bort från linsen än underkanten, så den projiceras mindre, och den tagna bilden visar rektangeln som en trapets där överkanten är kortare än underkanten.
Lösningen är att tillämpa en 3D-rotation på den tagna bildrutan som virtuellt omorienterar sensorplanet till att vara parallellt med scenplanet. Matematiken är samma perspektivavbildning som AprilTag-detektering använder för att återskapa en taggs pose från dess fyra hörn, fast körd baklänges: givet en rotation avbildar operationen varje utdatapixel tillbaka till den indataposition som rotationen skulle ha kommit från.
rotation_corr() kör den korrigeringen:
img.rotation_corr(x_rotation=10.0, y_rotation=0.0, z_rotation=0.0)
De tre rotationsparametrarna anges i grader och beskriver rotationer kring x-, y- och z-axlarna hos en virtuell kamera centrerad på bilden. x_rotation lutar kameran upp eller ner (den naturliga korrigeringen för en tagning av en vägg från marknivå); y_rotation panorerar kameran åt vänster eller höger; z_rotation roterar kameran kring sin optiska axel (den naturliga korrigeringen för ett snedt monterat fäste).
x_translation och y_translation flyttar den virtuella kameran i sidled utan att rotera den. zoom (standard 1.0) skalar utdatan. fov (standard 60.0) beskriver kamerans vertikala synfält, som används för att beräkna projektionen – värdet bör motsvara den faktiska linsen för att hålla geometrin konsekvent.
För en godtycklig kombination av lutning och panorering komponeras flera rotationer skilda från noll i ett anrop. Operationsordningen är fast inne i implementationen; applikationen anger bara vinklarna och resultatet kommer ut.
5.22.3. Rätning av en känd rektangel¶
Den vanligaste användbara formen av rotation_corr() är nyckelordet corners=, som tar en lista med fyra (x, y)-tupler som beskriver hörnen på en känd rektangel i indatabilden. Metoden beräknar vilken 3D-rotation som skulle ha avbildat en sann rektangel till just dessa fyra punkter, tillämpar inversen av den rotationen på hela bilden och returnerar ett resultat där den kända rektangeln återigen är rektangulär:
plate_corners = [(45, 80), (300, 60), (310, 180), (40, 200)]
img.rotation_corr(corners=plate_corners)
Den klassiska användningen är precis vad namnet antyder: en registreringsskylt (eller någon annan rektangulär särdrag) fotograferad från en sned vinkel. Ett tidigare steg detekterar skylten och rapporterar dess fyra hörnpositioner i den tagna bilden; att skicka dessa hörn till rotation_corr() producerar en bild där skylten sitter som en sann rektangel, redo för vilket teckenigenkännings- eller mallmatchningssteg som än följer.
När fyrhörnsformen löser det problem en applikation försöker lösa är den dramatiskt mer användbar än sexparametersformen. Applikationen behöver inte uppskatta några rotationsvinklar; den lämnar bara över fyra punkter till metoden och låter metoden räkna ut resten. Sexparametersformen är användbar när ingen identifierbar rektangel syns i scenen och rotationen måste handjusteras utifrån extern kunskap (en kalibrerad monteringsvinkel, till exempel).