Obraz z kamery HAR

Organy regulacyjne wprowadzają kilka wymagań, aby zapewnić, że pośrednia widoczność do tyłu dostarcza wystarczających informacji do precyzyjnego i szybkiego manewrowania pojazdem. Wpływa to na świadomość kierowcy dotyczącą otoczenia.

W przypadku systemów widoczności z tyłu opartych na systemie monitorowania za pomocą kamery (CMS) Narodowy Urząd ds. Bezpieczeństwa Ruchu Drogowego (NHTSA) wymaga spełnienia tych wymagań (S6.6.2.3 w odniesieniu do UNECE46):

  • S5.5.3 Czas odpowiedzi. Obraz z kamery cofania spełniający wymagania określone w punktach S5.5.1 (Pole widzenia) i S5.5.2 (Rozmiar), testowany zgodnie z punktem S14.2, wyświetla się w ciągu 2,0 sekundy od rozpoczęcia cofania.

  • S5.5.4 Czas wyświetlania. Obraz z kamery cofania spełniający wymagania określone w punktach S5.5.1 i S5.5.2 nie jest wyświetlany po zakończeniu zdarzenia cofania.

  • S5.5.5 Dezaktywacja. Obraz z kamery cofania spełniający wymagania określone w punktach S5.5.1 i S5.5.2 pozostaje widoczny podczas cofania, dopóki kierowca nie zmieni widoku lub dopóki dźwignia zmiany kierunku jazdy nie zostanie przestawiona z pozycji cofania.

  • S6.6.2.3.3.5 Artefakty Instrukcja obsługi powinna zawierać informacje o możliwych artefaktach i ich wpływie na częściowe zasłanianie pola widzenia i obiektów, co może wymagać od kierowcy szczególnej czujności i uwagi.

  • S6.2.2.3.4.1 Liczba klatek. Ruchy obiektów przed kamerą są płynne i naturalne. Minimalna liczba klatek systemu wynosi co najmniej 30 Hz (odpowiednik 30 kl./s). W warunkach słabego oświetlenia lub podczas manewrowania przy małej prędkości minimalna liczba klatek na sekundę wynosi co najmniej 15 Hz.

  • S6.2.2.3.4.2 Czas tworzenia obrazu. Czas tworzenia obrazu na monitorze jest krótszy niż 55 ms przy temperaturze 22°C ± 5°C.

  • S6.2.2.3.4.3 Czas oczekiwania systemu. System monitorowania z kamerą (CMS) ma wystarczająco małe opóźnienie, aby renderować scenerię niemal w tym samym czasie. Opóźnienie jest mniejsze niż 200 ms przy temperaturze 22 stopni Celsjusza ±5 stopni Celsjusza.

Aby spełnić te wymagania w przypadku systemu AAOS bez dodatkowych warstw, wprowadziliśmy system rozszerzonego widoku (EVS) w systemie operacyjnym Android Automotive (AAOS). Podobną usługę wprowadziliśmy w przypadku wirtualizacji na urządzeniach z AAOS z renderowaniem o wysokiej dostępności (HAR), które również spełnia te wymagania.

Potok podglądu z kamery

Te 5 etapów tworzy potok podglądu z kamery:

Etapy potoku podglądu z kamery

Rysunek 1. Etapy potoku podglądu z kamery.

Blokowanie usługi aparatu odnosi się do platformy usługi aparatu i jej warstwy abstrakcji, która umożliwia aplikacjom dostęp do dostępnych aparatów i korzystanie z nich. Funkcja Display Service wizualizuje dane obrazów dla użytkowników. Aplikacja realizuje docelowe ścieżki użytkownika za pomocą usług Camera Service i Display Service.

