Freigeben über


CameraIntrinsics.UndistortedProjectionTransform Eigenschaft

Definition

Ruft eine Matrix ab, die eine 2D-Koordinate in Meter auf der Bildebene in Videoframepixelkoordinaten transformiert, ohne das Verzerrungsmodell der Kamera zu kompensieren. Der 2D-Punkt, der sich aus dieser Transformation ergibt, wird der Pixelkoordinate in einem Videoframe nicht genau zugeordnet, es sei denn, die App wendet eine eigene Verzerrungskompensation an. Dies ist nützlich für Apps, die gpubasierte Verzerrungskompensation anstelle von UndistortPoint implementieren, bei dem die CPU zum Berechnen der Verzerrungskompensation verwendet wird.

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

Eigenschaftswert

Matrix4x4 Matrix4x4

float4x4

Ruft eine Matrix ab, die eine 2D-Koordinate in Meter auf der Bildebene in die Pixelkoordinaten des Videoframes transformiert, ohne das Verzerrungsmodell der Kamera zu kompensieren.

Windows-Anforderungen

Gerätefamilie
Windows 10 Anniversary Edition (eingeführt in 10.0.14393.0)
API contract
Windows.Foundation.UniversalApiContract (eingeführt in v3.0)

Hinweise

Die Transformation konvertiert von einer 2D-Koordinate in Metern auf der Bildebene (Ursprung am Prinzipalpunkt, +X zeigt nach rechts und +Y nach oben), in eine 2D-Koordinate in Pixeln mit dem Ursprung in der oberen linken Ecke des Bilds und +X, das nach rechts zeigt, und +Y nach unten. Wenn die 2D-Koordinate als Vektor mit vier Komponenten ausgedrückt wird, muss Z auf 0 und W auf 1 festgelegt werden.

Um eine 3D-Koordinate im Koordinatensystem der Kamera in Pixelkoordinaten zu konvertieren, müssen die X- und Y-Komponenten der Koordinate zuerst durch den Abstand zur Kamera (d. h. die Z-Koordinate) geteilt werden, um sie auf die Bildebene zu projizieren. Beachten Sie, dass Kamerakoordinatensysteme nach der Konvention rechtshändig sind, wobei +X nach rechts zeigt, +Y nach oben zeigt und -Z von der Kamera durch die Mitte (Prinzipalpunkt) des Bilds zeigt. In dieser Konvention muss die Z-Koordinate negiert werden, wenn sie in die X- und Y-Komponenten unterteilt wird. Beispiel:

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

Ein entsprechendes Ergebnis kann mit einem Vektor mit vier Komponenten erreicht werden, indem die Z-Komponente auf 1 und die W-Komponente auf den Abstand zur Kamera festgelegt wird. Beachten Sie, dass die resultierenden X- und Y-Komponenten durch die resultierende W-Komponente geteilt werden müssen, um die endgültigen Pixelkoordinaten zu erhalten:

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

Wenn diese Transformation auf viele 3D-Koordinaten angewendet wird, ist es möglicherweise bequemer, die Matrix selbst anzupassen, anstatt jede Eingabekoordinate. Dies kann erreicht werden, indem die dritte und vierte Zeile der Matrix ausgetauscht wird und eine homogene Koordinatentransformationsfunktion wie XMVector3TransformCoordStream verwendet wird. Beachten Sie, dass eine Konvertierung von rechts nach links auch als Teil der Transformation angewendet wird, sodass der Abstand von der Kamera positiv ist:

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

Gilt für: