Wes xx mediapipe integration

This commit is contained in:
Jelle De Geest
2023-03-12 20:34:16 +00:00
parent 8349b5f149
commit b11eeb465c
975 changed files with 192230 additions and 0 deletions

View File

@@ -0,0 +1,303 @@
// Copyright (c) 2021 homuler
//
// Use of this source code is governed by an MIT-style
// license that can be found in the LICENSE file or at
// https://opensource.org/licenses/MIT.
using UnityEngine;
namespace Mediapipe.Unity.CoordinateSystem
{
/// <summary>
/// This class provides helper methods for converting camera coordinate values to local coordinate values in Unity.
/// See <see cref="https://google.github.io/mediapipe/solutions/objectron.html#coordinate-systems" /> for more details.
/// </summary>
/// <remarks>
/// Assume that the origin is common to the two coordinate systems.
/// </remarks>
public static class CameraCoordinate
{
public static Vector3 CameraToRealWorld(float x, float y, float z, RotationAngle imageRotation = RotationAngle.Rotation0, bool isMirrored = false)
{
var isInverted = IsInverted(imageRotation);
var (rx, ry) = isInverted ? (y, x) : (x, y);
return new Vector3(IsXReversed(imageRotation, isMirrored) ? -rx : rx, IsYReversed(imageRotation, isMirrored) ? -ry : ry, -z);
}
/// <summary>
/// Convert from camera coordinates to local coordinates in Unity.
/// </summary>
/// <param name="x">X in camera coordinates</param>
/// <param name="y">Y in camera coordinates</param>
/// <param name="z">Z in camera coordinates</param>
/// <param name="xMin">The minimum X coordinate of the target rectangle</param>
/// <param name="xMax">The maximum X coordinate of the target rectangle</param>
/// <param name="yMin">The minimum X coordinate of the target rectangle</param>
/// <param name="yMax">The maximum X coordinate of the target rectangle</param>
/// <param name="focalLengthX">Normalized focal length X in NDC space</param>
/// <param name="focalLengthY">Normalized focal length Y in NDC space</param>
/// <param name="principalX">Normalized principal point X in NDC space</param>
/// <param name="principalY">Normalized principal point Y in NDC space</param>
/// <param name="zScale">Ratio of Z values in camera coordinates to local coordinates in Unity</param>
/// <param name="imageRotation">
/// Counterclockwise rotation angle of the input image in the image coordinate system.
/// In the local coordinate system, this value will often represent a clockwise rotation angle.
/// </param>
/// <param name="isMirrored">Set to true if the original coordinates is mirrored</param>
public static Vector3 CameraToLocalPoint(float x, float y, float z, float xMin, float xMax, float yMin, float yMax,
float focalLengthX, float focalLengthY, float principalX, float principalY,
float zScale, RotationAngle imageRotation = RotationAngle.Rotation0, bool isMirrored = false)
{
var (ndcX, ndcY) = ((-focalLengthX * x / z) + principalX, (focalLengthY * y / z) + principalY);
var (width, height) = (xMax - xMin, yMax - yMin);
var (nx, ny) = ((1 + ndcX) / 2.0f, (1 - ndcY) / 2.0f);
var (rectX, rectY) = IsInverted(imageRotation) ? (ny * width, nx * height) : (nx * width, ny * height);
var localX = (IsXReversed(imageRotation, isMirrored) ? width - rectX : rectX) + xMin;
var localY = (IsYReversed(imageRotation, isMirrored) ? height - rectY : rectY) + yMin;
// Reverse the sign of Z because camera coordinate system is right-handed
var localZ = -z * zScale;
return new Vector3(localX, localY, localZ);
}
/// <summary>
/// Convert from camera coordinates to local coordinates in Unity.
/// </summary>
/// <param name="x">X in camera coordinates</param>
/// <param name="y">Y in camera coordinates</param>
/// <param name="z">Z in camera coordinates</param>
/// <param name="xMin">The minimum X coordinate of the target rectangle</param>
/// <param name="xMax">The maximum X coordinate of the target rectangle</param>
/// <param name="yMin">The minimum X coordinate of the target rectangle</param>
/// <param name="yMax">The maximum X coordinate of the target rectangle</param>
/// <param name="focalLength">Normalized focal lengths in NDC space</param>
/// <param name="principalPoint">Normalized principal point in NDC space</param>
/// <param name="zScale">Ratio of Z values in camera coordinates to local coordinates in Unity</param>
/// <param name="imageRotation">
/// Counterclockwise rotation angle of the input image in the image coordinate system.
/// In the local coordinate system, this value will often represent a clockwise rotation angle.
/// </param>
/// <param name="isMirrored">Set to true if the original coordinates is mirrored</param>
public static Vector3 CameraToLocalPoint(float x, float y, float z, float xMin, float xMax, float yMin, float yMax, Vector2 focalLength, Vector2 principalPoint,
float zScale, RotationAngle imageRotation = RotationAngle.Rotation0, bool isMirrored = false)
{
return CameraToLocalPoint(x, y, z, xMin, xMax, yMin, yMax, focalLength.x, focalLength.y, principalPoint.x, principalPoint.y, zScale, imageRotation, isMirrored);
}
/// <summary>
/// Convert from camera coordinates to local coordinates in Unity.
/// </summary>
/// <param name="rectangle">Rectangle to get a point inside</param>
/// <param name="x">X in camera coordinates</param>
/// <param name="y">Y in camera coordinates</param>
/// <param name="z">Z in camera coordinates</param>
/// <param name="focalLengthX">Normalized focal length X in NDC space</param>
/// <param name="focalLengthY">Normalized focal length Y in NDC space</param>
/// <param name="principalX">Normalized principal point X in NDC space</param>
/// <param name="principalY">Normalized principal point Y in NDC space</param>
/// <param name="zScale">Ratio of Z values in camera coordinates to local coordinates in Unity</param>
/// <param name="imageRotation">
/// Counterclockwise rotation angle of the input image in the image coordinate system.
/// In the local coordinate system, this value will often represent a clockwise rotation angle.
/// </param>
/// <param name="isMirrored">Set to true if the original coordinates is mirrored</param>
public static Vector3 CameraToPoint(UnityEngine.Rect rectangle, float x, float y, float z,
float focalLengthX, float focalLengthY, float principalX, float principalY,
float zScale, RotationAngle imageRotation = RotationAngle.Rotation0, bool isMirrored = false)
{
return CameraToLocalPoint(x, y, z, rectangle.xMin, rectangle.xMax, rectangle.yMin, rectangle.yMax, focalLengthX, focalLengthY, principalX, principalY,
zScale, imageRotation, isMirrored);
}
/// <summary>
/// Convert from camera coordinates to local coordinates in Unity.
/// </summary>
/// <param name="rectangle">Rectangle to get a point inside</param>
/// <param name="x">X in camera coordinates</param>
/// <param name="y">Y in camera coordinates</param>
/// <param name="z">Z in camera coordinates</param>
/// <param name="focalLength">Normalized focal lengths in NDC space</param>
/// <param name="principalPoint">Normalized principal point in NDC space</param>
/// <param name="zScale">Ratio of Z values in camera coordinates to local coordinates in Unity</param>
/// <param name="imageRotation">
/// Counterclockwise rotation angle of the input image in the image coordinate system.
/// In the local coordinate system, this value will often represent a clockwise rotation angle.
/// </param>
/// <param name="isMirrored">Set to true if the original coordinates is mirrored</param>
public static Vector3 CameraToPoint(UnityEngine.Rect rectangle, float x, float y, float z,
Vector2 focalLength, Vector2 principalPoint,
float zScale, RotationAngle imageRotation = RotationAngle.Rotation0, bool isMirrored = false)
{
return CameraToLocalPoint(x, y, z, rectangle.xMin, rectangle.xMax, rectangle.yMin, rectangle.yMax, focalLength.x, focalLength.y, principalPoint.x, principalPoint.y,
zScale, imageRotation, isMirrored);
}
/// <summary>
/// Convert from camera coordinates to local coordinates in Unity.
/// It is assumed that the principal point is (0, 0) in the camera coordinate system and the focal length is (1, 1).
/// </summary>
/// <param name="rectangle">Rectangle to get a point inside</param>
/// <param name="x">X in camera coordinates</param>
/// <param name="y">Y in camera coordinates</param>
/// <param name="z">Z in camera coordinates</param>
/// <param name="zScale">Ratio of Z values in camera coordinates to local coordinates in Unity</param>
/// <param name="imageRotation">
/// Counterclockwise rotation angle of the input image in the image coordinate system.
/// In the local coordinate system, this value will often represent a clockwise rotation angle.
/// </param>
/// <param name="isMirrored">Set to true if the original coordinates is mirrored</param>
public static Vector3 CameraToPoint(UnityEngine.Rect rectangle, float x, float y, float z,
float zScale, RotationAngle imageRotation = RotationAngle.Rotation0, bool isMirrored = false)
{
return CameraToLocalPoint(x, y, z, rectangle.xMin, rectangle.xMax, rectangle.yMin, rectangle.yMax, Vector2.one, Vector2.zero, zScale, imageRotation, isMirrored);
}
/// <summary>
/// Get the coordinates represented by <paramref name="point3d" /> in local coordinate system.
/// </summary>
/// <param name="rectangle">Rectangle to get a point inside</param>
/// <param name="focalLengthX">Normalized focal length X in NDC space</param>
/// <param name="focalLengthY">Normalized focal length Y in NDC space</param>
/// <param name="principalX">Normalized principal point X in NDC space</param>
/// <param name="principalY">Normalized principal point Y in NDC space</param>
/// <param name="zScale">Ratio of values in camera coordinates to local coordinates in Unity</param>
/// <param name="imageRotation">
/// Counterclockwise rotation angle of the input image in the image coordinate system.
/// In the local coordinate system, this value will often represent a clockwise rotation angle.
/// </param>
/// <param name="isMirrored">Set to true if the original coordinates is mirrored</param>
public static Vector3 GetPoint(this UnityEngine.Rect rectangle, Point3D point3d, float focalLengthX, float focalLengthY, float principalX, float principalY,
float zScale, RotationAngle imageRotation = RotationAngle.Rotation0, bool isMirrored = false)
{
return CameraToPoint(rectangle, point3d.X, point3d.Y, point3d.Z, focalLengthX, focalLengthY, principalX, principalY, zScale, imageRotation, isMirrored);
}
/// <summary>
/// Get the coordinates represented by <paramref name="point3d" /> in local coordinate system.
/// </summary>
/// <param name="rectangle">Rectangle to get a point inside</param>
/// <param name="focalLength">Normalized focal lengths in NDC space</param>
/// <param name="principalPoint">Normalized principal point in NDC space</param>
/// <param name="zScale">Ratio of values in camera coordinates to local coordinates in Unity</param>
/// <param name="imageRotation">
/// Counterclockwise rotation angle of the input image in the image coordinate system.
/// In the local coordinate system, this value will often represent a clockwise rotation angle.
/// </param>
/// <param name="isMirrored">Set to true if the original coordinates is mirrored</param>
public static Vector3 GetPoint(this UnityEngine.Rect rectangle, Point3D point3d, Vector2 focalLength, Vector2 principalPoint,
float zScale, RotationAngle imageRotation = RotationAngle.Rotation0, bool isMirrored = false)
{
return CameraToPoint(rectangle, point3d.X, point3d.Y, point3d.Z, focalLength, principalPoint, zScale, imageRotation, isMirrored);
}
/// <summary>
/// Get the coordinates represented by <paramref name="point3d" /> in local coordinate system.
/// </summary>
/// <param name="rectangle">Rectangle to get a point inside</param>
/// <param name="zScale">Ratio of values in camera coordinates to local coordinates in Unity</param>
/// <param name="imageRotation">
/// Counterclockwise rotation angle of the input image in the image coordinate system.
/// In the local coordinate system, this value will often represent a clockwise rotation angle.
/// </param>
/// <param name="isMirrored">Set to true if the original coordinates is mirrored</param>
public static Vector3 GetPoint(this UnityEngine.Rect rectangle, Point3D point3d,
float zScale, RotationAngle imageRotation = RotationAngle.Rotation0, bool isMirrored = false)
{
return CameraToPoint(rectangle, point3d.X, point3d.Y, point3d.Z, zScale, imageRotation, isMirrored);
}
public static Quaternion GetApproximateQuaternion(ObjectAnnotation objectAnnotation, RotationAngle imageRotation = RotationAngle.Rotation0, bool isMirrored = false)
{
var isInverted = IsInverted(imageRotation);
var isXReversed = IsXReversed(imageRotation, isMirrored);
var isYReversed = IsYReversed(imageRotation, isMirrored);
var forward = GetZDir(objectAnnotation, isXReversed, isYReversed, isInverted);
var upward = GetYDir(objectAnnotation, isXReversed, isYReversed, isInverted);
return Quaternion.LookRotation(forward, upward);
}
public static (Vector3, Vector3, Vector3) GetDirections(ObjectAnnotation objectAnnotation, RotationAngle imageRotation = RotationAngle.Rotation0, bool isMirrored = false)
{
var isInverted = IsInverted(imageRotation);
var isXReversed = IsXReversed(imageRotation, isMirrored);
var isYReversed = IsYReversed(imageRotation, isMirrored);
var scale = objectAnnotation.Scale;
var xDir = scale[0] * GetXDir(objectAnnotation, isXReversed, isYReversed, isInverted);
var yDir = scale[1] * GetYDir(objectAnnotation, isXReversed, isYReversed, isInverted);
var zDir = scale[2] * GetZDir(objectAnnotation, isXReversed, isYReversed, isInverted);
return (xDir, yDir, zDir);
}
private static Vector3 GetXDir(ObjectAnnotation objectAnnotation, bool isXReversed, bool isYReversed, bool isInverted)
{
var points = objectAnnotation.Keypoints;
var v1 = GetDirection(points[1].Point3D, points[5].Point3D, isXReversed, isYReversed, isInverted).normalized;
var v2 = GetDirection(points[2].Point3D, points[6].Point3D, isXReversed, isYReversed, isInverted).normalized;
var v3 = GetDirection(points[3].Point3D, points[7].Point3D, isXReversed, isYReversed, isInverted).normalized;
var v4 = GetDirection(points[4].Point3D, points[8].Point3D, isXReversed, isYReversed, isInverted).normalized;
return (v1 + v2 + v3 + v4) / 4;
}
private static Vector3 GetYDir(ObjectAnnotation objectAnnotation, bool isXReversed, bool isYReversed, bool isInverted)
{
var points = objectAnnotation.Keypoints;
var v1 = GetDirection(points[1].Point3D, points[3].Point3D, isXReversed, isYReversed, isInverted).normalized;
var v2 = GetDirection(points[2].Point3D, points[4].Point3D, isXReversed, isYReversed, isInverted).normalized;
var v3 = GetDirection(points[5].Point3D, points[7].Point3D, isXReversed, isYReversed, isInverted).normalized;
var v4 = GetDirection(points[6].Point3D, points[8].Point3D, isXReversed, isYReversed, isInverted).normalized;
return (v1 + v2 + v3 + v4) / 4;
}
private static Vector3 GetZDir(ObjectAnnotation objectAnnotation, bool isXReversed, bool isYReversed, bool isInverted)
{
var points = objectAnnotation.Keypoints;
var v1 = GetDirection(points[2].Point3D, points[1].Point3D, isXReversed, isYReversed, isInverted).normalized;
var v2 = GetDirection(points[4].Point3D, points[3].Point3D, isXReversed, isYReversed, isInverted).normalized;
var v3 = GetDirection(points[6].Point3D, points[5].Point3D, isXReversed, isYReversed, isInverted).normalized;
var v4 = GetDirection(points[8].Point3D, points[7].Point3D, isXReversed, isYReversed, isInverted).normalized;
return (v1 + v2 + v3 + v4) / 4;
}
private static Vector3 GetDirection(Point3D from, Point3D to, bool isXReversed, bool isYReversed, bool isInverted)
{
var xDiff = to.X - from.X;
var yDiff = to.Y - from.Y;
var (xDir, yDir) = isInverted ? (yDiff, xDiff) : (xDiff, yDiff);
// convert from right-handed to left-handed
return new Vector3(isXReversed ? -xDir : xDir, isYReversed ? -yDir : yDir, from.Z - to.Z);
}
/// <summary>
/// When the image is rotated back, returns whether the axis parallel to the X axis of the Unity coordinates is pointing in the same direction as the X axis of the Unity coordinates.
/// For example, if <paramref name="rotationAngle" /> is <see cref="RotationAngle.Rotation180" /> and <paramRef name="isMirrored" /> is <c>false</c>, this returns <c>true</c>
/// because the original Y axis will be exactly opposite the X axis in Unity coordinates if the image is rotated back.
/// </summary>
public static bool IsXReversed(RotationAngle rotationAngle, bool isMirrored = false)
{
return isMirrored ?
rotationAngle == RotationAngle.Rotation0 || rotationAngle == RotationAngle.Rotation270 :
rotationAngle == RotationAngle.Rotation180 || rotationAngle == RotationAngle.Rotation270;
}
/// <summary>
/// When the image is rotated back, returns whether the axis parallel to the X axis of the Unity coordinates is pointing in the same direction as the X axis of the Unity coordinates.
/// For example, if <paramref name="rotationAngle" /> is <see cref="RotationAngle.Rotation180" /> and <paramRef name="isMirrored" /> is <c>false</c>, this returns <c>true</c>
/// because the original X axis will be exactly opposite the Y axis in Unity coordinates if the image is rotated back.
/// </summary>
public static bool IsYReversed(RotationAngle rotationAngle, bool isMirrored = false)
{
return isMirrored ?
rotationAngle == RotationAngle.Rotation180 || rotationAngle == RotationAngle.Rotation270 :
rotationAngle == RotationAngle.Rotation90 || rotationAngle == RotationAngle.Rotation180;
}
/// <summary>
/// Returns <c>true</c> if <paramref name="rotationAngle" /> is <see cref="RotationAngle.Rotation90" /> or <see cref="RotationAngle.Rotation270" />.
/// </summary>
public static bool IsInverted(RotationAngle rotationAngle)
{
return rotationAngle == RotationAngle.Rotation90 || rotationAngle == RotationAngle.Rotation270;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 92d2557dc55654e76b24cf607ac18146
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,676 @@
// Copyright (c) 2021 homuler
//
// Use of this source code is governed by an MIT-style
// license that can be found in the LICENSE file or at
// https://opensource.org/licenses/MIT.
using UnityEngine;
using mplt = Mediapipe.LocationData.Types;
namespace Mediapipe.Unity.CoordinateSystem
{
/// <summary>
/// This class provides helper methods for converting from image coordinate values to local coordinate values in Unity, and vice versa.
/// </summary>
public static class ImageCoordinate
{
/// <summary>
/// Convert from image coordinates to local coordinates in Unity.
/// </summary>
/// <param name="x">Column value in the image coordinate system</param>
/// <param name="y">Row value in the image coordinate system</param>
/// <param name="z">Depth value in the local coordinate system</param>
/// <param name="screenWidth">
/// The target screen width. The returned value will be local to this screen.
/// </param>
/// <param name="xMin">The minimum X coordinate of the target rectangle</param>
/// <param name="xMax">The maximum X coordinate of the target rectangle</param>
/// <param name="yMin">The minimum X coordinate of the target rectangle</param>
/// <param name="yMax">The maximum X coordinate of the target rectangle</param>
/// <param name="imageWidth">Image width in pixels</param>
/// <param name="imageHeight">Image width in pixels</param>
/// <param name="imageRotation">
/// Counterclockwise rotation angle of the input image in the image coordinate system.
/// In the local coordinate system, this value will often represent a clockwise rotation angle.
/// </param>
/// <param name="isMirrored">Set to true if the image coordinates is mirrored</param>
public static Vector3 ImageToLocalPoint(int x, int y, int z, float xMin, float xMax, float yMin, float yMax,
int imageWidth, int imageHeight, RotationAngle imageRotation = RotationAngle.Rotation0, bool isMirrored = false)
{
var isInverted = IsInverted(imageRotation);
var (rectX, rectY) = isInverted ? (y, x) : (x, y);
var (width, height) = (xMax - xMin, yMax - yMin);
var localX = ((IsXReversed(imageRotation, isMirrored) ? imageWidth - rectX : rectX) * width / imageWidth) + xMin;
var localY = ((IsYReversed(imageRotation, isMirrored) ? imageHeight - rectY : rectY) * height / imageHeight) + yMin;
return new Vector3(localX, localY, z);
}
/// <summary>
/// Convert from image coordinates to local coordinates in Unity.
/// </summary>
/// <param name="rectangle">Rectangle to get a point inside</param>
/// <param name="x">Column value in the image coordinate system</param>
/// <param name="y">Row value in the image coordinate system</param>
/// <param name="z">Depth value in the local coordinate system</param>
/// <param name="imageWidth">Image width in pixels</param>
/// <param name="imageHeight">Image width in pixels</param>
/// <param name="imageRotation">
/// Counterclockwise rotation angle of the input image in the image coordinate system.
/// In the local coordinate system, this value will often represent a clockwise rotation angle.
/// </param>
/// <param name="isMirrored">Set to true if the image coordinates is mirrored</param>
public static Vector3 ImageToPoint(UnityEngine.Rect rectangle, int x, int y, int z,
int imageWidth, int imageHeight, RotationAngle imageRotation = RotationAngle.Rotation0, bool isMirrored = false)
{
return ImageToLocalPoint(x, y, z, rectangle.xMin, rectangle.xMax, rectangle.yMin, rectangle.yMax, imageWidth, imageHeight, imageRotation, isMirrored);
}
/// <summary>
/// Convert from image coordinates to local coordinates in Unity.
/// </summary>
/// <param name="rectangle">Rectangle to get a point inside</param>
/// <param name="position">
/// The position in the image coordinate system.
/// If <c>position.z</c> is not zero, it's assumed to be the depth value in the local coordinate system.
/// </param>
/// <param name="imageSize">Image size in pixels</param>
/// <param name="imageRotation">
/// Counterclockwise rotation angle of the input image in the image coordinate system.
/// In the local coordinate system, this value will often represent a clockwise rotation angle.
/// </param>
/// <param name="isMirrored">Set to true if the image coordinates is mirrored</param>
public static Vector3 ImageToPoint(UnityEngine.Rect rectangle, Vector3Int position,
Vector2Int imageSize, RotationAngle imageRotation = RotationAngle.Rotation0, bool isMirrored = false)
{
return ImageToPoint(rectangle, position.x, position.y, position.z, imageSize.x, imageSize.y, imageRotation, isMirrored);
}
/// <summary>
/// Convert from image coordinates to local coordinates in Unity.
/// </summary>
/// <param name="rectangle">Rectangle to get a point inside</param>
/// <param name="x">Column value in the image coordinate system</param>
/// <param name="y">Row value in the image coordinate system</param>
/// <param name="imageWidth">Image width in pixels</param>
/// <param name="imageHeight">Image width in pixels</param>
/// <param name="imageRotation">
/// Counterclockwise rotation angle of the input image in the image coordinate system.
/// In the local coordinate system, this value will often represent a clockwise rotation angle.
/// </param>
/// <param name="isMirrored">Set to true if the image coordinates is mirrored</param>
public static Vector3 ImageToPoint(UnityEngine.Rect rectangle, int x, int y,
int imageWidth, int imageHeight, RotationAngle imageRotation = RotationAngle.Rotation0, bool isMirrored = false)
{
return ImageToLocalPoint(x, y, 0, rectangle.xMin, rectangle.xMax, rectangle.yMin, rectangle.yMax, imageWidth, imageHeight, imageRotation, isMirrored);
}
/// <summary>
/// Convert from image coordinates to local coordinates in Unity.
/// </summary>
/// <param name="rectangle">Rectangle to get a point inside</param>
/// <param name="position">The position in the image coordinate system</param>
/// <param name="imageSize">Image size in pixels</param>
/// <param name="imageRotation">
/// Counterclockwise rotation angle of the input image in the image coordinate system.
/// In the local coordinate system, this value will often represent a clockwise rotation angle.
/// </param>
/// <param name="isMirrored">Set to true if the image coordinates is mirrored</param>
public static Vector3 ImageToPoint(UnityEngine.Rect rectangle, Vector2Int position, Vector2Int imageSize,
RotationAngle imageRotation = RotationAngle.Rotation0, bool isMirrored = false)
{
return ImageToPoint(rectangle, position.x, position.y, imageSize.x, imageSize.y, imageRotation, isMirrored);
}
/// <summary>
/// Convert normalized values in the image coordinate system to local coordinate values in Unity.
/// If the normalized values are out of [0, 1], the return value will be off the target screen.
/// </summary>
/// <param name="normalizedX">Normalized x value in the image coordinate system</param>
/// <param name="normalizedY">Normalized y value in the image coordinate system</param>
/// <param name="normalizedZ">Normalized z value in the image coordinate system</param>
/// <param name="xMin">The minimum X coordinate of the target rectangle</param>
/// <param name="xMax">The maximum X coordinate of the target rectangle</param>
/// <param name="yMin">The minimum X coordinate of the target rectangle</param>
/// <param name="yMax">The maximum X coordinate of the target rectangle</param>
/// <param name="zScale">Ratio of Z value in image coordinates to local coordinates in Unity</param>
/// <param name="imageRotation">
/// Counterclockwise rotation angle of the input image in the image coordinate system.
/// In the local coordinate system, this value will often represent a clockwise rotation angle.
/// </param>
/// <param name="isMirrored">Set to true if the original coordinates is mirrored</param>
public static Vector3 ImageNormalizedToLocalPoint(float normalizedX, float normalizedY, float normalizedZ, float xMin, float xMax, float yMin, float yMax,
float zScale, RotationAngle imageRotation = RotationAngle.Rotation0, bool isMirrored = false)
{
var isInverted = IsInverted(imageRotation);
var (nx, ny) = isInverted ? (normalizedY, normalizedX) : (normalizedX, normalizedY);
var x = IsXReversed(imageRotation, isMirrored) ? Mathf.LerpUnclamped(xMax, xMin, nx) : Mathf.LerpUnclamped(xMin, xMax, nx);
var y = IsYReversed(imageRotation, isMirrored) ? Mathf.LerpUnclamped(yMax, yMin, ny) : Mathf.LerpUnclamped(yMin, yMax, ny);
var z = zScale * normalizedZ;
return new Vector3(x, y, z);
}
/// <summary>
/// Convert normalized values in the image coordinate system to local coordinate values in Unity.
/// If the normalized values are out of [0, 1], the return value will be off the target screen.
/// </summary>
/// <param name="rectangle">Rectangle to get a point inside</param>
/// <param name="normalizedX">Normalized x value in the image coordinate system</param>
/// <param name="normalizedY">Normalized y value in the image coordinate system</param>
/// <param name="normalizedZ">Normalized z value in the image coordinate system</param>
/// <param name="zScale">Ratio of Z value in image coordinates to local coordinates in Unity</param>
/// <param name="imageRotation">
/// Counterclockwise rotation angle of the input image in the image coordinate system.
/// In the local coordinate system, this value will often represent a clockwise rotation angle.
/// </param>
/// <param name="isMirrored">Set to true if the original coordinates is mirrored</param>
public static Vector3 ImageNormalizedToPoint(UnityEngine.Rect rectangle, float normalizedX, float normalizedY, float normalizedZ,
float zScale, RotationAngle imageRotation = RotationAngle.Rotation0, bool isMirrored = false)
{
return ImageNormalizedToLocalPoint(normalizedX, normalizedY, normalizedZ, rectangle.xMin, rectangle.xMax, rectangle.yMin, rectangle.yMax, zScale, imageRotation, isMirrored);
}
/// <summary>
/// Convert normalized values in the image coordinate system to local coordinate values in Unity.
/// If the normalized values are out of [0, 1], the return value will be off the target screen.
/// </summary>
/// <param name="rectangle">Rectangle to get a point inside</param>
/// <param name="position">The position in the image coordinate system</param>
/// <param name="zScale">Ratio of Z value in image coordinates to local coordinates in Unity</param>
/// <param name="imageRotation">
/// Counterclockwise rotation angle of the input image in the image coordinate system.
/// In the local coordinate system, this value will often represent a clockwise rotation angle.
/// </param>
/// <param name="isMirrored">Set to true if the original coordinates is mirrored</param>
public static Vector3 ImageNormalizedToPoint(UnityEngine.Rect rectangle, Vector3 position,
float zScale, RotationAngle imageRotation = RotationAngle.Rotation0, bool isMirrored = false)
{
return ImageNormalizedToPoint(rectangle, position.x, position.y, position.z, zScale, imageRotation, isMirrored);
}
/// <summary>
/// Convert normalized values in the image coordinate system to local coordinate values in Unity.
/// If the normalized values are out of [0, 1], the return value will be off the target screen.
/// </summary>
/// <param name="normalizedX">Normalized x value in the image coordinate system</param>
/// <param name="normalizedY">Normalized y value in the image coordinate system</param>
/// <param name="normalizedZ">Normalized z value in the image coordinate system</param>
/// <param name="xMin">The minimum X coordinate of the target rectangle</param>
/// <param name="xMax">The maximum X coordinate of the target rectangle</param>
/// <param name="yMin">The minimum X coordinate of the target rectangle</param>
/// <param name="yMax">The maximum X coordinate of the target rectangle</param>
/// <param name="imageRotation">
/// Counterclockwise rotation angle of the input image in the image coordinate system.
/// In the local coordinate system, this value will often represent a clockwise rotation angle.
/// </param>
/// <param name="isMirrored">Set to true if the original coordinates is mirrored</param>
public static Vector3 ImageNormalizedToLocalPoint(float normalizedX, float normalizedY, float normalizedZ, float xMin, float xMax, float yMin, float yMax,
RotationAngle imageRotation = RotationAngle.Rotation0, bool isMirrored = false)
{
// Z usually uses roughly the same scale as X
var zScale = IsInverted(imageRotation) ? (yMax - yMin) : (xMax - xMin);
return ImageNormalizedToLocalPoint(normalizedX, normalizedY, normalizedZ, xMin, xMax, yMin, yMax, zScale, imageRotation, isMirrored);
}
/// <summary>
/// Convert normalized values in the image coordinate system to local coordinate values in Unity.
/// If the normalized values are out of [0, 1], the return value will be off the target screen.
/// </summary>
/// <param name="rectangle">Rectangle to get a point inside</param>
/// <param name="normalizedX">Normalized x value in the image coordinate system</param>
/// <param name="normalizedY">Normalized y value in the image coordinate system</param>
/// <param name="normalizedZ">Normalized z value in the image coordinate system</param>
/// <param name="imageRotation">
/// Counterclockwise rotation angle of the input image in the image coordinate system.
/// In the local coordinate system, this value will often represent a clockwise rotation angle.
/// </param>
/// <param name="isMirrored">Set to true if the original coordinates is mirrored</param>
public static Vector3 ImageNormalizedToPoint(UnityEngine.Rect rectangle, float normalizedX, float normalizedY, float normalizedZ,
RotationAngle imageRotation = RotationAngle.Rotation0, bool isMirrored = false)
{
return ImageNormalizedToLocalPoint(normalizedX, normalizedY, normalizedZ, rectangle.xMin, rectangle.xMax, rectangle.yMin, rectangle.yMax, imageRotation, isMirrored);
}
/// <summary>
/// Convert normalized values in the image coordinate system to local coordinate values in Unity.
/// If the normalized values are out of [0, 1], the return value will be off the target screen.
/// </summary>
/// <param name="rectangle">Rectangle to get a point inside</param>
/// <param name="position">The position in the image coordinate system</param>
/// <param name="imageRotation">
/// Counterclockwise rotation angle of the input image in the image coordinate system.
/// In the local coordinate system, this value will often represent a clockwise rotation angle.
/// </param>
/// <param name="isMirrored">Set to true if the original coordinates is mirrored</param>
public static Vector3 ImageNormalizedToPoint(UnityEngine.Rect rectangle, Vector3 position, RotationAngle imageRotation = RotationAngle.Rotation0, bool isMirrored = false)
{
return ImageNormalizedToPoint(rectangle, position.x, position.y, position.z, imageRotation, isMirrored);
}
/// <summary>
/// Convert normalized values in the image coordinate system to local coordinate values in Unity.
/// If the normalized values are out of [0, 1], the return value will be off the target screen.
/// </summary>
/// <param name="rectangle">Rectangle to get a point inside</param>
/// <param name="normalizedX">Normalized x value in the image coordinate system</param>
/// <param name="normalizedY">Normalized y value in the image coordinate system</param>
/// <param name="imageRotation">
/// Counterclockwise rotation angle of the input image in the image coordinate system.
/// In the local coordinate system, this value will often represent a clockwise rotation angle.
/// </param>
/// <param name="isMirrored">Set to true if the original coordinates is mirrored</param>
public static Vector3 ImageNormalizedToPoint(UnityEngine.Rect rectangle, float normalizedX, float normalizedY,
RotationAngle imageRotation = RotationAngle.Rotation0, bool isMirrored = false)
{
return ImageNormalizedToPoint(rectangle, normalizedX, normalizedY, 0, imageRotation, isMirrored);
}
/// <summary>
/// Convert normalized values in the image coordinate system to local coordinate values in Unity.
/// If the normalized values are out of [0, 1], the return value will be off the target screen.
/// </summary>
/// <param name="rectangle">Rectangle to get a point inside</param>
/// <param name="position">The position in the image coordinate system</param>
/// <param name="imageRotation">
/// Counterclockwise rotation angle of the input image in the image coordinate system.
/// In the local coordinate system, this value will often represent a clockwise rotation angle.
/// </param>
/// <param name="isMirrored">Set to true if the original coordinates is mirrored</param>
public static Vector3 ImageNormalizedToPoint(UnityEngine.Rect rectangle, Vector2 position, RotationAngle imageRotation = RotationAngle.Rotation0, bool isMirrored = false)
{
return ImageNormalizedToPoint(rectangle, position.x, position.y, imageRotation, isMirrored);
}
/// <summary>
/// Returns a <see cref="Vector3" /> array which represents a rectangle's vertices.
/// They are in clockwise order, starting from the coordinate that was in the bottom-left.
/// </summary>
/// <remarks>
/// Z values are always zero.
/// </remarks>
/// <param name="rectangle">Rectangle to get a point inside</param>
/// <param name="xMin">Leftmost X value</param>
/// <param name="yMin">Topmost Y value</param>
/// <param name="imageWidth">Image width in pixels</param>
/// <param name="imageHeight">Image width in pixels</param>
/// <param name="imageRotation">
/// Counterclockwise rotation angle of the input image in the image coordinate system.
/// In the local coordinate system, this value will often represent a clockwise rotation angle.
/// </param>
/// <param name="isMirrored">Set to true if the original coordinates is mirrored</param>
public static Vector3[] ImageToRectVertices(UnityEngine.Rect rectangle, int xMin, int yMin, int width, int height,
int imageWidth, int imageHeight, RotationAngle imageRotation = RotationAngle.Rotation0, bool isMirrored = false)
{
var p = ImageToPoint(rectangle, xMin, yMin + height, imageWidth, imageHeight, imageRotation, isMirrored);
var q = ImageToPoint(rectangle, xMin + width, yMin, imageWidth, imageHeight, imageRotation, isMirrored);
return GetRectVertices(p, q);
}
/// <summary>
/// Returns a <see cref="Vector3" /> array which represents a rectangle's vertices.
/// They are in clockwise order, starting from the coordinate that was in the bottom-left.
/// </summary>
/// <remarks>
/// Z values are always zero.
/// </remarks>
/// <param name="rectangle">Rectangle to get a point inside</param>
/// <param name="xMin">Leftmost X value</param>
/// <param name="yMin">Topmost Y value</param>
/// <param name="imageSize">Image size in pixels</param>
/// <param name="imageRotation">
/// Counterclockwise rotation angle of the input image in the image coordinate system.
/// In the local coordinate system, this value will often represent a clockwise rotation angle.
/// </param>
/// <param name="isMirrored">Set to true if the original coordinates is mirrored</param>
public static Vector3[] ImageToRectVertices(UnityEngine.Rect rectangle, int xMin, int yMin, int width, int height,
Vector2Int imageSize, RotationAngle imageRotation = RotationAngle.Rotation0, bool isMirrored = false)
{
return ImageToRectVertices(rectangle, xMin, yMin, width, height, imageSize.x, imageSize.y, imageRotation, isMirrored);
}
/// <summary>
/// Returns a <see cref="Vector3" /> array which represents a rectangle's vertices.
/// They are in clockwise order, starting from the coordinate that was in the bottom-left.
/// </summary>
/// <remarks>
/// Z values are always zero.
/// </remarks>
/// <param name="rectangle">Rectangle to get a point inside</param>
/// <param name="normalizedXMin">Normalized leftmost X value</param>
/// <param name="normalizedYMin">Normalized topmost Y value</param>
/// <param name="normalizedWidth">Normalized width</param>
/// <param name="normalizedHeight">Normalized height</param>
/// <param name="imageRotation">
/// Counterclockwise rotation angle of the input image in the image coordinate system.
/// In the local coordinate system, this value will often represent a clockwise rotation angle.
/// </param>
/// <param name="isMirrored">Set to true if the original coordinates is mirrored</param>
public static Vector3[] ImageNormalizedToRectVertices(UnityEngine.Rect rectangle, float normalizedXMin, float normalizedYMin, float normalizedWidth, float normalizedHeight,
RotationAngle imageRotation = RotationAngle.Rotation0, bool isMirrored = false)
{
var p = ImageNormalizedToPoint(rectangle, normalizedXMin, normalizedYMin + normalizedHeight, imageRotation, isMirrored);
var q = ImageNormalizedToPoint(rectangle, normalizedXMin + normalizedWidth, normalizedYMin, imageRotation, isMirrored);
return GetRectVertices(p, q);
}
/// <summary>
/// Returns a <see cref="Vector3" /> array which represents a rectangle's vertices.
/// They are in clockwise order, starting from the coordinate that was in the bottom-left before the rotation.
/// </summary>
/// <param name="rectangle">Rectangle to get a point inside</param>
/// <param name="xCenter">X value of the rectangle's center coordinate</param>
/// <param name="yCenter">Y value of the rectangle's center coordinate</param>
/// <param name="rotation">Clockwise rotation angle in radians</param>
/// <param name="imageWidth">Image width in pixels</param>
/// <param name="imageHeight">Image width in pixels</param>
/// <param name="imageRotation">
/// Counterclockwise rotation angle of the input image in the image coordinate system.
/// In the local coordinate system, this value will often represent a clockwise rotation angle.
/// </param>
/// <param name="isMirrored">Set to true if the original coordinates is mirrored</param>
public static Vector3[] ImageToRectVertices(UnityEngine.Rect rectangle, int xCenter, int yCenter, int width, int height, float rotation,
int imageWidth, int imageHeight, RotationAngle imageRotation = RotationAngle.Rotation0, bool isMirrored = false)
{
var isInverted = IsInverted(imageRotation);
var (rectWidth, rectHeight) = IsInverted(imageRotation) ? (height, width) : (width, height);
var center = ImageToPoint(rectangle, xCenter, yCenter, imageWidth, imageHeight, imageRotation, isMirrored);
var isRotationReversed = isInverted ^ IsXReversed(imageRotation, isMirrored) ^ IsYReversed(imageRotation, isMirrored);
var quaternion = Quaternion.Euler(0, 0, (isRotationReversed ? -1 : 1) * Mathf.Rad2Deg * rotation);
var bottomLeftRel = quaternion * new Vector3(-rectWidth / 2, -rectHeight / 2, 0);
var topLeftRel = quaternion * new Vector3(-rectWidth / 2, rectHeight / 2, 0);
return new Vector3[] {
center + bottomLeftRel,
center + topLeftRel,
center - bottomLeftRel,
center - topLeftRel,
};
}
/// <summary>
/// Returns a <see cref="Vector3" /> array which represents a rectangle's vertices.
/// They are in clockwise order, starting from the coordinate that was in the bottom-left before the rotation.
/// </summary>
/// <param name="rectangle">Rectangle to get a point inside</param>
/// <param name="xCenter">X value of the rectangle's center coordinate</param>
/// <param name="yCenter">Y value of the rectangle's center coordinate</param>
/// <param name="rotation">Clockwise rotation angle in radians</param>
/// <param name="imageSize">Image size in pixels</param>
/// <param name="imageRotation">
/// Counterclockwise rotation angle of the input image in the image coordinate system.
/// In the local coordinate system, this value will often represent a clockwise rotation angle.
/// </param>
/// <param name="isMirrored">Set to true if the original coordinates is mirrored</param>
public static Vector3[] ImageToRectVertices(UnityEngine.Rect rectangle, int xCenter, int yCenter, int width, int height, float rotation,
Vector2Int imageSize, RotationAngle imageRotation = RotationAngle.Rotation0, bool isMirrored = false)
{
return ImageToRectVertices(rectangle, xCenter, yCenter, width, height, rotation, imageSize.x, imageSize.y, imageRotation, isMirrored);
}
/// <summary>
/// Returns a <see cref="Vector3" /> array which represents a rectangle's vertices.
/// They are in clockwise order, starting from the coordinate that was in the bottom-left before the rotation.
/// </summary>
/// <param name="rectangle">Rectangle to get a point inside</param>
/// <param name="normalizedXCenter">X value of the rectangle's center coordinate</param>
/// <param name="normalizedYCenter">Y value of the rectangle's center coordinate</param>
/// <param name="normalizedWidth">Normalized width</param>
/// <param name="normalizedHeight">Normalized height</param>
/// <param name="rotation">Clockwise rotation angle in radians</param>
/// <param name="imageRotation">
/// Counterclockwise rotation angle of the input image in the image coordinate system.
/// In the local coordinate system, this value will often represent a clockwise rotation angle.
/// </param>
/// <param name="isMirrored">Set to true if the original coordinates is mirrored</param>
public static Vector3[] ImageNormalizedToRectVertices(UnityEngine.Rect rectangle, float normalizedXCenter, float normalizedYCenter, float normalizedWidth, float normalizedHeight,
float rotation, RotationAngle imageRotation = RotationAngle.Rotation0, bool isMirrored = false)
{
var isInverted = IsInverted(imageRotation);
var width = rectangle.width * (isInverted ? normalizedHeight : normalizedWidth);
var height = rectangle.height * (isInverted ? normalizedWidth : normalizedHeight);
var center = ImageNormalizedToPoint(rectangle, normalizedXCenter, normalizedYCenter, imageRotation, isMirrored);
var isRotationReversed = isInverted ^ IsXReversed(imageRotation, isMirrored) ^ IsYReversed(imageRotation, isMirrored);
var quaternion = Quaternion.Euler(0, 0, (isRotationReversed ? -1 : 1) * Mathf.Rad2Deg * rotation);
var bottomLeftRel = quaternion * new Vector3(-width / 2, -height / 2, 0);
var topLeftRel = quaternion * new Vector3(-width / 2, height / 2, 0);
return new Vector3[] {
center + bottomLeftRel,
center + topLeftRel,
center - bottomLeftRel,
center - topLeftRel,
};
}
private static Vector3[] GetRectVertices(Vector2 p, Vector2 q)
{
var leftX = Mathf.Min(p.x, q.x);
var rightX = Mathf.Max(p.x, q.x);
var bottomY = Mathf.Min(p.y, q.y);
var topY = Mathf.Max(p.y, q.y);
var bottomLeft = new Vector3(leftX, bottomY);
var topLeft = new Vector3(leftX, topY);
var topRight = new Vector3(rightX, topY);
var bottomRight = new Vector3(rightX, bottomY);
return new Vector3[] { bottomLeft, topLeft, topRight, bottomRight };
}
/// <summary>
/// Get the coordinates represented by <paramref name="relativeKeypoint" /> in the local coordinate system.
/// </summary>
/// <param name="rectangle">Rectangle to get a point inside</param>
/// <param name="imageRotation">
/// Counterclockwise rotation angle of the input image in the image coordinate system.
/// In the local coordinate system, this value will often represent a clockwise rotation angle.
/// </param>
/// <param name="isMirrored">Set to true if the original coordinates is mirrored</param>
public static Vector2 GetPoint(this UnityEngine.Rect rectangle, mplt.RelativeKeypoint relativeKeypoint,
RotationAngle imageRotation = RotationAngle.Rotation0, bool isMirrored = false)
{
return ImageNormalizedToPoint(rectangle, relativeKeypoint.X, relativeKeypoint.Y, imageRotation, isMirrored);
}
/// <summary>
/// Get the coordinates represented by <paramref name="normalizedLandmark" /> in the local coordinate system.
/// </summary>
/// <param name="rectangle">Rectangle to get a point inside</param>
/// <param name="imageRotation">
/// Counterclockwise rotation angle of the input image in the image coordinate system.
/// In the local coordinate system, this value will often represent a clockwise rotation angle.
/// </param>
/// <param name="isMirrored">Set to true if the original coordinates is mirrored</param>
public static Vector3 GetPoint(this UnityEngine.Rect rectangle, NormalizedLandmark normalizedLandmark,
RotationAngle imageRotation = RotationAngle.Rotation0, bool isMirrored = false)
{
return ImageNormalizedToPoint(rectangle, normalizedLandmark.X, normalizedLandmark.Y, normalizedLandmark.Z, imageRotation, isMirrored);
}
/// <summary>
/// Get the coordinates represented by <paramref name="point2d" /> in the local coordinate system.
/// </summary>
/// <param name="rectangle">Rectangle to get a point inside</param>
/// <param name="imageRotation">
/// Counterclockwise rotation angle of the input image in the image coordinate system.
/// In the local coordinate system, this value will often represent a clockwise rotation angle.
/// </param>
/// <param name="isMirrored">Set to true if the original coordinates is mirrored</param>
public static Vector3 GetPoint(this UnityEngine.Rect rectangle, NormalizedPoint2D point2d, RotationAngle imageRotation = RotationAngle.Rotation0, bool isMirrored = false)
{
return ImageNormalizedToPoint(rectangle, point2d.X, point2d.Y, imageRotation, isMirrored);
}
/// <summary>
/// Get the coordinates represented by <paramref name="anchor3d" /> in the local coordinate system.
/// </summary>
/// <param name="rectangle">Rectangle to get a point inside</param>
/// <param name="imageRotation">
/// Counterclockwise rotation angle of the input image in the image coordinate system.
/// In the local coordinate system, this value will often represent a clockwise rotation angle.
/// </param>
/// <param name="isMirrored">Set to true if the original coordinates is mirrored</param>
public static Vector2 GetPoint(this UnityEngine.Rect rectangle, Anchor3d anchor3d, RotationAngle imageRotation = RotationAngle.Rotation0, bool isMirrored = false)
{
return ImageNormalizedToPoint(rectangle, anchor3d.x, anchor3d.y, imageRotation, isMirrored);
}
/// <summary>
/// Get a Vector3 array which represents <paramref name="boundingBox" />'s vertex coordinates in the local coordinate system.
/// They are ordered clockwise from bottom-left point.
/// </summary>
/// <param name="rectangle">Rectangle to get a point inside</param>
/// <param name="imageWidth">Image width in pixels</param>
/// <param name="imageHeight">Image width in pixels</param>
/// <param name="imageRotation">
/// Counterclockwise rotation angle of the input image in the image coordinate system.
/// In the local coordinate system, this value will often represent a clockwise rotation angle.
/// </param>
/// <param name="isMirrored">Set to true if the original coordinates is mirrored</param>
public static Vector3[] GetRectVertices(this UnityEngine.Rect rectangle, mplt.BoundingBox boundingBox, int imageWidth, int imageHeight,
RotationAngle imageRotation = RotationAngle.Rotation0, bool isMirrored = false)
{
return ImageToRectVertices(rectangle, boundingBox.Xmin, boundingBox.Ymin, boundingBox.Width, boundingBox.Height, imageWidth, imageHeight, imageRotation, isMirrored);
}
/// <summary>
/// Get a Vector3 array which represents <paramref name="boundingBox" />'s vertex coordinates in the local coordinate system.
/// They are ordered clockwise from bottom-left point.
/// </summary>
/// <param name="rectangle">Rectangle to get a point inside</param>
/// <param name="imageSize">Image size in pixels</param>
/// <param name="imageRotation">
/// Counterclockwise rotation angle of the input image in the image coordinate system.
/// In the local coordinate system, this value will often represent a clockwise rotation angle.
/// </param>
/// <param name="isMirrored">Set to true if the original coordinates is mirrored</param>
public static Vector3[] GetRectVertices(this UnityEngine.Rect rectangle, mplt.BoundingBox boundingBox, Vector2Int imageSize,
RotationAngle imageRotation = RotationAngle.Rotation0, bool isMirrored = false)
{
return ImageToRectVertices(rectangle, boundingBox.Xmin, boundingBox.Ymin, boundingBox.Width, boundingBox.Height, imageSize, imageRotation, isMirrored);
}
/// <summary>
/// Get a Vector3 array which represents <paramref name="boundingBox" />'s vertex coordinates in the local coordinate system.
/// They are ordered clockwise from bottom-left point.
/// </summary>
/// <param name="rectangle">Rectangle to get a point inside</param>
/// <param name="imageRotation">
/// Counterclockwise rotation angle of the input image in the image coordinate system.
/// In the local coordinate system, this value will often represent a clockwise rotation angle.
/// </param>
/// <param name="isMirrored">Set to true if the original coordinates is mirrored</param>
public static Vector3[] GetRectVertices(this UnityEngine.Rect rectangle, mplt.RelativeBoundingBox boundingBox,
RotationAngle imageRotation = RotationAngle.Rotation0, bool isMirrored = false)
{
return ImageNormalizedToRectVertices(rectangle, boundingBox.Xmin, boundingBox.Ymin, boundingBox.Width, boundingBox.Height, imageRotation, isMirrored);
}
/// <summary>
/// Get a Vector3 array which represents <paramref name="rect" />'s vertex coordinates in the local coordinate system.
/// They are ordered clockwise from bottom-left point.
/// </summary>
/// <param name="rectangle">Rectangle to get a point inside</param>
/// <param name="imageWidth">Image width in pixels</param>
/// <param name="imageHeight">Image width in pixels</param>
/// <param name="imageRotation">
/// Counterclockwise rotation angle of the input image in the image coordinate system.
/// In the local coordinate system, this value will often represent a clockwise rotation angle.
/// </param>
/// <param name="isMirrored">Set to true if the original coordinates is mirrored</param>
public static Vector3[] GetRectVertices(this UnityEngine.Rect rectangle, Rect rect, int imageWidth, int imageHeight,
RotationAngle imageRotation = RotationAngle.Rotation0, bool isMirrored = false)
{
return ImageToRectVertices(rectangle, rect.XCenter, rect.YCenter, rect.Width, rect.Height, rect.Rotation, imageWidth, imageHeight, imageRotation, isMirrored);
}
/// <summary>
/// Get a Vector3 array which represents <paramref name="rect" />'s vertex coordinates in the local coordinate system.
/// They are ordered clockwise from bottom-left point.
/// </summary>
/// <param name="rectangle">Rectangle to get a point inside</param>
/// <param name="imageSize">Image size in pixels</param>
/// <param name="imageRotation">
/// Counterclockwise rotation angle of the input image in the image coordinate system.
/// In the local coordinate system, this value will often represent a clockwise rotation angle.
/// </param>
/// <param name="isMirrored">Set to true if the original coordinates is mirrored</param>
public static Vector3[] GetRectVertices(this UnityEngine.Rect rectangle, Rect rect, Vector2Int imageSize,
RotationAngle imageRotation = RotationAngle.Rotation0, bool isMirrored = false)
{
return ImageToRectVertices(rectangle, rect.XCenter, rect.YCenter, rect.Width, rect.Height, rect.Rotation, imageSize, imageRotation, isMirrored);
}
/// <summary>
/// Get a Vector3 array which represents <paramref name="normalizedRect" />'s vertex coordinates in the local coordinate system.
/// They are ordered clockwise from bottom-left point.
/// </summary>
/// <param name="rectangle">Rectangle to get a point inside</param>
/// <param name="imageRotation">
/// Counterclockwise rotation angle of the input image in the image coordinate system.
/// In the local coordinate system, this value will often represent a clockwise rotation angle.
/// </param>
/// <param name="isMirrored">Set to true if the original coordinates is mirrored</param>
public static Vector3[] GetRectVertices(this UnityEngine.Rect rectangle, NormalizedRect normalizedRect,
RotationAngle imageRotation = RotationAngle.Rotation0, bool isMirrored = false)
{
return ImageNormalizedToRectVertices(rectangle, normalizedRect.XCenter, normalizedRect.YCenter, normalizedRect.Width, normalizedRect.Height, normalizedRect.Rotation, imageRotation, isMirrored);
}
/// <summary>
/// Get the image normalized point corresponding to <paramref name="localPosition" />.
/// </summary>
/// <param name="rectangle">Rectangle to get a point inside</param>
/// <param name="imageRotation">
/// Counterclockwise rotation angle of the input image in the image coordinate system.
/// In the local coordinate system, this value will often represent a clockwise rotation angle.
/// </param>
/// <param name="isMirrored">Set to true if the original coordinates is mirrored</param>
public static Vector2 PointToImageNormalized(this UnityEngine.Rect rectangle, Vector2 localPosition, RotationAngle imageRotation = RotationAngle.Rotation0, bool isMirrored = false)
{
var normalizedX = IsXReversed(imageRotation, isMirrored) ?
Mathf.InverseLerp(rectangle.width / 2, -rectangle.width / 2, localPosition.x) :
Mathf.InverseLerp(-rectangle.width / 2, rectangle.width / 2, localPosition.x);
var normalizedY = IsYReversed(imageRotation, isMirrored) ?
Mathf.InverseLerp(rectangle.height / 2, -rectangle.height / 2, localPosition.y) :
Mathf.InverseLerp(-rectangle.height / 2, rectangle.height / 2, localPosition.y);
return IsInverted(imageRotation) ? new Vector2(normalizedY, normalizedX) : new Vector2(normalizedX, normalizedY);
}
/// <summary>
/// When the image is rotated back, returns whether the axis parallel to the X axis of the Unity coordinates is pointing in the same direction as the X axis of the Unity coordinates.
/// For example, if <paramref name="rotationAngle" /> is <see cref="RotationAngle.Rotation90" /> and <paramRef name="isMirrored" /> is <c>false</c>, this returns <c>true</c>
/// because the original Y axis will be exactly opposite the X axis in Unity coordinates if the image is rotated back.
/// </summary>
public static bool IsXReversed(RotationAngle rotationAngle, bool isMirrored = false)
{
return isMirrored ?
rotationAngle == RotationAngle.Rotation0 || rotationAngle == RotationAngle.Rotation90 :
rotationAngle == RotationAngle.Rotation90 || rotationAngle == RotationAngle.Rotation180;
}
/// <summary>
/// When the image is rotated back, returns whether the axis parallel to the X axis of the Unity coordinates is pointing in the same direction as the X axis of the Unity coordinates.
/// For example, if <paramref name="rotationAngle" /> is <see cref="RotationAngle.Rotation90" /> and <paramRef name="isMirrored" /> is <c>false</c>, this returns <c>true</c>
/// because the original X axis will be exactly opposite the Y axis in Unity coordinates if the image is rotated back.
/// </summary>
public static bool IsYReversed(RotationAngle rotationAngle, bool isMirrored = false)
{
return isMirrored ?
rotationAngle == RotationAngle.Rotation0 || rotationAngle == RotationAngle.Rotation270 :
rotationAngle == RotationAngle.Rotation0 || rotationAngle == RotationAngle.Rotation90;
}
/// <summary>
/// Returns <c>true</c> if <paramref name="rotationAngle" /> is <see cref="RotationAngle.Rotation90" /> or <see cref="RotationAngle.Rotation270" />.
/// </summary>
public static bool IsInverted(RotationAngle rotationAngle)
{
return rotationAngle == RotationAngle.Rotation90 || rotationAngle == RotationAngle.Rotation270;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: f0e382e967c8301cfb71c0baf698cb45
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,106 @@
// Copyright (c) 2021 homuler
//
// Use of this source code is governed by an MIT-style
// license that can be found in the LICENSE file or at
// https://opensource.org/licenses/MIT.
using UnityEngine;
namespace Mediapipe.Unity.CoordinateSystem
{
/// <summary>
/// This class provides helper methods for converting real-world coordinate values to local coordinate values.
/// In real-world coordinate system, X axis is toward the right, Y axis is toward the bottom, and Z axis is toward the back.
/// </summary>
public static class RealWorldCoordinate
{
/// <summary>
/// Convert from real world coordinates to Unity local coordinates.
/// Assume that the origin is common to the two coordinate systems.
/// </summary>
/// <param name="x">X in real world coordinates</param>
/// <param name="y">Y in real world coordinates</param>
/// <param name="z">Z in real world coordinates</param>
/// <param name="scale">Ratio of real world coordinate values to local coordinate values</param>
/// <param name="imageRotation">
/// Counterclockwise rotation angle of the input image in the image coordinate system.
/// In the local coordinate system, this value will often represent a clockwise rotation angle.
/// </param>
/// <param name="isMirrored">Set to true if the original coordinates is mirrored</param>
public static Vector3 RealWorldToLocalPoint(float x, float y, float z, Vector3 scale,
RotationAngle imageRotation = RotationAngle.Rotation0, bool isMirrored = false)
{
var (rx, ry) = IsInverted(imageRotation) ? (y, x) : (x, y);
var realX = IsXReversed(imageRotation, isMirrored) ? -rx : rx;
var realY = IsYReversed(imageRotation, isMirrored) ? -ry : ry;
return Vector3.Scale(new Vector3(realX, realY, z), scale);
}
/// <summary>
/// Convert from real world coordinates to Unity local coordinates.
/// Assume that the origin is common to the two coordinate systems.
/// </summary>
/// <param name="x">X in real world coordinates</param>
/// <param name="y">Y in real world coordinates</param>
/// <param name="z">Z in real world coordinates</param>
/// <param name="scaleX">Ratio of real world coordinate X to local coordinate X</param>
/// <param name="scaleY">Ratio of real world coordinate Y to local coordinate Y</param>
/// <param name="scaleZ">Ratio of real world coordinate Z to local coordinate Z</param>
/// <param name="imageRotation">
/// Counterclockwise rotation angle of the input image in the image coordinate system.
/// In the local coordinate system, this value will often represent a clockwise rotation angle.
/// </param>
/// <param name="isMirrored">Set to true if the original coordinates is mirrored</param>
public static Vector3 RealWorldToLocalPoint(float x, float y, float z, float scaleX = 1, float scaleY = 1, float scaleZ = 1,
RotationAngle imageRotation = RotationAngle.Rotation0, bool isMirrored = false)
{
return RealWorldToLocalPoint(x, y, z, new Vector3(scaleX, scaleY, scaleZ), imageRotation, isMirrored);
}
/// <summary>
/// Get the coordinates represented by <paramref name="landmark" /> in the local coordinate system.
/// </summary>
/// <param name="scale">Ratio of real world coordinate values to local coordinate values</param>
/// <param name="imageRotation">
/// Counterclockwise rotation angle of the input image in the image coordinate system.
/// In the local coordinate system, this value will often represent a clockwise rotation angle.
/// </param>
/// <param name="isMirrored">Set to true if the original coordinates is mirrored</param>
public static Vector3 GetPoint(this UnityEngine.Rect _, Landmark landmark, Vector3 scale, RotationAngle imageRotation = RotationAngle.Rotation0, bool isMirrored = false)
{
return RealWorldToLocalPoint(landmark.X, landmark.Y, landmark.Z, scale, imageRotation, isMirrored);
}
/// <summary>
/// When the image is rotated back, returns whether the axis parallel to the X axis of the Unity coordinates is pointing in the same direction as the X axis of the Unity coordinates.
/// For example, if <paramref name="rotationAngle" /> is <see cref="RotationAngle.Rotation90" /> and <paramRef name="isMirrored" /> is <c>false</c>, this returns <c>true</c>
/// because the original Y axis will be exactly opposite the X axis in Unity coordinates if the image is rotated back.
/// </summary>
public static bool IsXReversed(RotationAngle rotationAngle, bool isMirrored = false)
{
return isMirrored ?
rotationAngle == RotationAngle.Rotation0 || rotationAngle == RotationAngle.Rotation90 :
rotationAngle == RotationAngle.Rotation90 || rotationAngle == RotationAngle.Rotation180;
}
/// <summary>
/// When the image is rotated back, returns whether the axis parallel to the X axis of the Unity coordinates is pointing in the same direction as the X axis of the Unity coordinates.
/// For example, if <paramref name="rotationAngle" /> is <see cref="RotationAngle.Rotation90" /> and <paramRef name="isMirrored" /> is <c>false</c>, this returns <c>true</c>
/// because the original X axis will be exactly opposite the Y axis in Unity coordinates if the image is rotated back.
/// </summary>
public static bool IsYReversed(RotationAngle rotationAngle, bool isMirrored = false)
{
return isMirrored ?
rotationAngle == RotationAngle.Rotation0 || rotationAngle == RotationAngle.Rotation270 :
rotationAngle == RotationAngle.Rotation0 || rotationAngle == RotationAngle.Rotation90;
}
/// <summary>
/// Returns <c>true</c> if <paramref name="rotationAngle" /> is <see cref="RotationAngle.Rotation90" /> or <see cref="RotationAngle.Rotation270" />.
/// </summary>
public static bool IsInverted(RotationAngle rotationAngle)
{
return rotationAngle == RotationAngle.Rotation90 || rotationAngle == RotationAngle.Rotation270;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 1bd1bbb8c8056065c940c7d9d211b3d2
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: