HoloLens Zdjęcie/Kamera wideo w Unreal

Urządzenie HoloLens ma kamerę foto/wideo (PV) na wizjerze, która może być używana zarówno do Mixed Reality Capture (MRC) i lokalizowania obiektów w przestrzeni świata Unreal world ze współrzędnych pikseli w ramce aparatu.

Ważne

Kamera PV nie jest obsługiwana przy użyciu komunikacji wirtualnej Holographic Remoting, ale można użyć kamery internetowej dołączonej do komputera w celu symulowania funkcji kamery PV HoloLens.

Instalacja kanału informacyjnego kamery PV

Ważne

Kamera PV jest implementowana zarówno w wtyczkach Windows Mixed Reality, jak i OpenXR. Jednak rozszerzenie OpenXR wymaga zainstalowania wtyczki Microsoft OpenXR . Ponadto rozszerzenie OpenXR for Unreal 4.26 ma ograniczenie: aparat może pracować z directX11 RHI. To ograniczenie zostało naprawione w wersji Unreal 4.27.1 lub nowszej.

  • W obszarze Ustawienia > projektu HoloLens włącz funkcję kamery internetowej :

Zrzut ekranu przedstawiający ustawienia projektu HoloLens z wyróżnioną właściwością Kamera internetowa

  • Utwórz nowego aktora o nazwie "CamCapture" i dodaj płaszczyznę w celu renderowania kanału informacyjnego kamery:

Zrzut ekranu przedstawiający aktora z dodanym samolotem

  • Dodaj aktora do sceny, utwórz nowy materiał o nazwie CamTextureMaterial z parametrem obiektu tekstury i próbką tekstury. Wyślij dane rgb tekstury do koloru wyjściowego emisive:

Strategia próbki materiału i tekstury

Renderowanie kanału informacyjnego kamery PV

  • W strategii CamCapture włącz kamerę PV:

Strategia funkcji Toggle ARCapture z włączoną kamerą PV

  • Utwórz dynamiczne wystąpienie materiału z camTextureMaterial i przypisz ten materiał do płaszczyzny aktora:

Strategia funkcji Create Dynamic Material Instance (Tworzenie dynamicznego wystąpienia materiału)

  • Pobierz teksturę ze źródła kamery i przypisz ją do materiału dynamicznego, jeśli jest prawidłowa. Jeśli tekstura jest nieprawidłowa, uruchom czasomierz i spróbuj ponownie po przekroczeniu limitu czasu:

Strategia tekstury kanału informacyjnego kamery przypisanej do materiału dynamicznego

  • Na koniec przeskaluj płaszczyznę według współczynnika proporcji obrazu aparatu:

Strategia płaszczyzny skalowana względem współczynnika proporcji obrazów aparatu

Znajdowanie pozycji kamery w przestrzeni światowej

Aparat na HoloLens 2 jest przesunięty pionowo z śledzenia głowy urządzenia. Istnieje kilka funkcji, aby zlokalizować aparat w przestrzeni światowej, aby uwzględnić przesunięcie.

GetPVCameraToWorldTransform pobiera transformację w światowej przestrzeni kamery PV i zostanie umieszczony na obiektywie aparatu:

Strategia funkcji Get PVCamera to World Transform

GetWorldSpaceRayFromCameraPoint rzuca promienie z obiektywu aparatu do sceny w przestrzeni świata Unreal, aby znaleźć zawartość piksela w ramce kamery:

Strategia Get World Space Ray z camera point

Funkcja GetPVCameraIntrinsics zwraca wartości wewnętrzne aparatu, które mogą być używane podczas przetwarzania obrazów komputerowych na ramce aparatu:

Strategia funkcji wewnętrznych Get PVCamera

Aby znaleźć to, co istnieje w przestrzeni światowej na określonej współrzędnej piksela, użyj śladu linii ze światowym promieniem kosmicznym:

Strategia światowego promienia kosmicznego używana do dowiedzieć się, co istnieje w przestrzeni światowej na określonej współrzędnej

Tutaj oddaliśmy 2-metrowy ray z obiektywu aparatu do pozycji przestrzeń kamery 1/4 z lewej górnej części ramy. Następnie użyj wyniku trafienia, aby renderować element, w którym obiekt istnieje w przestrzeni światowej:

Strategia 2-metrowego promienia odlewanego z obiektywu aparatu do pozycji przestrzeń kamery 1/4 z lewej górnej części ramy

W przypadku korzystania z mapowania przestrzennego ta pozycja trafienia będzie zgodna z powierzchnią, którą widzi aparat.

Renderowanie kanału informacyjnego kamery PV w języku C++

  • Tworzenie nowego aktora języka C++ o nazwie CamCapture
  • W pliku build.cs projektu dodaj element "AugmentedReality" do listy PublicDependencyModuleNames:
PublicDependencyModuleNames.AddRange(
    new string[] {
        "Core",
        "CoreUObject",
        "Engine",
        "InputCore",
        "AugmentedReality"
});
  • W camCapture.h, dołącz ARBlueprintLibrary.h
#include "ARBlueprintLibrary.h"
  • Należy również dodać zmienne lokalne dla siatki i materiału:
private:
    UStaticMesh* StaticMesh;
    UStaticMeshComponent* StaticMeshComponent;
    UMaterialInstanceDynamic* DynamicMaterial;
    bool IsTextureParamSet = false;
  • W pliku CamCapture.cpp zaktualizuj konstruktor, aby dodać siatkę statyczną do sceny:
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);
}

W elemencie BeginPlay utwórz dynamiczne wystąpienie materiału z materiału kamery projektu, zastosuj je do składnika siatki statycznej i uruchom aparat HoloLens.

W edytorze kliknij prawym przyciskiem myszy element CamTextureMaterial w przeglądarce zawartości i wybierz pozycję "Kopiuj odwołanie", aby pobrać ciąg cameraMatPath.

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);
}

W obszarze Tick pobierz teksturę z aparatu, ustaw go na parametr tekstury w materiale CamTextureMaterial i przeskaluj statyczny składnik siatki przez współczynnik proporcji ramki aparatu:

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));
    }
}

Następny punkt kontrolny programowania

Jeśli obserwujesz określoną przez nas podróż deweloperów Unreal, jesteś w środku eksplorowania możliwości platformy Mixed Reality i interfejsów API. W tym miejscu możesz przejść do następnego tematu:

Możesz też przejść bezpośrednio do wdrożenia aplikacji na urządzeniu lub emulatorze:

Zawsze możesz wrócić do nierealnych punktów kontrolnych programowania w dowolnym momencie.

Zobacz też