Condividi tramite


CameraIntrinsics.UndistortedProjectionTransform Proprietà

Definizione

Ottiene una matrice che trasforma una coordinata 2D in metri sul piano dell'immagine in coordinate pixel dei fotogrammi video senza compensare il modello di distorsione della fotocamera. Il punto 2D risultante da questa trasformazione non verrà mappato in modo accurato alla coordinata pixel in un fotogramma video, a meno che l'app non applichi la propria compensazione di distorsione. Ciò è utile per le app che scelgono di implementare la compensazione della distorsione basata su GPU invece di usare UndistortPoint, che usa la CPU per calcolare la compensazione della distorsione.

public:
 property float4x4 UndistortedProjectionTransform { float4x4 get(); };
float4x4 UndistortedProjectionTransform();
public Matrix4x4 UndistortedProjectionTransform { get; }
var matrix4x4 = cameraIntrinsics.undistortedProjectionTransform;
Public ReadOnly Property UndistortedProjectionTransform As Matrix4x4

Valore della proprietà

Matrix4x4 Matrix4x4

float4x4

Ottiene una matrice che trasforma una coordinata 2D in metri sul piano dell'immagine alle coordinate pixel dei fotogrammi video senza compensare il modello di distorsione della fotocamera.

Requisiti Windows

Famiglia di dispositivi
Windows 10 Anniversary Edition (è stato introdotto in 10.0.14393.0)
API contract
Windows.Foundation.UniversalApiContract (è stato introdotto in v3.0)

Commenti

La trasformazione converte da una coordinata 2D in metri sul piano immagine (origine nel punto principale, +X che punta a destra e +Y puntando verso l'alto), a una coordinata 2D in pixel con l'origine nell'angolo superiore sinistro dell'immagine e +X che punta a destra e +Y puntando verso il basso. Se la coordinata 2D è espressa come vettore con quattro componenti, Z deve essere impostata su 0 e W deve essere impostata su 1.

Per convertire una coordinata 3D nel sistema di coordinate della fotocamera in coordinate pixel, i componenti X e Y della coordinata devono prima essere divisi per la distanza dalla fotocamera (ovvero la coordinata Z) per proiettarli sul piano immagine. Si noti che i sistemi di coordinate della fotocamera sono a destra per convenzione, con +X puntando a destra, +Y puntando su e -Z puntando dalla fotocamera attraverso il centro (punto principale) dell'immagine. In tale convenzione, la coordinata Z deve essere negata durante la divisione nei componenti X e Y. Ad esempio:

using namespace winrt::Windows::Foundation::Numerics;
winrt::Windows::Foundation::Point ProjectCameraCoordinateToPixelCoordinate(
    const winrt::Windows::Media::Devices::Core::CameraIntrinsics& cameraIntrinsics,
    const float3& cameraCoordinate)
{
    const float2 imagePlaneCoordinate = float2{ cameraCoordinate.x / -cameraCoordinate.z, cameraCoordinate.y / -cameraCoordinate.z };
    float2 pixelCoordinate = transform(imagePlaneCoordinate, cameraIntrinsics.UndistortedProjectionTransform());
    return winrt::Windows::Foundation::Point{ pixelCoordinate.x, pixelCoordinate.y };
}

Un risultato equivalente può essere ottenuto usando un vettore con quattro componenti impostando il componente Z su 1 e il componente W sulla distanza dalla fotocamera. Si noti che i componenti X e Y risultanti devono essere divisi per il componente W risultante per produrre le coordinate pixel finali:

using namespace winrt::Windows::Foundation::Numerics;
winrt::Windows::Foundation::Point ProjectCameraCoordinateToPixelCoordinate(
    const winrt::Windows::Media::Devices::Core::CameraIntrinsics& cameraIntrinsics,
    const float3& cameraCoordinate)
{
    float4 cameraCoordinateVector{ cameraCoordinate.x, cameraCoordinate.y, 1, -cameraCoordinate.z };
    float4 pixelCoordinate = transform(cameraCoordinateVector, cameraIntrinsics.UndistortedProjectionTransform());
    return winrt::Windows::Foundation::Point{ pixelCoordinate.x / pixelCoordinate.w, pixelCoordinate.y / pixelCoordinate.w };
}

Se questa trasformazione verrà applicata a molte coordinate 3D, potrebbe essere più utile regolare la matrice stessa, anziché ogni coordinata di input. Questa operazione può essere eseguita scambiando le terze e quarta righe della matrice e usando una funzione di trasformazione delle coordinate omogenea come XMVector3TransformCoordStream. Si noti che una conversione da destra a sinistra viene applicata anche come parte della trasformazione in modo che la distanza dalla fotocamera sia un valore positivo:

using namespace DirectX;
void ProjectCameraCoordinatesToPixelCoordinates(
    const winrt::Windows::Media::Devices::Core::CameraIntrinsics& cameraIntrinsics,
    const winrt::array_view<XMFLOAT3>& cameraCoordinates,
    winrt::array_view<winrt::Windows::Foundation::Point>& pixelCoordinates)
{
    XMMATRIX undistortedProjectionTransform = XMLoadFloat4x4(&cameraIntrinsics.UndistortedProjectionTransform());
    std::swap(undistortedProjectionTransform.r[2], undistortedProjectionTransform.r[3]);

    // convert right-handed coordinates (-Z forward) to right-handed coordinates (+Z forward) as part of the transform
    static const XMMATRIX rightToLeft = XMMatrixScaling(1, 1, -1);

    std::vector<XMFLOAT3> pixelCoordinateVectors(cameraCoordinates.size());
    XMVector3TransformCoordStream(
        pixelCoordinateVectors.data(), sizeof(pixelCoordinateVectors[0]),
        cameraCoordinates.data(), sizeof(cameraCoordinates[0]), cameraCoordinates.size(),
        rightToLeft * undistortedProjectionTransform);

    std::transform(pixelCoordinateVectors.begin(), pixelCoordinateVectors.end(), pixelCoordinates.begin(),
        [](const XMFLOAT3& v) { return winrt::Windows::Foundation::Point{ v.x, v.y }; });
}

Si applica a