4.17. Pokrętła sensora¶
Poza pixformat() i framesize() klasa CSI udostępnia garść ustawień specyficznych dla sensora, po które prędzej czy później sięga niemal każda aplikacja – orientacja montażu, ekspozycja, wzmocnienie, balans bieli oraz kilka pomocy diagnostycznych. Każde z nich odpowiada bezpośrednio koncepcji sensora omawianej wcześniej; API zapewnia jedynie pythonowy uchwyt do zapisu rejestru, którego pod spodem dokonuje sterownik.
Wszystkie poniższe metody działają na bazowym sensorze. Wszystkie one przesyłają zapisy rejestrów po magistrali sterującej I2C sensora, więc koszt to mikrosekundy, a nowe ustawienie wchodzi w życie przy następnej ekspozycji – zwykle przy następnym snapshot().
4.17.1. Orientacja¶
Kamera nie wie, którą stroną do góry została zamontowana. Dwie flagi odbicia zastosowane na sensorze obracają obraz we właściwą stronę, zanim jakikolwiek piksel opuści chip:
csi0.hmirror(True)
csi0.vflip(True)
hmirror() odbija lewą stronę z prawą, a vflip() odbija górę z dołem. Razem pokrywają przypadki spotykane w praktyce: płytkę zamontowaną do góry nogami (obie flagi True), płytkę za lustrem powierzchniowym (tylko hmirror) lub patrzącą na odbitą scenę od spodu (tylko vflip).
Ponieważ odbicie odbywa się w logice odczytu sensora, nie obciąża to procesora ani pamięci – ramka trafia do bufora ramki już w odpowiedniej orientacji.
4.17.2. Ekspozycja¶
Ekspozycja to czas integracji – jak długo fotodioda w każdym pikselu zbiera ładunek, zanim wiersz zostanie odczytany, w mikrosekundach. Sterownik startuje z włączoną pętlą automatycznej ekspozycji sensora, więc kamera stara się utrzymać średnią wartość pikseli w pobliżu wartości docelowej. Wyłączenie pętli ustala ekspozycję na wartość wybraną przez aplikację:
csi0.auto_exposure(False, exposure_us=8000)
Stała ekspozycja to właściwy wybór, gdy jasność sceny jest stabilna, a aplikacja potrzebuje przewidywalnego rozmycia ruchu lub spójnej intensywności między kolejnymi ramkami na potrzeby progowania. Odczytanie bieżącej ekspozycji – niezależnie od tego, czy ustawiła ją pętla, czy aplikacja – to osobne wywołanie:
us = csi0.exposure_us()
Wywołanie auto_exposure() z True i bez wartości ekspozycji oddaje kontrolę z powrotem pętli.
4.17.3. Wzmocnienie¶
Wzmocnienie to wzmacniacz stosowany do napięcia piksela, zanim dotrze ono do ADC, w decybelach. Podobnie jak w przypadku ekspozycji, sterownik startuje z włączoną pętlą automatycznego wzmocnienia. Często pojawiają się dwa wzorce. Ograniczenie górnego pułapu pozwala pętli dostosowywać się do oświetlenia, ale powstrzymuje ją przed wzmacnianiem szumu w nieskończoność w ciemnych scenach:
csi0.auto_gain(True, gain_db_ceiling=16)
Ustalenie stałego wzmocnienia to właściwy ruch, gdy aplikacja ustala także ekspozycję – stabilność wzmocnienia ma znaczenie dla aplikacji porównujących wartości pikseli między ramkami, takich jak śledzenie kolorów:
csi0.auto_gain(False, gain_db=0)
Bieżące wzmocnienie odczytuje się przez gain_db(). Za każdym razem, gdy aplikacja wyłącza automatyczne wzmocnienie, powinna również wyłączyć automatyczny balans bieli i automatyczną ekspozycję – w przeciwnym razie wciąż działające pętle sterujące będą przeciągać obraz w sposób niweczący stałe wzmocnienie.
4.17.4. Balans bieli¶
Balans bieli to wzmocnienie na kanał, które ISP stosuje do kanałów czerwonego, zielonego i niebieskiego wychodzących z etapu debayeryzacji, tak aby biały obiekt wyglądał na biały przy każdym kolorze światła. Pętla automatycznego balansu bieli oblicza te trzy wzmocnienia na podstawie statystyk na region, które ISP zbiera dla każdej ramki, i stosuje je na następnej ramce.
Większość aplikacji pozostawia pętlę włączoną. Śledzenie kolorów to częsty wyjątek – wzmocnienia są również tym, czym pętla manipuluje, goniąc za kolorowym obiektem, więc jeśli aplikacja próbuje znaleźć czerwoną plamę (blob), pętla po cichu przyciemni kanał czerwony i plama przestanie pasować. Zablokowanie pętli to naprawia:
csi0.auto_whitebal(False)
Przekaż jawną krotkę (r, g, b) w decybelach dla powtarzalnej kalibracji koloru – te same wzmocnienia na różnych płytkach i w różnych sesjach:
csi0.auto_whitebal(False, rgb_gain_db=(0.0, 0.0, 0.0))
Bieżące wzmocnienia odczytuje się jako krotkę przez rgb_gain_db().
4.17.5. Ograniczenie liczby klatek na sekundę¶
Sensory domyślnie pracują ze swoją natywną liczbą klatek na sekundę – od 30 do 60 klatek na sekundę w większości układów, znacznie więcej w sensorach wysokoprędkościowych, gdy rozmiar ramki jest wystarczająco mały. Ograniczenie tej liczby pozwala aplikacji zdławić kamerę do tego, z czym może nadążyć dalsze przetwarzanie:
csi0.framerate(15)
Na sensorach obsługujących sprzętową kontrolę liczby klatek to wywołanie wydłuża również budżet ekspozycji na ramkę, co może pomóc przy słabym oświetleniu; na pozostałych sterownik po prostu pomija nadmiarowe ramki na poziomie bufora ramki.
4.17.6. Wzór testowy¶
Wzór testowy w postaci pasków kolorów jest wbudowany w większość sensorów i przydatny do oddzielenia problemu obrazowania od problemu wyjścia. Włączenie go omija matrycę fotodiod i wysyła stały wzór tą samą ścieżką danych pikseli:
csi0.colorbar(True)
Jeśli wzór testowy wygląda poprawnie, ale obraz na żywo nie, usterka tkwi w optyce lub analogowym torze wejściowym sensora; jeśli nawet wzór testowy jest uszkodzony, problem jest gdzieś na magistrali danych pikseli albo w konfiguracji pixformat() / framesize(). Przekaż False, aby wrócić do obrazu na żywo.
Zobacz csi.CSI, aby poznać pełne API, w tym specyficzne dla sensora polecenia ioctl(), które udostępniają ustawienia unikalne dla poszczególnych rodzin sensorów.