CameraIntrinsics.UndistortedProjectionTransform 属性
定义
重要
一些信息与预发行产品相关,相应产品在发行之前可能会进行重大修改。 对于此处提供的信息,Microsoft 不作任何明示或暗示的担保。
获取一个矩阵,该矩阵将图像平面上的 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
属性值
获取一个矩阵,该矩阵将图像平面上的 2D 坐标(以米为单位)转换为视频帧像素坐标,而无需补偿相机的失真模型。
Windows 要求
设备系列 |
Windows 10 Anniversary Edition (在 10.0.14393.0 中引入)
|
API contract |
Windows.Foundation.UniversalApiContract (在 v3.0 中引入)
|
注解
转换从图像平面上以米为单位的 2D 坐标转换为主点 (原点,+X 指向右侧,+Y 指向) ,转换为以像素为单位的 2D 坐标,原点位于图像左上角,+X 指向右侧,+Y 指向下。 如果 2D 坐标表示为具有四个分量的向量,则 Z 必须设置为 0,W 必须设置为 1。
若要将相机坐标系中的 3D 坐标转换为像素坐标,必须先将坐标的 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 };
}
如果此转换将应用于许多 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 }; });
}