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