HoloLens-foto-/videocamera in Unreal

De HoloLens heeft een foto-/videocamera (PV) op het vizier die kan worden gebruikt voor zowel Mixed Reality Capture (MRC) als het lokaliseren van objecten in de Ruimte van De Wereld van Unreal op basis van pixelcoördinaten in het cameraframe.

Belangrijk

De PV-camera wordt niet ondersteund met Holoographic Remoting, maar het is mogelijk om een webcam te gebruiken die op uw pc is aangesloten om de holoLens PV Camera-functionaliteit te simuleren.

Installatie van PV-camerafeed

Belangrijk

De PV camera is geïmplementeerd in zowel Windows Mixed Reality als OpenXR plugins. OpenXR moet echter wel de Microsoft OpenXR-invoegtoepassing installeren. Ook OpenXR voor Unreal 4.26 heeft een beperking: camera kan werken met DirectX11 RHI. Deze beperking is opgelost in Unreal 4.27.1 of hoger.

  • Schakel in Projectinstellingen > HoloLens de webcamfunctie in:

Schermopname van de HoloLens-projectinstellingen met de eigenschap Webcam gemarkeerd

  • Maak een nieuwe actor met de naam 'CamCapture' en voeg een vliegtuig toe om de camerafeed weer te geven:

Schermopname van een actor met een toegevoegd vlak

  • Voeg de actor toe aan uw scène, maak een nieuw materiaal met de naam CamTextureMaterial met een objectparameter Texture en een patroonvoorbeeld. Verzend de RGB-gegevens van het patroon naar de uitvoer-emissive-kleur:

Blauwdruk van een materiaal- en patroonvoorbeeld

De PV-camerafeed weergeven

  • Schakel in de blauwdruk CamCapture de PV-camera in:

Blauwdruk van de functie ArCapture in-/uitschakelen met de PV-camera ingeschakeld

  • Maak een dynamisch materiaalexemplaar van CamTextureMaterial en wijs dit materiaal toe aan het vlak van de actor:

Blauwdruk van de functie Exemplaar van dynamisch materiaal maken

  • Haal het patroon op uit de camerafeed en wijs deze toe aan het dynamische materiaal als het geldig is. Als het patroon niet geldig is, start u een timer en probeert u het opnieuw na de time-out:

Blauwdruk van de textuur van de camerafeed die is toegewezen aan het dynamische materiaal

  • Schaal ten slotte het vlak op de hoogte-breedteverhouding van de cameraafbeelding:

Blauwdruk van het vliegtuig dat is geschaald ten opzichte van de hoogte-breedteverhouding van camerabeelden

Zoek cameraposities in de wereldruimte

De camera op de HoloLens 2 wordt verticaal verschoven ten opzichte van de hoofdtracering van het apparaat. Er zijn enkele functies om de camera in de wereldruimte te vinden om rekening te houden met de verschuiving.

GetPVCameraToWorldTransform krijgt de transformatie in de wereldruimte van de PV Camera en wordt op de cameralens gepositioneerd:

Blauwdruk van de functie Get PVCamera to World Transform

GetWorldSpaceRayFromCameraPoint werpt een straal van de cameralens in de scène in de ruimte van de Wereld van Unreal om de inhoud van een pixel in het cameraframe te vinden:

Blauwdruk van de Get World Space Ray van Camera Point

GetPVCameraIntrinsics retourneert de intrinsieke waarden van de camera, die kunnen worden gebruikt bij het verwerken van Computer Vision op een cameraframe:

Blauwdruk van intrinsieke functies van PVCamera ophalen

Als u wilt vinden wat er in de wereldruimte op een bepaalde pixelcoördinaat bestaat, gebruikt u een lijntracering met de wereldruimtestraal:

Blauwdruk van de wereldruimtestraal die wordt gebruikt om te ontdekken wat er in de wereldruimte op een bepaalde coördinaat bestaat

Hier casten we een 2-meter straal van de cameralens naar de cameraruimtepositie 1/4 vanaf de linkerbovenhoek van het frame. Gebruik vervolgens het resultaat van de hit om iets weer te geven waar het object zich in de wereldruimte bevindt:

Blauwdruk van een straal van 2 meter van de cameralens naar de positie van de cameraruimte 1/4 vanaf de linkerbovenhoek van het frame

Wanneer u ruimtelijke toewijzing gebruikt, komt deze positie overeen met het oppervlak dat de camera ziet.

De PV-camerafeed weergeven in C++

  • Een nieuwe C++-actor maken met de naam CamCapture
  • Voeg in de build.cs van het project AugmentedReality toe aan de lijst PublicDependencyModuleNames:
PublicDependencyModuleNames.AddRange(
    new string[] {
        "Core",
        "CoreUObject",
        "Engine",
        "InputCore",
        "AugmentedReality"
});
  • Neem in CamCapture.h ARBlueprintLibrary.h op
#include "ARBlueprintLibrary.h"
  • U moet ook lokale variabelen toevoegen voor de mesh en het materiaal:
private:
    UStaticMesh* StaticMesh;
    UStaticMeshComponent* StaticMeshComponent;
    UMaterialInstanceDynamic* DynamicMaterial;
    bool IsTextureParamSet = false;
  • Werk in CamCapture.cpp de constructor bij om een statische mesh toe te voegen aan de scène:
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);
}

Maak in BeginPlay een dynamisch materiaalexemplaar van het cameramateriaal van het project, pas dit toe op het statische mesh-onderdeel en start de HoloLens-camera.

Klik in de editor met de rechtermuisknop op CamTextureMaterial in de inhoudsbrowser en selecteer Naslag kopiëren om de tekenreeks voor CameraMatPath op te halen.

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

Stel in Tick get the texture from the camera in op the texture parameter in the CamTextureMaterial material, and scale the static mesh component by the aspect ratio the camera frame's:

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

Volgend controlepunt voor ontwikkeling

Als u het Unreal-ontwikkelingstraject volgt dat we hebben opgesteld, bent u bezig met het verkennen van de Mixed Reality platformmogelijkheden en API's. Vanaf hier kunt u doorgaan naar het volgende onderwerp:

Of ga rechtstreeks naar het implementeren van uw app op een apparaat of emulator:

U kunt altijd op elk gewenst moment teruggaan naar de Controlepunten voor Unreal-ontwikkeling .

Zie ook