Główna ścieżka użytkownika dotycząca widoczności z tyłu:

  1. Kierowca ustawia selektor kierunku jazdy (bieg) w pozycji wstecznej, aby wywołać zdarzenie cofania.

  2. System rozsyła zdarzenie wspierające. Aplikacja odbiera transmisję i inicjuje blok wejścia kamery (usługa kamery) oraz moduł renderujący (usługa wyświetlania).

  3. Blok wejścia z kamery inicjuje platformę usługi aparatu i zwraca do aplikacji uchwyt usługi.

  4. Renderowanie inicjuje okno widoku dla danych wejściowych z kamery z kroku 4.

  5. Aplikacja wysyła żądanie do bloku wejścia kamery, aby rozpocząć wysyłanie buforów klatek i zdarzeń.

  6. Aplikacja umieszcza dostarczone bufory klatek w kolejce za pomocą wywołań zwrotnych (asynchronicznie). Bufory klatek należą do bloku wejściowego kamery, więc aplikacja nie może ich modyfikować.

  7. Aplikacja usuwa bufor ramki z kolejki (jeśli nie jest pusta) i tworzy widok użytkownika. Użytkownicy mogą utworzyć kopię, aby zmodyfikować zawartość.

  8. Aplikacja wysyła bufor do renderera.

  9. Renderer rysuje zawartość otrzymanego bufora na wyświetlaczu.

  10. Jeśli zdarzenie bazowe nadal trwa, przejdź do kroku 7. Po zakończeniu zdarzenia w tle aplikacja wysyła do bloku wejściowego kamery żądanie zatrzymania wysyłania buforów klatek i zdarzeń po ukryciu widoku przed użytkownikiem.

  11. Aplikacja opcjonalnie zamyka kamerę i zwalnia moduł renderujący.

Ilustruje to rysunek 1. Ten obraz wykorzystuje elementy interfejsu QNX Camera Library API do korzystania z platformy Camera Service.

Główna ścieżka użytkownika HAR

Rysunek 2. Główna ścieżka użytkownika HAR.

Blok wejściowy kamery deklaruje 3 interfejsy:

  • CameraManager, deklaruje metody zarządzania urządzeniami z kamerą. Na przykład aplikacja używa tego interfejsu do otwierania (rezerwowania) docelowego urządzenia z kamerą.

  • CameraDevice deklaruje metody sterowania kamerą, np. rozpoczynania lub zatrzymywania strumienia danych.

  • CameraStreamListener deklaruje jedną metodę odbierania różnych zdarzeń z kamery docelowej.

Projektowanie

W tej sekcji opisujemy projekt systemu.

Wrażenia użytkownika

Kierowca może wyświetlić podgląd z kamery cofania na wyświetlaczu zestawu wskaźników, gdy włączy bieg wsteczny. Wyświetlacz przestaje wyświetlać podgląd z kamery, gdy kierowca przestawi bieg z wstecznego.

Możesz włączyć dodatkowe ścieżki użytkownika. Kierowca może na przykład wyświetlić obszar niewidoczny w lusterkach, gdy włączy kierunkowskaz.

Uruchamianie podglądu z kamery

Podczas korzystania z aparatów aplikacja wylicza i ocenia dostępne aparaty, aby znaleźć najlepszy aparat do zamierzonego celu. Na przykład w przypadku widoczności z tyłu aplikacja wyszukuje na liście dostępnych kamer tę, która pokazuje tylną część pojazdu.

Aplikacja ocenia to, sprawdzając charakterystykę każdej kamery, np. lokalizację, kierunek obiektywu, liczbę klatek na sekundę, rozdzielczość wyjściową i format wyjściowy. Jeśli kilka aparatów ma te same wymagane cechy, aplikacja może sprawdzić dodatkowe cechy, takie jak pole widzenia i odległość ogniskowa.

Ilustracja przedstawia sekwencję uruchamiania podglądu z aparatu statycznego:

Uruchamianie podglądu z kamery ze statyczną konfiguracją kamery

Rysunek 3. Uruchom podgląd z kamery ze statyczną konfiguracją.

Zatrzymaj podgląd z kamery

Aplikacja przestaje zapewniać widoczność z tyłu po zakończeniu cofania. Aby uniknąć wyświetlania pustego ekranu lub nieruchomego obrazu, aplikacja najpierw ukrywa widok przed użytkownikiem, a następnie żąda, aby blok wejścia kamery przestał wysyłać zdarzenia.

Ilustracja przedstawiająca sekwencję zatrzymywania strumienia danych z kamery docelowej:

Zatrzymywanie strumienia danych z docelowego urządzenia z kamerą

Rysunek 4. Zatrzymaj strumień danych z kamery docelowej.

Błędy

Urządzenie z kamerą może nieoczekiwanie przestać wysyłać nowy bufor klatek. Aby wykrywać takie zdarzenia, blok wejściowy kamery może mieć licznik czasu, który wygasa po nadejściu nowej klatki, i wysyłać powiadomienie, gdy ten licznik wygaśnie.

