Strumienie wyjściowe, przycinanie i powiększanie

Strumienie wyjściowe

W przypadku wszystkich rozdzielczości i formatów wyjściowych podsystem kamery działa wyłącznie na potoku opartym na ANativeWindow. Możesz skonfigurować wiele strumieni naraz, aby wysyłać jedną klatkę do wielu elementów docelowych, np. do GPU, kodera wideo, RenderScriptu lub buforów widocznych dla aplikacji (RAW Bayer, przetworzone bufory YUV czy bufory zakodowane w formacie JPEG).

W celu optymalizacji te strumienie wyjściowe muszą zostać skonfigurowane z wyprzedzeniem, a ich liczba jest ograniczona. Umożliwia to wstępną alokację buforów pamięci i konfigurację sprzętu kamery, dzięki czemu podczas przesyłania żądań z wieloma lub różnymi wymienionymi kanałami wyjściowymi nie będzie opóźnień w spełnianiu żądań.

Więcej informacji o gwarantowanych kombinacjach wyjściowych strumieni, które zależą od obsługiwanego poziomu sprzętu, znajdziesz w sekcji createCaptureSession().

Przycinanie

Przycinanie pełnej tablicy pikseli (na potrzeby powiększenia cyfrowego i innych zastosowań, gdy pożądane jest mniejsze pole widzenia) jest przekazywane za pomocą ustawienia ANDROID_SCALER_CROP_REGION. To ustawienie jest ustawiane dla każdej prośby i może się zmieniać w zależności od prośby. Jest to kluczowe dla płynnego stosowania cyfrowego powiększenia.

Region jest zdefiniowany jako prostokąt (x, y, szerokość, wysokość), gdzie (x, y) opisuje lewy górny róg prostokąta. Prostokąt jest zdefiniowany w układzie współrzędnych aktywnego tablicznego czujnika, przy czym współrzędne (0,0) odpowiadają lewemu górnemu wierzchołkowi tablicy aktywnych pikseli. Dlatego szerokość i wysokość nie mogą być większe niż wymiary podane w polu informacji statycznej ANDROID_SENSOR_ACTIVE_PIXEL_ARRAY. Minimalna dozwolona szerokość i wysokość są zgłaszane przez HAL za pomocą pola statycznych informacji ANDROID_SCALER_MAX_DIGITAL_ZOOM, które opisuje maksymalny obsługiwany współczynnik powiększenia. Dlatego minimalna szerokość i wysokość regionu przycinania to:

  {width, height} =
   { floor(ANDROID_SENSOR_ACTIVE_PIXEL_ARRAY[0] /
       ANDROID_SCALER_MAX_DIGITAL_ZOOM),
     floor(ANDROID_SENSOR_ACTIVE_PIXEL_ARRAY[1] /
       ANDROID_SCALER_MAX_DIGITAL_ZOOM) }

Jeśli obszar przycięcia musi spełniać określone wymagania (np. musi zaczynać się od równomiernych współrzędnych, a jego szerokość i wysokość muszą być takie same), HAL musi wykonać niezbędne zaokrąglenia i zapisać końcowy region przycinania używany w metadanych wyniku wyjściowego. Podobnie, jeśli HAL implementuje stabilizację wideo, musi dostosować obszar przycinania wyniku, aby opisać obszar faktycznie uwzględniony w wyjściu po zastosowaniu stabilizacji wideo. Ogólnie rzecz biorąc, aplikacja korzystająca z kamery musi mieć możliwość określenia pola widzenia na podstawie regionu przycinania, wymiarów czujnika obrazu i ogniskowej obiektywu.

Ponieważ region przycinania jest stosowany we wszystkich strumieniach, które mogą mieć inne proporcje niż region przycinania, dokładny obszar czujnika używany w przypadku każdego strumienia może być mniejszy niż region przycinania. Każdy strumień powinien zachowywać kwadratowe piksele i współczynnik proporcji poprzez minimalne przycięcie zdefiniowanego obszaru przycinania. Jeśli współczynnik proporcji strumienia jest szerszy niż obszar przycięcia, należy go jeszcze bardziej przyciąć w pionie, a jeśli współczynnik proporcji jest węższy niż obszar przycięcia, należy go przyciąć w poziomie.

W każdym przypadku przycięty strumień musi być wyśrodkowany w całym obszarze przycięcia, a każdy strumień jest przycięty tylko w poziomie lub w pionie w stosunku do pełnego obszaru przycięcia, nigdy w obu kierunkach.

Jeśli na przykład zdefiniowano 2 strumienie: strumień 640 x 480 (współczynnik 4:3) i strumień 1280 x 720 (współczynnik proporcji 16:9), poniżej przedstawiamy oczekiwane regiony wyjściowe dla każdego strumienia dla kilku przykładowych obszarów przycięcia na hipotetycznej macierze 3 Mpix (2000 x 1500).

Region przycięcia: (500, 375, 1000, 750) (format obrazu 4:3)
Przycięty strumień 640 x 480: (500, 375, 1000, 750) (równy regionowi przycięcia)
Przycięty strumień 1280 x 720: (500, 469, 1000, 562)

crop-region-43-ratio

Rysunek 1. Format obrazu 4:3

Region przycięcia: (500, 375, 1333, 750) (format obrazu 16:9)
Przycięty obraz strumienia 640 x 480: (666, 375, 1000, 750)
Przycięty obraz strumienia 1280 x 720: (500, 375, 1333, 750) (równy regionowi przycięcia)

crop-region-169-ratio

Rysunek 2. Współczynnik proporcji 16:9

