次の方法で共有


CameraIntrinsics.UndistortedProjectionTransform プロパティ

定義

カメラの歪みモデルを補正せずに、イメージ プレーン上の 2D 座標をメートル単位でビデオ フレームピクセル座標に変換するマトリックスを取得します。 この変換によって得られる 2D ポイントは、アプリが独自の歪み補正を適用しない限り、ビデオ フレーム内のピクセル座標に正確にマップされません。 これは、CPU を使用して歪み補正を計算する UndistortPoint を使用する代わりに GPU ベースの歪み補正を実装するアプリに役立ちます。

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、+Y を指す) から、画像の左上隅に原点を持つピクセル単位の 2D 座標に変換し、+X は右を指し、+Y は下を指します。 2D 座標が 4 つの成分を持つベクトルとして表される場合、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 成分をカメラからの距離に設定することで、4 つのコンポーネントを持つベクトルを使用して同等の結果を得ることができます。 最終的なピクセル座標を生成するには、結果の 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 座標に適用される場合は、各入力座標ではなく、マトリックス自体を調整する方が便利な場合があります。 これを実現するには、行列の 3 行目と 4 行目を入れ替え、 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 }; });
}

適用対象