Compartir a través de


Cámara de fotos y vídeo de HoloLens en Unreal

HoloLens tiene una cámara foto/vídeo (PV) en el visor que se puede usar tanto para Mixed Reality Capture (MRC) como para localizar objetos en el espacio unreal world a partir de coordenadas de píxeles en el marco de la cámara.

Importante

La cámara PV no es compatible con la comunicación remota holográfica, pero es posible usar una cámara web conectada a su PC para simular la funcionalidad de la cámara PV de HoloLens.

Configuración de la fuente de la cámara PV

Importante

La cámara fotovoltaica se implementa en complementos Windows Mixed Reality y OpenXR. Sin embargo, OpenXR necesita que se instale el complemento Microsoft OpenXR . Además, OpenXR para Unreal 4.26 tiene una limitación: la cámara puede trabajar con DirectX11 RHI. Esta limitación se corrige en Unreal 4.27.1 o posterior.

  • En Configuración del > proyecto HoloLens, habilite la funcionalidad Webcam :

Captura de pantalla de la configuración del proyecto de HoloLens con la propiedad Webcam resaltada

  • Cree un actor llamado "CamCapture" y agregue un plano para representar la fuente de la cámara:

Captura de pantalla de un actor con un plano agregado

  • Agregue el actor a la escena, cree un nuevo material denominado CamTextureMaterial con un parámetro de objeto texture y una muestra de textura. Envíe los datos rgb de la textura al color emisivo de salida:

Plano técnico de un material y una muestra de textura

Representación de la fuente de cámara PV

  • En el plano técnico de CamCapture, active la cámara PV:

Plano técnico de la función Toggle ARCapture con la cámara PV activada

  • Cree una instancia de material dinámico a partir de CamTextureMaterial y asigne este material al plano del actor:

Plano técnico de la función Crear instancia dinámica de material

  • Obtenga la textura de la fuente de la cámara y asígnela al material dinámico si es válida. Si la textura no es válida, inicie un temporizador e inténtelo de nuevo después del tiempo de espera:

Plano técnico de la textura de alimentación de cámara asignada al material dinámico

  • Por último, escale el plano según la relación de aspecto de la imagen de la cámara:

Plano técnico del plano escalado en relación con la relación de aspecto de las imágenes de cámara

Buscar posiciones de cámara en el espacio mundial

La cámara del HoloLens 2 se desplaza verticalmente desde el seguimiento de la cabeza del dispositivo. Existen algunas funciones para localizar la cámara en el espacio del mundo para tener en cuenta el desplazamiento.

GetPVCameraToWorldTransform obtiene la transformación en el espacio mundial de la cámara fotovoltaica y se colocará en la lente de la cámara:

Plano técnico de la función Get PVCamera to World Transform

GetWorldSpaceRayFromCameraPoint convierte un rayo de la lente de la cámara en la escena en el espacio unreal world para encontrar el contenido de un píxel en el marco de la cámara:

Plano técnico de la obtención del rayo espacial del mundo desde el punto de la cámara

GetPVCameraIntrinsics devuelve los valores intrínsecos de la cámara, que se pueden usar al realizar el procesamiento de computer vision en un marco de cámara:

Plano técnico de obtener funciones intrínsecas de PVCamera

Para encontrar lo que existe en el espacio mundial en una coordenada de píxel determinada, use un seguimiento de línea con el rayo espacial del mundo:

Plano técnico del rayo espacial del mundo que se usa para averiguar lo que existe en el espacio mundial en una coordenada determinada

Aquí lanzamos un rayo de 2 metros desde la lente de la cámara a la posición del espacio de la cámara 1/4 desde la parte superior izquierda del marco. A continuación, use el resultado de aciertos para representar algo donde el objeto existe en el espacio mundial:

Plano técnico de una transmisión de rayos de 2 metros desde la lente de la cámara a la posición del espacio de la cámara 1/4 desde la parte superior izquierda del marco

Cuando se usa la asignación espacial, esta posición de posicionamiento coincidirá con la superficie que ve la cámara.

Representación de la fuente de cámara PV en C++

  • Creación de un nuevo actor de C++ llamado CamCapture
  • En el build.cs del proyecto, agregue "AugmentedReality" a la lista PublicDependencyModuleNames:
PublicDependencyModuleNames.AddRange(
    new string[] {
        "Core",
        "CoreUObject",
        "Engine",
        "InputCore",
        "AugmentedReality"
});
  • En CamCapture.h, incluya ARBlueprintLibrary.h.
#include "ARBlueprintLibrary.h"
  • También debe agregar variables locales para la malla y el material:
private:
    UStaticMesh* StaticMesh;
    UStaticMeshComponent* StaticMeshComponent;
    UMaterialInstanceDynamic* DynamicMaterial;
    bool IsTextureParamSet = false;
  • En CamCapture.cpp, actualice el constructor para agregar una malla estática a la escena:
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);
}

En BeginPlay, cree una instancia de material dinámico a partir del material de cámara del proyecto, aplíquela al componente de malla estática e inicie la cámara HoloLens.

En el editor, haga clic con el botón derecho en CamTextureMaterial en el explorador de contenido y seleccione "Copiar referencia" para obtener la cadena de 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);
}

En Tick, obtenga la textura de la cámara, establézcala en el parámetro texture del material CamTextureMaterial y escale el componente de malla estática por la relación de aspecto del marco de la cámara:

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

Siguiente punto de comprobación de desarrollo

Si sigue el recorrido de desarrollo de Unreal que hemos diseñado, se encuentra en medio de la exploración de las funcionalidades y las API de la plataforma de Mixed Reality. Desde aquí, puede continuar con el tema siguiente:

O vaya directamente a la implementación de la aplicación en un dispositivo o emulador:

Siempre puede volver a los puntos de control de desarrollo de Unreal en cualquier momento.

Vea también