共用方式為


CameraIntrinsics.UndistortedProjectionTransform 屬性

定義

取得矩陣,此矩陣會將影像平面上公尺的 2D 座標轉換成視訊框架圖元座標,而不會補償相機的失真模型。 除非應用程式套用自己的失真補償,否則此轉換所產生的 2D 點不會精確地對應到視訊畫面中的圖元座標。 這適用于選擇實作 GPU 型失真補償,而不是使用 UndistortPoint的應用程式,它會使用 CPU 來計算失真補償。

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

屬性值

Matrix4x4 Matrix4x4

float4x4

取得矩陣,此矩陣會將影像平面上公尺的 2D 座標轉換成視訊框架圖元座標,而不會補償相機的失真模型。

Windows 需求

裝置系列
Windows 10 Anniversary Edition (已於 10.0.14393.0 引進)
API contract
Windows.Foundation.UniversalApiContract (已於 v3.0 引進)

備註

轉換會從影像平面上以公尺為單位的 2D 座標, (主要點的原點、指向右側和 +Y 指向) 的 2D 座標、以圖元為單位的 2D 座標,以及指向右邊的 +X,以及 +Y 指向右方。 如果 2D 座標以具有四個元件的向量表示,則 Z 必須設定為 0,且 W 必須設定為 1。

若要將相機座標系統中的 3D 座標轉換成圖元座標,座標的 X 和 Y 元件必須先除以相機 (的距離,也就是 Z 座標) 將它們投影到影像平面。 請注意,相機座標系統依慣例是靠右手,+X 指向右、+Y 指向,以及透過影像中央 (主體點) 從相機指向的 -Z。 在該慣例中,在分割為 X 和 Y 元件時,必須否定 Z 座標。 例如:

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

將 Z 元件設定為 1,W 元件與相機距離,即可使用具有四個元件的向量來達成對等的結果。 請注意,產生的 X 和 Y 元件必須除以產生的 W 元件,才能產生最終圖元座標:

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

如果此轉換會套用至許多 3D 座標,則調整矩陣本身,而不是每個輸入座標可能會比較方便。 這可以透過交換矩陣的第三個和第四個數據列,並使用 XMVector3TransformCoordStream等同質座標轉換函式來完成。 請注意,從右手到左手的轉換也會套用為轉換的一部分,讓相機的距離是正值:

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

適用於