5.22. Korekcja obiektywu i perspektywy¶
Dwie klasy korekcji geometrycznej zniekształcają obraz w sposób, którego nie da się osiągnąć odwzorowaniem prostokąta na prostokąt. Korekcja obiektywu usuwa zniekształcenia promieniowe wprowadzane przez rzeczywisty obiektyw szerokokątny – wybrzuszenie typu rybie oko, które wygina proste linie sceny w widoczne krzywizny przy narożnikach ramki. Korekcja perspektywy usuwa efekt trapezu, który pojawia się, gdy obiektyw nie jest skierowany prostopadle do sceny – trapezoidalne zniekształcenie, które zamienia znany prostokąt w świecie w nieprostokątną plamę na obrazie. Obie korekcje usuwają, już po wykonaniu zdjęcia, efekty o pochodzeniu optycznym.
5.22.1. Promieniowe zniekształcenie obiektywu¶
Materiał rzeczywiste efekty obiektywu opisuje zniekształcenie beczkowate, które wprowadzają niedrogie obiektywy szerokokątne. Piksele blisko środka ramki znajdują się mniej więcej tam, gdzie przewiduje model otworkowy; piksele blisko krawędzi są wygięte na zewnątrz o wartość, która rośnie wraz z kwadratem odległości promieniowej od osi optycznej. Prosta linia w scenie, która biegnie blisko krawędzi ramki, widocznie się wygina na zarejestrowanym obrazie, a każdy klasyczny algorytm wizji maszynowej, który zakłada, że proste linie pozostają proste – wykrywanie narożników AprilTag, śledzenie krawędzi, nawigacja po linii – daje błędny wynik przy narożnikach.
lens_corr() usuwa zniekształcenie. Metoda wykonuje odwrotne odwzorowanie: każdy piksel wyjściowy jest próbkowany z pozycji w obrazie wejściowym, z której obiektyw by go wygiął na zewnątrz, a wynikiem jest geometrycznie prosty obraz.
img.lens_corr(strength=1.8)
Parametr strength jest sercem korekcji. To pojedyncza liczba opisująca, jak silnie obiektyw wygina obraz; wartość bliska 1.0 to łagodna korekcja dla umiarkowanie szerokiego obiektywu, a wartości do około 2.0 są rozsądne dla silnego rybiego oka. Domyślna wartość 1.8 jest rozsądnym punktem wyjścia dla standardowych obiektywów OpenMV Cam; właściwa wartość dla konkretnego obiektywu to kwestia wypróbowania kilku i obserwowania obrazu.
Dwa parametry poboczne zwykle dobrze działają z wartościami domyślnymi. zoom (domyślnie 1.0) skaluje wyjście – wartość większa niż jeden przycina obraz na zewnątrz, aby skompensować sposób, w jaki korekcja obiektywu wypycha narożniki dalej; mniejsze wartości pozostawiają widoczną większą część skorygowanej sceny kosztem dołączenia pustych pikseli przy krawędziach obrazu. x_corr i y_corr przesuwają środek korekcji od geometrycznego środka obrazu, co jest przydatne, gdy obiektyw nie jest optycznie wyśrodkowany nad sensorem (przypadek nietypowy, ale warto o nim wiedzieć).
Typowy potok: przechwyć obraz, uruchom raz lens_corr() aby wyprostować geometrię, a następnie wykonaj to, co aplikacja faktycznie robi z wynikiem.
5.22.2. Korekcja obrotu 3D¶
Drugą klasą zniekształcenia geometrycznego jest zniekształcenie perspektywiczne, które pojawia się, gdy płaszczyzna sensora nie jest równoległa do płaszczyzny sceny. Klasycznym przypadkiem jest znak lub tablica rejestracyjna oglądana od dołu: górna część znaku jest dalej od obiektywu niż dolna, więc rzutuje się jako mniejsza, a zarejestrowany obraz pokazuje prostokąt jako trapez z krótszą górną krawędzią niż dolna.
Rozwiązaniem jest zastosowanie obrotu 3D do przechwyconej ramki, który wirtualnie zmienia orientację płaszczyzny sensora tak, by była równoległa do płaszczyzny sceny. Matematyka jest tym samym odwzorowaniem perspektywicznym, którego wykrywanie AprilTag używa do odtworzenia pozy znacznika z jego czterech narożników, wykonanym w odwrotnym kierunku: dla danego obrotu operacja odwzorowuje każdy piksel wyjściowy z powrotem na pozycję wejściową, z której obrót by pochodził.
rotation_corr() wykonuje tę korekcję:
img.rotation_corr(x_rotation=10.0, y_rotation=0.0, z_rotation=0.0)
Trzy parametry obrotu są podane w stopniach i opisują obroty wokół osi x, y oraz z wirtualnej kamery wyśrodkowanej na obrazie. x_rotation przechyla kamerę w górę lub w dół (naturalna korekcja dla ujęcia ściany z poziomu gruntu); y_rotation obraca kamerę w lewo lub w prawo; z_rotation obraca kamerę wokół jej osi optycznej (naturalna korekcja dla nierówno zamontowanej kamery).
x_translation i y_translation przesuwają wirtualną kamerę bocznie bez jej obracania. zoom (domyślnie 1.0) skaluje wyjście. fov (domyślnie 60.0) opisuje pionowe pole widzenia kamery, używane do obliczenia rzutowania – wartość powinna odpowiadać rzeczywistemu obiektywowi, aby zachować spójność geometrii.
Dla dowolnej kombinacji przechylenia i obrotu wiele niezerowych obrotów składa się w jednym wywołaniu. Kolejność operacji jest ustalona wewnątrz implementacji; aplikacja po prostu podaje kąty, a wynik zostaje wyprodukowany.
5.22.3. Prostowanie znanego prostokąta¶
Najbardziej przydatną postacią rotation_corr() jest słowo kluczowe corners=, które przyjmuje listę czterech krotek (x, y) opisujących narożniki znanego prostokąta na obrazie wejściowym. Metoda oblicza, jaki obrót 3D odwzorowałby prawdziwy prostokąt na te konkretne cztery punkty, stosuje odwrotność tego obrotu do całego obrazu i zwraca wynik, w którym znany prostokąt znów jest prostokątny:
plate_corners = [(45, 80), (300, 60), (310, 180), (40, 200)]
img.rotation_corr(corners=plate_corners)
Klasyczne zastosowanie jest dokładnie tym, co sugeruje nazwa: tablica rejestracyjna (lub dowolna inna prostokątna cecha) sfotografowana pod skośnym kątem. Wcześniejszy etap wykrywa tablicę i raportuje pozycje jej czterech narożników na zarejestrowanym obrazie; przekazanie tych narożników do rotation_corr() daje obraz, na którym tablica leży jako prawdziwy prostokąt, gotowa dla dowolnego kolejnego etapu rozpoznawania znaków lub dopasowywania szablonów.
Gdy postać z czterema narożnikami rozwiązuje problem, który aplikacja próbuje rozwiązać, jest ona znacznie bardziej użyteczna niż postać z sześcioma parametrami. Aplikacja nie musi szacować żadnych kątów obrotu; po prostu przekazuje metodzie cztery punkty i pozwala metodzie wymyślić resztę. Postać z sześcioma parametrami jest przydatna, gdy w scenie nie jest widoczny żaden identyfikowalny prostokąt, a obrót trzeba dostroić ręcznie na podstawie wiedzy zewnętrznej (na przykład skalibrowanego kąta montażu).