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 座標, (主要點的原點、指向右側和 +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 }; });
}