Gdy aplikacja otrzyma powiadomienie, poinformuje użytkownika, że podgląd z kamery nie jest już dostępny, i spróbuje go przywrócić, zamykając urządzenie z kamerą i otwierając je ponownie. Na rysunku 5 pokazano, jak aplikacja obsługuje przekroczenie limitu czasu:

Obsługa przekroczenia limitu czasu

Rysunek 5. Obsługa przekroczenia limitu czasu (zawieszony strumień danych).

Blok wejścia kamery może zgłaszać incydenty inne niż zawieszony strumień danych i osadzać więcej szczegółów w buforach. Producenci OEM mogą używać tych metadanych zdarzenia do obsługi incydentów na swojej platformie.

Działania

Interfejs API jest używany przez aplikacje działające na hoście i zarządzające wyświetlaczem zestawu wskaźników za pomocą HAR (niebieskie bloki na schemacie poniżej).

Diagram systemu przedstawiono na rysunku 5:

Schemat systemu

Rysunek 6. Diagram systemu.

Usługi

Wywołania interfejsu API powinny być uruchamiane w kontekście procesu wywołującego.

Interfejsy API

Nowy interfejs API jest przeznaczony tylko dla aplikacji, które zarządzają podglądem z kamery na wyświetlaczu zestawu wskaźników za pomocą HAR. Interfejs API jest dostępny za pomocą warstwy abstrakcji platformy i jest łączony dynamicznie.

Interfejs CameraInputBlock deklaruje metody inicjowania funkcji aparatu i pobierania menedżera bloków wejściowych. Aplikacja używa zwróconej instancji CameraManager do zarządzania urządzeniami z aparatem.

// This class represents a camera input block for the application that manages the
// instrument cluster display with Harry.
public class CameraInputBlock : public InputBlock {
    public:
        // Clean up the resources.
        virtual ~CameraInputBlock();

        // A method inherited from InputBlock class. This method initializes
        // CameraInputBlock instance; e.g. checking the platform camera service
        // is live.
        //
        // @return CAMERA_EPERM if the platform camera service is not
        //                      available.
        //         CAMERA_OK otherwise.
        virtual CameraError init() override;

        // A method inherited from InputBlock class. This method release all
        // resources held by this CameraInputBlock instance.
        virtual void release() override;

        // This method returns a CameraManager instance. The caller uses
        // this instance to manage camera devices.
        //
        // @param out If this method is successful, this points to a valid
        //            CameraManager instance.
        // @return CAMERA_EACCESS when we fail to create CameraManager instance
        //         to return.
        //         CAMERA_OK otherwise.
        virtual CameraError getCameraManager(
            std::shared_ptr<CameraManager>* out) = 0;

    private:
        // Handle to manage camera devices.
        std::shared_ptr<CameraManager> mMgr;

        // Handle to manage camera devices that have been opened by clients.
        std::set<CameraDevice> mCameras;
};

Klasa CameraManager deklaruje metody otwierania (lub przejmowania) kamer i zwalniania ich, gdy aplikacja zakończy korzystanie z danej kamery. Aplikacja może otwierać więcej niż 1 kamerę i korzystać z jej strumieni, aby uzyskać szersze pole widzenia lub widok wielokrotny.

// This pure virtual class declares methods to manage camera devices.
public class CameraManager {
    public:
        // This method returns a list of CameraDescriptor objects representing
        // available cameras.
        //
        // @param out A list of CameraDescriptor instances. This list may be
        //            empty if the platform camera service does not list any
        //            camera.
        // @return CAMERA_EACCESS if we failed to build a camera list.
        //         CAMERA_OK otherwise.
        virtual CameraError getCameraList(
            std::vector<CameraDescriptor>* out) = 0;

        // Open a camera device associated with a given string identifier.
        //
        // @param ID A string identifier of a camera device to request.
        // @param out A pointer to CameraDevice shared pointer object. This
        //            is null when we fail to open a target device.
        // @return CAMERA_ENODEV if no camera is associated with a given id.
        //         CAMERA_EACCESS if it fails to open a target device.
        //         CAMERA_OK otherwise.
        virtual CameraError open(
            std::string ID, std::shared_ptr<CameraDevice>* out) = 0;

        // Close a camera device associated with a given string identifier.
        // This method is assumed to be always successful.
        //
        // @param id A string identifier of a camera device to close.
        virtual void close(std::string id) = 0;
};

Jeśli aplikacje nie mogą wykryć, których kamer użyć, mogą wybrać kamerę, która najlepiej sprawdza się w danym kontekście. CameraManager::getCameraList() zwraca listę instancjiCameraDescriptor, która zawiera charakterystykę każdej kamery.

