HoloLens-Foto-/Videokamera in Unreal

Die HoloLens weist eine Foto-/Videokamera (FV-Kamera) auf dem Visor auf, die sowohl für die Mixed Reality-Aufnahme (Mixed Reality Capture, MRC) als auch zum Lokalisieren von Objekten im Weltbereich von Unreal anhand von Pixelkoordinaten im Kamerabild verwendet werden kann.

Wichtig

Die PV-Kamera wird nicht mit Holographic Remoting unterstützt, aber es ist möglich, eine mit Ihrem PC verbundene Webcam zu verwenden, um die PV-Kamerafunktion von HoloLens zu simulieren.

Setup des FV-Kamerafeeds

Wichtig

Die FV-Kamera ist sowohl in Windows Mixed Reality- als auch in OpenXR-Plug-Ins implementiert. Für OpenXR muss allerdings das Microsoft OpenXR-Plug-In installiert sein. Außerdem gilt für OpenXR für Unreal 4.26 eine Einschränkung: Die Kamera kann mit DirectX11 RHI funktionieren. Diese Einschränkung wurde in Unreal 4.27.1 oder höher behoben.

  • Aktivieren Sie in Project Settings > HoloLens (Projekteinstellungen > HoloLens) die Webcam-Funktionalität:

Screenshot der HoloLens-Projekteinstellungen mit hervorgehobener Webcam-Eigenschaft

  • Erstellen Sie einen neuen Akteur mit dem Namen „CamCapture“, und fügen Sie eine Ebene zum Rendern des Kamerafeeds hinzu:

Screenshot des Akteurs mit einer hinzugefügten Ebene

  • Fügen Sie Ihrer Szene den Akteur hinzu, erstellen Sie ein neues Material mit dem Namen „CamTextureMaterial“ und einem Texture-Objektparameter sowie einem Texturbeispiel. Senden Sie die RGB-Daten der Textur an die Ausgabe „Emissionsfarbe“:

Blaupause eines Material- und Texturbeispiels

Rendern des FV-Kamerafeeds

  • Schalten Sie in der CamCapture-Blaupause die FV-Kamera ein:

Blaupause der Funktion zum Umschalten von ARCapture mit eingeschalteter FV-Kamera

  • Erstellen Sie eine dynamische Materialinstanz aus „CamTextureMaterial“, und weisen Sie dieses Material der Ebene des Akteurs zu:

Blaupause der Funktion zum Erstellen einer dynamischen Materialinstanz

  • Rufen Sie die Textur aus dem Kamerafeed ab, und weisen Sie sie dem dynamischen Material zu, wenn sie gültig ist. Wenn die Textur nicht gültig ist, starten Sie einen Timer, und versuchen Sie es nach dessen Ablauf erneut:

Blaupause der Kamerafeed-Textur, die dem dynamischen Material zugewiesen ist

  • Skalieren Sie abschließend die Ebene um das Seitenverhältnis des Kamerabilds:

Blaupause der Ebene, die relativ zum Seitenverhältnis des Kamerabilds skaliert ist

Finden von Kamerapositionen im Weltbereich

Die Kamera in der HoloLens 2 ist gegenüber dem Head Tracking des Geräts vertikal versetzt. Es gibt ein paar Funktionen, um die Position der Kamera im Weltbereich zu ermitteln, um diesem Versatz Rechnung zu tragen.

„GetPVCameraToWorldTransform“ ruft die Transformation der FV-Kamera im Weltbereich ab und wird auf der Kameralinse positioniert:

Blaupause der Funktion zum Abrufen der Transformation der FV-Kamera gegenüber dem Weltbereich

„GetWorldSpaceRayFromCameraPoint“ wirft einen Strahl aus dem Kameraobjektiv in die Szene im Weltbereich von Unreal, um den Inhalt eines Pixels im Kamerabild herauszufinden:

Blaupause des Strahls vom Kamerapunkt zum Abrufen des Weltbereichs

„GetPVCameraIntrinsics“ gibt die systeminternen Werte der Kamera zurück, die bei der Verarbeitung eines Kamerabilds beim maschinellen Sehen verwendet werden können:

Blaupause der Funktionen zum Abrufen der systeminternen PVCamera-Werte

Um herauszufinden, was an einer bestimmten Pixelkoordinate im Weltbereich vorhanden ist, verwenden Sie eine Zeilenablaufverfolgung mit dem Weltbereichs-Strahl:

Blaupause des Weltbereich-Strahls, der verwendet wird, um zu ermitteln, was im Weltbereich an einer bestimmten Koordinate vorhanden ist

Hier werfen wir einen 2-m-Strahl vom Kameraobjektiv auf die Raumposition der Kamera, die ¼ vom oberen linken Punkt des Bilds entfernt ist. Verwenden Sie dann das Trefferergebnis, um etwas an der Position zu rendern, an der das Objekt im Weltbereich vorhanden ist:

Blaupause eines 2-m-Strahls, der vom Kameraobjektiv aus auf die Raumposition der Kamera geworfen wird, die 1/4 vom oberen linken Punkt des Bilds entfernt ist.

