CameraIntrinsics.UndistortedProjectionTransform Свойство

Определение

Возвращает матрицу, которая преобразует двухмерную координату в метрах на плоскости изображения в пиксельные координаты видеокадра без компенсации модели искажений камеры. Двухd-точка, полученная в результате этого преобразования, не будет точно сопоставляться с пиксельной координатой в видеокадре, если приложение не применяет собственную компенсацию искажений. Это полезно для приложений, которые решили реализовать компенсацию искажений на основе GPU вместо UndistortPoint, которая использует ЦП для вычисления компенсации искажений.

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

Получает матрицу, которая преобразует двухмерную координату в метрах на плоскости изображения в пиксельные координаты видеокадра без компенсации модели искажений камеры.

Требования к Windows

Семейство устройств
Windows 10 Anniversary Edition (появилось в 10.0.14393.0)
API contract
Windows.Foundation.UniversalApiContract (появилось в v3.0)

Комментарии

Преобразование преобразует двухдиаметровую координату в метрах на плоскости изображения (начало в основной точке, +X — вправо и +Y — вверх) в двухd-координату в пикселях с источником в левом верхнем углу изображения, +X — вправо и +Y — вниз. Если двухсторонная координата выражена в виде вектора с четырьмя компонентами, для Z необходимо задать значение 0, а для W — значение 1.

Чтобы преобразовать трехмерную координату в системе координат камеры в пиксельные координаты, компоненты координат X и Y необходимо сначала разделить на расстояние от камеры (т. е. координаты Z), чтобы проецировать их на плоскость изображения. Обратите внимание, что системы координат камеры являются правосторонними по соглашению: +X указывает вправо, +Y — вверх, а -Z — через центр (основную точку) изображения. В этом соглашении координата Z должна быть отрицаема при делении на компоненты X и Y. Пример:

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

Если это преобразование будет применено ко многим трехмерных координатам, может быть удобнее настроить саму матрицу, а не каждую входную координату. Это можно сделать, заменив третью и четвертую строки матрицы и используя однородную функцию преобразования координат, например 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 }; });
}

Применяется к