Klasa CameraDevice reprezentuje pojedyncze urządzenie kamery i deklaruje metody rozpoczynania i zatrzymywania strumienia danych. Jeśli charakterystyka kamery nie jest znana statycznie, klienci pobierają ją z deskryptora i ją analizują.

Na przykład klient może uzyskać z metadanych listę konfiguracji strumienia, które oferuje docelowe urządzenie z kamerą, i wybrać tę o najlepszych atrybutach (np. liczba klatek na sekundę, rozdzielczość i format wyjściowy).

// This class represents a single camera device.
public class CameraDevice {
    public:
        // Start a data stream that attributes are matching to given
        // configuration best.
        // If a selected configuration is not given (null), a data stream is
        // initiated in its default configuration and return.
        //
        // @param configuration Selected attributes of the imagery data stream.
        // @param listener An object to listen to an active data stream.
        // @param effective Actual attributes of started data stream.
        // @return CAMERA_EINVAL if a listener object is invalid.
        //         CAMERA_EIO if we failed to start a video stream.
        //         CAMERA_OK otherwise.
        virtual CameraError start(
                std::shared_ptr<CameraStreamConfiguration>& configuration,
                std::shared_ptr<CameraStreamListener>& listener,
                std::shared_ptr<CameraStreamConfiguration>* effective) = 0;

        // Stop a data stream.
        virtual void stop() = 0;

        // Get a camera descriptor.
        //
        // @param desc A set of attributes that defines this camera device.
        // @return CAMERA_ENODATA if a descriptor is not available.
        //         CAMERA_OK otherwise.
        CameraError getDescriptor(std::shared_ptr<CameraDescriptor>* desc) = 0;

        // Return a consumed buffer to the camera device. A client of active
        // stream must return a frame buffer explicitly by calling this method.
        virtual void doneWithFrame(std::shared_ptr<FrameBuffer>& buffer) = 0;

    private:
        // Describe this camera device.
        CameraDescriptor mDescriptor;

        // A weak reference to a listening client.
        std::weak_ptr<CameraStreamListener> mClient;
};

// This class declares attributes that characterize a camera device.
public class CameraDescriptor {
    public:
        // Unique std::string object to identify a single camera device.
        std::string mId;

        // A set of stream configurations this camera device is capable of. A
        // camera must have at least one stream configuration.
        std::set<CameraStreamConfiguration> mConfigurations;

        // Are more attributes needed to exist, such as locations, lens
        // facing directions, and intrinsic/extrinsic parameters?
};

// This class declares attributes that characterize an imagery data stream.
public class CameraStreamConfiguration {
    public:
        // Width of output of this stream in pixels.
        unsigned int mWidthInPixels;

        // Height of output of this stream in pixels.
        unsigned int mHeightInPixels;

        // An average number of frames per second.
        double mFrameRate;

        // A format of this stream's output. A client could calculate a
        // byte-per-pixel (bpp) from this.
        CameraColorFormat mFormat;
};

// This class represents a listener/callback object to listen to frames and
// events.
public class CameraStreamListener {
    public:
        // A listener method to receive various stream events including a new
        // frame buffer.
        //
        // @param event CameraStreamEvent object that represents a single event
        //              such as an arrival of a new frame buffer, camera stream
        //              is terminated, and so forth.
        virtual void onEvent(std::shared_ptr<CameraStreamEvent>* event) = 0;
};

Funkcja CameraDevice::start() przyjmuje 3 argumenty:

  • Konfiguracja transmisji wybrana przez kod wywołujący.

  • Detektor do odbierania zdarzeń strumienia.

  • Wskaźnik skutecznej konfiguracji strumienia danych. Zdecydowanie zalecamy, aby wywołujący sprawdził tę wartość, aby odpowiednio obsługiwać nadchodzące bufory klatek.

Gdy CameraDevice::start() rozpoczyna strumień danych za pomocą platformy usługi aparatu, przechowuje słabe odwołanie do obiektu słuchacza wywołującego, aby wykryć nieoczekiwane zakończenie wywołującego.

Gdy klient skończy korzystać z bufora klatek, musi powiadomić urządzenie z kamerą, że nie potrzebuje już bufora klatek, wywołując metodę CameraDevice::doneWithFrame().

