CameraIntrinsics.UndistortedProjectionTransform Propriété
Définition
Important
Certaines informations portent sur la préversion du produit qui est susceptible d’être en grande partie modifiée avant sa publication. Microsoft exclut toute garantie, expresse ou implicite, concernant les informations fournies ici.
Obtient une matrice qui transforme une coordonnée 2D en mètres sur le plan d’image en coordonnées de pixels image vidéo sans compenser le modèle de distorsion de la caméra. Le point 2D résultant de cette transformation ne sera pas mappé avec précision à la coordonnée de pixel dans une image vidéo, sauf si l’application applique sa propre compensation de distorsion. Cela est utile pour les applications qui choisissent d’implémenter la compensation de distorsion basée sur GPU au lieu d’utiliser UndistortPoint, qui utilise le processeur pour calculer la compensation de distorsion.
public:
property float4x4 UndistortedProjectionTransform { float4x4 get(); };
float4x4 UndistortedProjectionTransform();
public Matrix4x4 UndistortedProjectionTransform { get; }
var matrix4x4 = cameraIntrinsics.undistortedProjectionTransform;
Public ReadOnly Property UndistortedProjectionTransform As Matrix4x4
Valeur de propriété
Obtient une matrice qui transforme une coordonnée 2D en mètres sur le plan d’image en coordonnées de pixels de trame vidéo sans compenser le modèle de distorsion de la caméra.
Configuration requise pour Windows
Famille d’appareils |
Windows 10 Anniversary Edition (introduit dans 10.0.14393.0)
|
API contract |
Windows.Foundation.UniversalApiContract (introduit dans v3.0)
|
Remarques
La transformation effectue la conversion d’une coordonnée 2D en mètres sur le plan de l’image (origine au point principal, +X pointant vers la droite et +Y pointant vers le haut), en coordonnée 2D en pixels avec l’origine en haut à gauche de l’image, et +X pointant vers la droite et +Y pointant vers le bas. Si la coordonnée 2D est exprimée sous la forme d’un vecteur avec quatre composants, Z doit être défini sur 0 et W sur 1.
Pour convertir une coordonnée 3D dans le système de coordonnées de la caméra en coordonnées de pixels, les composants X et Y de la coordonnée doivent d’abord être divisés par la distance de la caméra (c’est-à-dire la coordonnée Z) pour les projeter sur le plan de l’image. Notez que les systèmes de coordonnées de caméra sont des droitiers par convention, avec +X pointant vers la droite, +Y pointant vers le haut et -Z pointant vers le haut de la caméra par le centre (point principal) de l’image. Dans cette convention, la coordonnée Z doit être annulée lors de la division en composants X et Y. Par exemple :
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 };
}
Un résultat équivalent peut être obtenu à l’aide d’un vecteur avec quatre composants en définissant le composant Z sur 1 et le composant W sur la distance de la caméra. Notez que les composants X et Y résultants doivent être divisés par le composant W résultant pour obtenir les coordonnées de pixels finales :
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 };
}
Si cette transformation est appliquée à de nombreuses coordonnées 3D, il peut être plus pratique d’ajuster la matrice elle-même, plutôt que chaque coordonnée d’entrée. Pour ce faire, vous pouvez permuter les troisième et quatrième lignes de la matrice et utiliser une fonction de transformation de coordonnées homogène comme XMVector3TransformCoordStream. Notez qu’une conversion de droitier en gaucher est également appliquée dans le cadre de la transformation afin que la distance par rapport à la caméra soit une valeur positive :
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 }; });
}