Wenn räumliche Abbildung verwendet wird, stimmt diese Trefferposition mit der Oberfläche überein, die von der Kamera gesehen wird.

Rendern des FV-Kamerafeeds in C++

  • Erstellen Sie einen neuen C++-Akteur mit dem Namen „CamCapture“.
  • Fügen Sie in der Datei „build.cs“ des Projekts „AugmentedReality“ zur Liste „PublicDependencyModuleNames“ hinzu:
PublicDependencyModuleNames.AddRange(
    new string[] {
        "Core",
        "CoreUObject",
        "Engine",
        "InputCore",
        "AugmentedReality"
});
  • Schließen Sie „ARBlueprintLibrary.h“ in „CamCapture.h“ ein
#include "ARBlueprintLibrary.h"
  • Darüber hinaus müssen Sie lokale Variablen für das Gittermodell und das Material hinzufügen:
private:
    UStaticMesh* StaticMesh;
    UStaticMeshComponent* StaticMeshComponent;
    UMaterialInstanceDynamic* DynamicMaterial;
    bool IsTextureParamSet = false;
  • Aktualisieren Sie in „CamCapture.cpp“ den Konstruktor, um der Szene ein statisches Gittermodell hinzuzufügen:
ACamCapture::ACamCapture()
{
    PrimaryActorTick.bCanEverTick = true;

    // Load a mesh from the engine to render the camera feed to.
    StaticMesh = LoadObject<UStaticMesh>(nullptr, TEXT("/Engine/EngineMeshes/Cube.Cube"), nullptr, LOAD_None, nullptr);

    // Create a static mesh component to render the static mesh
    StaticMeshComponent = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("CameraPlane"));
    StaticMeshComponent->SetStaticMesh(StaticMesh);

    // Scale and add to the scene
    StaticMeshComponent->SetWorldScale3D(FVector(0.1f, 1, 1));
    this->SetRootComponent(StaticMeshComponent);
}

Erstellen Sie in „BeginPlay“ eine dynamische Materialinstanz aus dem Kameramaterial des Projekts, wenden Sie es auf die statische Gittermodellkomponente an, und starten Sie die HoloLens-Kamera.

Klicken Sie im Editor mit der rechten Maustaste auf das „CamTextureMaterial“ im Inhaltsbrowser, und wählen Sie „COPY-Referenz“ aus, um die Zeichenfolge für „CameraMatPath“ abzurufen.

void ACamCapture::BeginPlay()
{
    Super::BeginPlay();

    // Create a dynamic material instance from the game's camera material.
    // Right-click on a material in the project and select "Copy Reference" to get this string.
    FString CameraMatPath("Material'/Game/Materials/CamTextureMaterial.CamTextureMaterial'");
    UMaterial* BaseMaterial = (UMaterial*)StaticLoadObject(UMaterial::StaticClass(), nullptr, *CameraMatPath, nullptr, LOAD_None, nullptr);
    DynamicMaterial = UMaterialInstanceDynamic::Create(BaseMaterial, this);

    // Use the dynamic material instance when rendering the camera mesh.
    StaticMeshComponent->SetMaterial(0, DynamicMaterial);

    // Start the webcam.
    UARBlueprintLibrary::ToggleARCapture(true, EARCaptureType::Camera);
}

Rufen Sie in Tick die Textur bei der Kamera ab, legen Sie sie auf den Texturparameter im Material „CamTextureMaterial“ fest, und skalieren Sie die statische Gittermodellkomponente um das Seitenverhältnis des Kamerabilds:

void ACamCapture::Tick(float DeltaTime)
{
    Super::Tick(DeltaTime);

    // Dynamic material instance only needs to be set once.
    if(IsTextureParamSet)
    {
        return;
    }

    // Get the texture from the camera.
    UARTexture* ARTexture = UARBlueprintLibrary::GetARTexture(EARTextureType::CameraImage);
    if(ARTexture != nullptr)
    {
        // Set the shader's texture parameter (named "Param") to the camera image.
        DynamicMaterial->SetTextureParameterValue("Param", ARTexture);
        IsTextureParamSet = true;

        // Get the camera instrincs
        FARCameraIntrinsics Intrinsics;
        UARBlueprintLibrary::GetCameraIntrinsics(Intrinsics);

        // Scale the camera mesh by the aspect ratio.
        float R = (float)Intrinsics.ImageResolution.X / (float)Intrinsics.ImageResolution.Y;
        StaticMeshComponent->SetWorldScale3D(FVector(0.1f, R, 1));
    }
}

Nächster Entwicklungsprüfpunkt

Wenn Sie der Unity-Entwicklungs-Journey folgen, die wir entworfen haben, befinden Sie sich mitten im Kennenlernen der Mixed Reality-Plattformfunktionen und APIs. Von hier aus können Sie mit dem nächsten Thema fortfahren:

Oder wechseln Sie direkt zur Bereitstellung Ihrer App auf einem Gerät oder Emulator:

Sie können jederzeit zu den Prüfpunkten für die Unreal-Entwicklung zurückkehren.

Siehe auch