Gdy strumień się rozpocznie, klient otrzyma wiadomości o zdarzeniach. Częstym komunikatem jest nowy bufor ramki. Za pomocą zarejestrowanej funkcji wywołania zwrotnego klient otrzymuje zdarzenie kNewFrameBuffer, które zawiera dane obrazu wraz z metadanymi bufora klatek. StreamEventType deklaruje więcej typów do obsługi innych zdarzeń strumienia. np. zatrzymany lub zawieszony strumień danych.

// This class lists events possibly occurring while a data stream is active.
enum class CameraStreamEventType {
    // A delivery of a new frame buffer.
    kNewFrameBuffer,
    // A data stream has been stopped.
    kStreamStopped,
    // No new frame buffer arrives for a while.
    kStreamHang,
    // Add more.
    ...
};

// This class represents a single instance of StreamEventType.
public class CameraStreamEvent {
    public:
        // Return a type of this event.
        //
        // @return CameraStreamEventType enum value.
        CameraStreamEventType getType() { return mType; }

        // Return a pointer to data associated with this event.
        //
        // @return A shared pointer object of the buffer that contains data for
        //         this event.
        std::shared_ptr<void> getData() { return mData; }

    private:
        // Describe a type of this event.
        CameraStreamEventType mType;

        // A pointer to the data buffer.
        std::shared_ptr<void> mData;
};

// This class inherits StreamEvent class and has additional fields to represent
// the frame buffer.
public class FrameBufferEvent : public CameraStreamEvent {
    public:
        // Return an identifier of this frame buffer.
        //
        // @return A unique integer value to identify this frame buffer.
        int getBufferID() { return mBufferID; }

        // Give access to frame buffer metadata.
        //
        // @return A shared pointer to the buffer that contains data besides
        //         the imagery data.
        std::shared_ptr<void> getMetadata() { return mMetadata; }

    private:
        // Unique integer to identify this buffer.
        int mBufferID;

        // A pointer to metadata of this frame buffer.
        std::shared_ptr<void> mMetadata;
};

Ten przykład pokazuje implementację interfejsu CameraInputBlock i jego aplikacji:

CameraError getCameraManager(std::shared_ptr<CameraManager>* out) {
    // During an instantiation, CameraManager will retrieve a list of camera
    // devices from the platform camera service and identify their attributes.
    *out = std::make_shared<CameraManager>();
    return CAMERA_OK;
}

// This method returns a list of CameraDescriptor objects representing available
// cameras.
CameraError CameraManager::getCameraList(std::vector<CameraDescriptor>* out) {
    if (mCameraList.size() < 1) {
        // Query a list of cameras and get their attributes.
    }
    *out = mCameraList;
    return CAMERA_OK;
}

// Open a camera device associated with a given string identifier.
CameraError CameraManager::open(std::string id, std::shared_ptr<CameraDevice>* out) {
    if (!mCameraList.contains(id)) {
        // We cannot identify any camera with a given value.
        return CAMERA_NODEV;
    }

    // During a construction, CameraDevice will obtain a handle of a target
    // camera device from the platform camera service.
    std::shared_ptr<CameraDevice> h = std::make_shared<CameraDevice>(id);
    if (!h) {
        // We fail to open a camera device.
        return CAMERA_EACCESS;
    }

    *out = h;
    return CAMERA_OK;
}

// Close a camera device associated with a given string identifier. This method
// is assumed to be always successful.
void CameraManager::close(std::string id) {
    if (!mCameraList.contains(id)) {
        // We ignore calls with unknown identifiers.
        return;
    }

    // mCameraList.remove() returns an object removed from the list.
    std::shared_ptr<CameraDevice> device = mCameraList.remove(id);

    // Ensure a device stops streaming.
    device->stop();
}

// Start a data stream that attributes are matching to given configuration
// best.
// If a selected configuration is not given (null), a data stream will be
// initiated in its default configuration and return.
CameraError CameraDevice::start(
        std::shared_ptr<CameraStreamConfiguration>& configuration,
        std::shared_ptr<CameraStreamListener>& listener,
        std::shared_ptr<CameraStreamConfiguration>* effective) {
    if (!listener) {
        return CAMERA_EINVAL;
    }

    // selectStreamConfiguration examines this camera's stream configurations
    // and returns the one closest to the selected configuration.
    CameraStreamConfiguration config = selectStreamConfiguration(configuration);

    // mDevice refers to the camera handle for the platform camera service. We
    // may need to translate CameraStreamConfiguration for the platform service.
    mDevice->configure(
        configuration.mWidth, configuration.mHeight, configuration.mFormat);

    // Start a data stream with a callback object.
    if (!mDevice->startStream(mCallback)) {
        // We failed to start a data stream.
        return CAMERA_EIO;
    }

    return CAMERA_OK;
}

