| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106 |
- using UnityEngine;
- namespace LightGlue.Unity.Networking
- {
- /// <summary>
- /// LightGlue算法结果数据类
- /// 包含相机位置、匹配质量等信息
- /// </summary>
- public struct LightGlueResult
- {
- /// <summary>
- /// 坐标映射目标类型:
- /// - GameScreen:用于 Camera.ScreenPointToRay 等“屏幕坐标”场景(左下角原点)
- /// - UIAnchored:用于 RectTransform.anchoredPosition 等 UI 场景(通常也是左下角原点,但可能需要 offset)
- /// </summary>
- public enum MappedCoordinateType
- {
- GameScreen = 0,
- UIAnchored = 1,
- }
- /// <summary>
- /// 结果是否有效(单应性矩阵计算成功且匹配点数量足够)
- /// </summary>
- public bool IsValid { get; }
- /// <summary>
- /// 匹配点数量(参考帧与当前帧之间的匹配关键点数量)
- /// </summary>
- public ushort NumMatches { get; }
- /// <summary>
- /// 内点比例(单应性矩阵计算中的内点比例,范围 0.0-1.0)
- /// </summary>
- public float InliersRatio { get; }
- /// <summary>
- /// 相机位置(在参考图像坐标系中的像素坐标,原点在左上角)
- /// </summary>
- public Vector2 CameraPosition { get; }
- /// <summary>
- /// 构造函数
- /// </summary>
- public LightGlueResult(bool isValid, ushort numMatches, float inliersRatio, float cameraX, float cameraY)
- {
- IsValid = isValid;
- NumMatches = numMatches;
- InliersRatio = inliersRatio;
- CameraPosition = new Vector2(cameraX, cameraY);
- }
- /// <summary>
- /// 创建无效结果(当算法计算失败时使用)
- /// </summary>
- public static LightGlueResult CreateInvalid(ushort numMatches = 0)
- {
- return new LightGlueResult(false, numMatches, 0.0f, 0.0f, 0.0f);
- }
- /// <summary>
- /// 将参考图像坐标(原点左上,Y向下)映射到目标坐标(原点左下,Y向上)。
- /// 用于统一 UI / Camera 的坐标转换逻辑,避免重复实现。
- /// </summary>
- /// <param name="referenceWidth">参考图宽(必须与 Python --resize 一致)</param>
- /// <param name="referenceHeight">参考图高(必须与 Python --resize 一致)</param>
- /// <param name="targetWidth">目标宽(Screen.width 或 Canvas 宽)</param>
- /// <param name="targetHeight">目标高(Screen.height 或 Canvas 高)</param>
- /// <param name="type">目标使用场景(UI / Camera)。当前两者映射规则一致,差别主要体现在 offset 用途。</param>
- /// <param name="offset">额外偏移(用于 UI anchoredPosition 的中心偏移等)。</param>
- public Vector2 GetMappedPosition(
- int referenceWidth,
- int referenceHeight,
- float targetWidth,
- float targetHeight,
- MappedCoordinateType type = MappedCoordinateType.GameScreen,
- Vector2 offset = default)
- {
- if (referenceWidth <= 0 || referenceHeight <= 0) return offset;
- if (targetWidth <= 0f || targetHeight <= 0f) return offset;
- float scaleX = targetWidth / referenceWidth;
- float scaleY = targetHeight / referenceHeight;
- float x = CameraPosition.x * scaleX;
- float y = targetHeight - (CameraPosition.y * scaleY);
- // 当前映射规则在 UI / Camera 两类场景相同;UI 额外通过 offset 适配 anchoredPosition 的坐标原点偏移
- _ = type; // 保留参数,便于未来扩展不同映射策略
- return new Vector2(x + offset.x, y + offset.y);
- }
- public override string ToString()
- {
- if (IsValid)
- {
- return $"LightGlueResult(Valid, Matches={NumMatches}, Inliers={InliersRatio:P1}, Pos=({CameraPosition.x:F1}, {CameraPosition.y:F1}))";
- }
- else
- {
- return $"LightGlueResult(Invalid, Matches={NumMatches})";
- }
- }
- }
- }
|