diff --git a/XP.ImageProcessing.Core/Alignment/AlignmentRecipe.cs b/XP.ImageProcessing.Core/Alignment/AlignmentRecipe.cs
new file mode 100644
index 0000000..ff33afb
--- /dev/null
+++ b/XP.ImageProcessing.Core/Alignment/AlignmentRecipe.cs
@@ -0,0 +1,21 @@
+namespace XP.ImageProcessing.Core.Alignment;
+
+///
+/// 示教阶段保存的对齐配方:基准位姿 + 示教图像素坐标下的检测 ROI。
+///
+public sealed class AlignmentRecipe
+{
+ /// 示教图上的基准位姿(建议示教图自匹配得到,或与模板 ROI 中心 + 角度 0 一致)。
+ public Pose2D ReferencePose { get; set; }
+
+ /// 示教图上的 ROI 多边形顶点(至少 3 点)。
+ public List RoiPoints { get; set; } = new();
+
+ /// 将示教 ROI 变换到运行图坐标。
+ public Point2D[] TransformRoi(Pose2D measuredPose)
+ => RoiAlignment.TransformPolygon(RoiPoints, ReferencePose, measuredPose);
+
+ /// 变换为整型顶点,供检测算子注入。
+ public (int X, int Y)[] TransformRoiToInt(Pose2D measuredPose)
+ => RoiAlignment.TransformPolygonToInt(RoiPoints, ReferencePose, measuredPose);
+}
diff --git a/XP.ImageProcessing.Core/Alignment/Point2D.cs b/XP.ImageProcessing.Core/Alignment/Point2D.cs
new file mode 100644
index 0000000..26d1bb1
--- /dev/null
+++ b/XP.ImageProcessing.Core/Alignment/Point2D.cs
@@ -0,0 +1,4 @@
+namespace XP.ImageProcessing.Core.Alignment;
+
+/// 图像像素平面上的点(与 WPF/Emgu 解耦)。
+public readonly record struct Point2D(double X, double Y);
diff --git a/XP.ImageProcessing.Core/Alignment/Pose2D.cs b/XP.ImageProcessing.Core/Alignment/Pose2D.cs
new file mode 100644
index 0000000..5a80ae0
--- /dev/null
+++ b/XP.ImageProcessing.Core/Alignment/Pose2D.cs
@@ -0,0 +1,18 @@
+namespace XP.ImageProcessing.Core.Alignment;
+
+///
+/// 图像平面上的刚体位姿:绕 / 旋转 (度)。
+/// 与 TemplateMatchLib 的 CenterX/CenterY/Angle 约定一致。
+///
+public readonly record struct Pose2D(double X, double Y, double AngleDegrees)
+{
+ /// 示教/标准姿态(角度 0,中心由调用方指定)。
+ public static Pose2D IdentityAt(double x, double y) => new(x, y, 0);
+
+ ///
+ /// 由模板学习 ROI 矩形估计示教位姿中心(pattern 几何中心),角度默认 0。
+ /// 更稳妥的做法是在示教图上自匹配得到 。
+ ///
+ public static Pose2D FromTemplateRoiCenter(int roiX, int roiY, int roiWidth, int roiHeight, double angleDegrees = 0)
+ => new(roiX + roiWidth * 0.5, roiY + roiHeight * 0.5, angleDegrees);
+}
diff --git a/XP.ImageProcessing.Core/Alignment/RoiAlignment.cs b/XP.ImageProcessing.Core/Alignment/RoiAlignment.cs
new file mode 100644
index 0000000..2770573
--- /dev/null
+++ b/XP.ImageProcessing.Core/Alignment/RoiAlignment.cs
@@ -0,0 +1,96 @@
+namespace XP.ImageProcessing.Core.Alignment;
+
+///
+/// 将示教图(模板坐标系)上的 ROI 点变换到运行图坐标。
+/// 旋转中心与模板匹配一致:绕 /(pattern 中心)。
+///
+public static class RoiAlignment
+{
+ ///
+ /// 刚体变换:示教图点 → 运行图点。
+ /// :示教图上的基准位姿;
+ /// :运行图匹配位姿。
+ ///
+ public static Point2D TransformPoint(Point2D point, Pose2D reference, Pose2D measured)
+ {
+ double dTheta = DegreesToRadians(measured.AngleDegrees - reference.AngleDegrees);
+ double cos = Math.Cos(dTheta);
+ double sin = Math.Sin(dTheta);
+ double dx = point.X - reference.X;
+ double dy = point.Y - reference.Y;
+ return new Point2D(
+ measured.X + cos * dx - sin * dy,
+ measured.Y + sin * dx + cos * dy);
+ }
+
+ public static Point2D TransformPoint(double x, double y, Pose2D reference, Pose2D measured)
+ => TransformPoint(new Point2D(x, y), reference, measured);
+
+ /// 变换多边形顶点(顺序不变)。
+ public static Point2D[] TransformPolygon(IReadOnlyList templatePoints, Pose2D reference, Pose2D measured)
+ {
+ if (templatePoints == null || templatePoints.Count == 0)
+ return Array.Empty();
+
+ var result = new Point2D[templatePoints.Count];
+ for (int i = 0; i < templatePoints.Count; i++)
+ result[i] = TransformPoint(templatePoints[i], reference, measured);
+ return result;
+ }
+
+ /// 变换后四舍五入为整型顶点,供 BGA 等算子 PolyX/PolyY 注入。
+ public static (int X, int Y)[] TransformPolygonToInt(
+ IReadOnlyList templatePoints,
+ Pose2D reference,
+ Pose2D measured)
+ {
+ var transformed = TransformPolygon(templatePoints, reference, measured);
+ var result = new (int X, int Y)[transformed.Length];
+ for (int i = 0; i < transformed.Length; i++)
+ {
+ result[i] = (
+ (int)Math.Round(transformed[i].X, MidpointRounding.AwayFromZero),
+ (int)Math.Round(transformed[i].Y, MidpointRounding.AwayFromZero));
+ }
+
+ return result;
+ }
+
+ /// 变换轴对齐矩形为四个顶点(左上、右上、右下、左下)。
+ public static Point2D[] TransformRect(double x, double y, double width, double height, Pose2D reference, Pose2D measured)
+ {
+ var corners = new[]
+ {
+ new Point2D(x, y),
+ new Point2D(x + width, y),
+ new Point2D(x + width, y + height),
+ new Point2D(x, y + height)
+ };
+ return TransformPolygon(corners, reference, measured);
+ }
+
+ ///
+ /// 校验匹配结果四角质心是否与 Center 一致(用于确认库的中心/角度约定)。
+ ///
+ public static bool IsMatchCenterConsistentWithCorners(
+ double centerX,
+ double centerY,
+ double ltX,
+ double ltY,
+ double rtX,
+ double rtY,
+ double rbX,
+ double rbY,
+ double lbX,
+ double lbY,
+ double tolerancePixels = 1.0)
+ {
+ double cx = (ltX + rtX + rbX + lbX) * 0.25;
+ double cy = (ltY + rtY + rbY + lbY) * 0.25;
+ double dx = cx - centerX;
+ double dy = cy - centerY;
+ return dx * dx + dy * dy <= tolerancePixels * tolerancePixels;
+ }
+
+ private static double DegreesToRadians(double degrees) => degrees * (Math.PI / 180.0);
+}
diff --git a/XP.ImageProcessing.Processors/定位识别/TemplateMatchAlignmentExtensions.cs b/XP.ImageProcessing.Processors/定位识别/TemplateMatchAlignmentExtensions.cs
new file mode 100644
index 0000000..873650f
--- /dev/null
+++ b/XP.ImageProcessing.Processors/定位识别/TemplateMatchAlignmentExtensions.cs
@@ -0,0 +1,27 @@
+using XP.ImageProcessing.Core.Alignment;
+
+namespace XP.ImageProcessing.Processors;
+
+///
+/// 将 TemplateMatchLib 匹配结果转换为对齐工具使用的 。
+///
+public static class TemplateMatchAlignmentExtensions
+{
+ public static Pose2D ToPose2D(this TM_Result result)
+ => new(result.CenterX, result.CenterY, result.Angle);
+
+ /// 四角质心是否与 Center 一致(容差默认 1 像素)。
+ public static bool IsCenterConsistentWithCorners(this TM_Result result, double tolerancePixels = 1.0)
+ => RoiAlignment.IsMatchCenterConsistentWithCorners(
+ result.CenterX,
+ result.CenterY,
+ result.LtX,
+ result.LtY,
+ result.RtX,
+ result.RtY,
+ result.RbX,
+ result.RbY,
+ result.LbX,
+ result.LbY,
+ tolerancePixels);
+}