Region przycięcia: (500, 375, 750, 750) (format obrazu 1:1)
640 x 480: (500, 469, 750, 562)
1280 x 720: (500, 543, 750, 414)

współczynnik-regionu-11

Rysunek 3. Format obrazu 1:1

Ostatni przykład: transmisja w formacie 1024 x 1024 w formacie kwadratowym zamiast 480p:
Region przycinania: (500, 375, 1000, 750) (format obrazu 4:3)
Przycięty obraz transmisji 1024 x 1024: (625, 375, 750, 750)
Przycięty obraz transmisji 1280 x 720: (500, 469, 1000, 562)

crop-region-43-square-ratio

Rysunek 4. Format obrazu 4:3, kwadrat

Przetwarzanie ponownie

Dodatkowa obsługa plików z obrazami w formacie RAW jest zapewniana przez przetwarzanie danych Bayera w formacie RAW. Ta obsługa pozwala potokowi aparatu przetworzyć wcześniej zarejestrowany bufor i metadane RAW (całą zarejestrowaną wcześniej klatkę) w celu wygenerowania nowego wyrenderowanego formatu YUV lub JPEG.

Zoom

Na urządzeniach z Androidem 11 lub nowszym aplikacja może używać powiększenia aparatu (cyfrowego i optycznego) za pomocą ustawienia ANDROID_CONTROL_ZOOM_RATIO.

Współczynnik powiększenia jest zdefiniowany jako współczynnik zmiennoprzecinkowy. Zamiast ANDROID_SCALER_CROP_REGION do przycinania i powiększania, aplikacja może używać ANDROID_CONTROL_ZOOM_RATIO do kontrolowania poziomu powiększenia oraz ANDROID_SCALER_CROP_REGION do przycinania poziomego i pionowy, aby uzyskać proporcje inne niż te, które zapewnia czujnik aparatu.

System z wieloma kamerami może zawierać więcej niż 1 obiektyw o różnych ogniskowych, a użytkownik może używać zoomu optycznego, przełączając się między obiektywami. Korzystanie z tabeli ANDROID_CONTROL_ZOOM_RATIO ma zalety w tych sytuacjach:

  • Zbliżanie z obiektywu szerokokątnego na teleobiektyw: współczynnik zmiennoprzecinkowy zapewnia większą precyzję w porównaniu z wartościami całkowitymi ANDROID_SCALER_CROP_REGION.
  • Zmniejszanie zoomu z obiektywu szerokokątnego na ultraszerokokątny: ANDROID_CONTROL_ZOOM_RATIO obsługuje zmniejszanie zoomu (<1.0f), podczas gdy ANDROID_SCALER_CROP_REGION tego nie robi.

Aby to zilustrować, podajemy kilka scenariuszy z różnymi współczynnikami powiększenia, regionami przycinania i strumieniami wyjściowymi, korzystając z tej samej hipotetycznej kamery zdefiniowanej w poprzedniej sekcji.

Współczynnik powiększenia: 2,0; 1/4 oryginalnego pola widzenia
Region przycinania: (0, 0, 2000, 1500) (współczynnik proporcji 4:3)
Przycięcie strumienia 640 x 480: (0, 0, 2000, 1500) (równe: 2 x 20, 1280)
1280

zoom-ratio-2-crop-43

Rysunek 5. Powiększenie 2,0, format obrazu 4:3

Współczynnik powiększenia: 2,0; 1/4 oryginalnego pola widzenia
Obszar przycinania: (0, 187, 2000, 1125) (format 16:9)
Przycięty strumień 640 x 480: (250, 187, 1500, 1125) (format pillarbox)
Przycięty strumień 1280 x 720: (0, 187, 2000, 1125) (równy obszarowi przycinania)

współczynnik-powiększenia-2-przycięcie-169

Rysunek 6. Zoom 2,0, format obrazu 16:9

Współczynnik powiększenia: 0, 5; 4x oryginalnego pola widzenia (250 x 480, obiektyw szerokokątny 8 x 4, obiektyw ultraszerokokątny 4)
Region przycinania: (250, 0, 1500, 1500) (współczynnik proporcji 1:1)
Przycięcie strumienia 640 x 480: (250, 187, 1500, 1125)

obrazy/współczynnik powiększenia-0,5-przycięcia-11

Rysunek 7. Powiększenie 0,5, format obrazu 1:1

Jak widać na poniższych wykresach, system współrzędnych regionu przycięcia zmienia się na skuteczne pole widzenia po powiększeniu i jest reprezentowane przez prostokąt o następujących wymiarach: (0, 0, activeArrayWith, activeArrayHeight). To samo dotyczy regionów AE/AWB/AF i twarzy. Ta zmiana systemu współrzędnych nie dotyczy rejestrowania w formacie RAW ani powiązanych z nim metadanych, takich jak intrinsicCalibrationlensShadingMap.

W tym samym hipotetycznym przykładzie, zakładając, że strumień wyjściowy 1 (640 x 480) jest strumieniem wizjer, powiększenie 2,0x można uzyskać na jeden z 2 sposobów:

  • zoomRatio = 2.0, scaler.cropRegion = (0, 0, 2000, 1500)
  • zoomRatio = 1.0 (domyślnie), scaler.cropRegion = (500, 375, 1000, 750)

Aby aplikacja ustawiła android.control.aeRegions na lewy górny ćwiartkę pola widzenia wizjera, ustaw android.control.aeRegions na (0, 0, 1000, 750), a android.control.zoomRatio na 2.0. Aplikacja może też ustawić android.control.aeRegions na równoważny region (500, 375, 1000, 750) dla android.control.zoomRatio klasy 1.0.