Unreal'da HoloLens Fotoğraf/Video Kamera

HoloLens'in vizörde hem Karma Gerçeklik Yakalama (MRC) hem de gerçek olmayan dünya uzayında nesneleri kamera çerçevesindeki piksel koordinatlarından bulmak için kullanılabilecek bir Fotoğraf/Video (PV) Kamera bulunur.

Önemli

PV Kamera Holographic Remoting ile desteklenmez, ancak HoloLens PV Kamera işlevini simüle etmek için bilgisayarınıza bağlı bir web kamerası kullanmak mümkündür.

PV Kamera Akışı Kurulumu

Önemli

PV kamera hem Windows Mixed Reality hem de OpenXR eklentilerinde uygulanır. Ancak OpenXR için Microsoft OpenXR eklentisinin yüklü olması gerekir. Ayrıca, Unreal 4.26 için OpenXR'nin bir sınırlaması vardır: kamera DirectX11 RHI ile çalışabilir. Bu sınırlama, Unreal 4.27.1 veya sonraki sürümlerde düzeltilmiştir.

  • Proje Ayarları > HoloLens'teWeb Kamerası özelliğini etkinleştirin:

Web Kamerası özelliğinin vurgulandığı HoloLens proje ayarlarının ekran görüntüsü

  • "CamCapture" adlı yeni bir aktör oluşturun ve kamera akışını işlemek için bir düzlem ekleyin:

Eklenen düzleme sahip bir aktörün ekran görüntüsü

  • Aktörü sahnenize ekleyin, Doku Nesnesi Parametresi ile CamTextureMaterial adlı yeni bir malzeme ve doku örneği oluşturun. Doku rgb verilerini çıkış izinli renge gönderin:

Malzeme ve doku örneğinin şeması

PV Kamera Akışını İşleme

  • CamCapture şemasında PV Kamera'yı açın:

PV Kamera açık durumdayken ARCapture işlevini aç/kapat işlevinin şeması

  • CamTextureMaterial'dan dinamik bir malzeme örneği oluşturun ve bu malzemeyi aktörün düzlemine atayın:

Dinamik Malzeme Örneği Oluştur işlevinin şeması

  • Kamera akışından dokuyu alın ve geçerliyse dinamik malzemeye atayın. Doku geçerli değilse bir zamanlayıcı başlatın ve zaman aşımından sonra yeniden deneyin:

Dinamik malzemeye atanan kamera besleme dokusunun şeması

  • Son olarak, düzlemi kamera görüntüsünün en boy oranına göre ölçeklendirin:

Kamera görüntüleri en boy oranına göre ölçeklendirilmiş düzlem şeması

World Space'te Kamera Konumlarını Bulma

HoloLens 2 kamera, cihazın baş izlemesinden dikey olarak uzaklıktadır. Uzaklığı hesaba eklemek için dünya uzayında kamerayı bulmak için birkaç işlev vardır.

GetPVCameraToWorldTransform, PV Kamera'nın dünya uzayında dönüşümü alır ve kamera merceğine konumlandırılır:

Get PVCamera to World Transform işlevinin şeması

GetWorldSpaceRayFromCameraPoint, kamera çerçevesinde bir pikselin içeriğini bulmak için gerçek olmayan dünya alanında kamera merceğinden bir ışın yayınlar:

Kamera Noktasından Dünya Uzay ışını Alma Şeması

GetPVCameraIntrinsics, kamera çerçevesinde görüntü işleme yaparken kullanılabilecek kamera iç değerlerini döndürür:

GET PVCamera İç işlevlerinin şeması

Belirli bir piksel koordinatında dünya uzayında nelerin var olduğunu bulmak için dünya uzay ışını ile bir çizgi izleme kullanın:

Belirli bir koordinatta dünya uzayında nelerin var olduğunu bulmak için kullanılan dünya uzay ışınının şeması

Burada kamera lensinden çerçevenin sol üst kısmından 1/4 kamera alanı konumuna 2 metrelik bir ışın atıyoruz. Ardından, nesnenin dünya alanında bulunduğu bir şeyi işlemek için isabet sonucunu kullanın:

Kamera lensinden çerçevenin sol üst kısmından 1/4 kamera alanı konumuna 2 metrelik bir ışın dökümünün şeması

Uzamsal haritalama kullanılırken, bu isabet konumu kameranın gördüğü yüzeyle eşleşecektir.

C++ dilinde PV Kamera Akışını İşleme

  • CamCapture adlı yeni bir C++ aktörü oluşturma
  • Projenin build.cs dosyasına PublicDependencyModuleNames listesine "AugmentedReality" ekleyin:
PublicDependencyModuleNames.AddRange(
    new string[] {
        "Core",
        "CoreUObject",
        "Engine",
        "InputCore",
        "AugmentedReality"
});
  • CamCapture.h içinde ARBlueprintLibrary.h dosyasını ekleyin
#include "ARBlueprintLibrary.h"
  • Ağ ve malzeme için yerel değişkenler de eklemeniz gerekir:
private:
    UStaticMesh* StaticMesh;
    UStaticMeshComponent* StaticMeshComponent;
    UMaterialInstanceDynamic* DynamicMaterial;
    bool IsTextureParamSet = false;
  • CamCapture.cpp dosyasında oluşturucuyu güncelleştirerek sahneye statik bir ağ ekleyin:
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);
}

BeginPlay'de projenin kamera malzemesinden dinamik bir malzeme örneği oluşturun, bunu statik ağ bileşenine uygulayın ve HoloLens kamerasını başlatın.

Düzenleyicide, içerik tarayıcısında CamTextureMaterial öğesine sağ tıklayın ve CameraMatPath dizesini almak için "Başvuruyu Kopyala"yı seçin.

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

Tick'de dokuyu kameradan alın, CamTextureMaterial malzemedeki doku parametresine ayarlayın ve statik ağ bileşenini kamera çerçevesinin en boy oranına göre ölçeklendirin:

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

Sonraki Geliştirme Denetim Noktası

Ortaya koyduğumuz Gerçek olmayan geliştirme yolculuğunu takip ediyorsanız, Karma Gerçeklik platformu özelliklerini ve API'lerini keşfetmenin tam ortasındasınız demektir. Buradan bir sonraki konuya devam edebilirsiniz:

Veya doğrudan uygulamanızı bir cihaza veya öykünücüye dağıtmaya atlayın:

İstediğiniz zaman Gerçekleşmemiş geliştirme denetim noktalarına geri dönebilirsiniz.

Ayrıca bkz.