// Stop a data stream.
void CameraDevice::stop() {
    if (!mDevice) {
        // Nothing to do if we don't have a valid camera handle for the
        // platform camera service.
        return;
    }

    mDevice->stopStream();
}

// Get a camera descriptor.
CameraError CameraDevice::getDescriptor(std::shared_ptr<CameraDescriptor>* desc) {
    if (!mDescriptor) {
        return CAMERA_ENODATA;
    }

    *desc = *mDescriptor;
    return CAMERA_OK;
}

// Return a consumed buffer to the camera device. A client of active stream
// must return a frame buffer explicitly by calling this method.
void CameraDevice::doneWithFrame(std::shared_ptr<FrameBuffer>& buffer) {
    if (!mBufferRecords.contains(buffer.getId())) {
        // Ignore a call with unknown frame buffer.
        return;
    }

    // Simply remove from the record.
    (void)mBufferRecords.remove(buffer.getId());
}

// This method handles gear-shift events.
void Application::handleGearShift(GearSelection selection) {
    switch (selection) {
        case GEAR_SELECTION_REVERSE:
            // Upon the reverse gear selection, we are going to start a video
            // stream and show its preview on the instrument cluster display.
            (void)startStream(mCameraInputBlock);

            // FIXME: Exact method to control the camera preview window on the
            // instrument display is to be determined.
            show(mRearVisibilityWindow);
            break;

        default:
            // Upon all other gear selection, we are going to stop a video
            // stream (if it's running) and hide the preview.
            stopStream(mCameraInputBlock);

            // FIXME: Exact method to control the camera preview window on the
            // instrument display is to be determined.
            hide(mRearVisibilityWindow);
            break;
    }
}

bool Application::startStream(std::shared_ptr<CameraInputBlock> handle) {
    return handle->start(std::bind(&Application::handleStreamCallback, this);
}

void Application::stopStream(std::shared_ptr<CameraInputBlock> handle) {
    handle->stop();
}

// This method handles a stream callback.
void Application::handleStreamCallback(StreamEvent& event) {
    switch (event.getType()) {
        case StreamEventType::kNewFrameBuffer:
            // Handle a new frame buffer. We may just enqueue it for the
            // future or forward to CameraInputBlock client.
            break;

        case StreamEventType::kStreamStopped:
            // Handle as an incident if this event is not expected.
            break;

        // More cases to be added.
    }
}

void Application::handleNewFrameBuffer(StreamEvent& event) {
    // Enqueue a new frame buffer for the further processing. A buffer
    // must be returned explicitly by calling
    // CameraDevice.doneWithFrame(FrameBuffer&) method.
}

void Application::handleStreamEvent(StreamEvent& event) {
    // Handle a received stream event except a new frame buffer's
    // arrival; e.g. a video stream is terminated unexpectedly.
}

Wydajność

Widoczność z tyłu jest zgodna z tymi przepisami lokalnymi.

Wartość Rozporządzenie
Czas odpowiedzi CFR 571.111 S5.5.3
Liczba klatek UNECE R46 6.2.2.3.4
Czas tworzenia obrazu UNECE R46 6.2.2.3.4.2
Czas oczekiwania systemu UNECE R46 6.2.2.3.4.3

Prywatność

W zakresie prywatności:

  • Interfejs API nie wymaga od implementacji zbierania, rejestrowania ani przechowywania informacji umożliwiających identyfikację osób. Ponieważ jednak zarejestrowane dane obrazów (lub powiązane z nimi metadane) mogą zawierać informacje umożliwiające identyfikację, aplikacja korzystająca z interfejsu API musi uzyskać wyraźną zgodę użytkownika.

  • Użytkownicy nie mogą sterować kamerami, aby wyświetlać podgląd na wyświetlaczu zestawu wskaźników, ponieważ kamery pełnią funkcje o krytycznym znaczeniu dla bezpieczeństwa. Producenci OEM uzyskują zgodę użytkownika podczas konfiguracji lub od kierowcy.

  • Ten interfejs API nie obsługuje klientów kamery działających w tle. Wskaźnik prywatności, który informuje użytkowników, że urządzenie z kamerą rejestruje dane, nie jest więc objęty tymi zasadami.