Opencv中文网

平移(WarpAffine 仿射平移)

算法:WarpAffine 仿射平移

void WarpAffine(
    Mat src,
    Mat dst,
    Mat M,
    Size dsize,
    InterpolationFlags flags = InterpolationFlags.Linear,
    BorderTypes borderMode = BorderTypes.Constant,
    Scalar borderValue = default
)

平移矩阵

[1, 0, tx]
[0, 1, ty]
  • tx:X 轴偏移
    • 范围:- 图像宽度~图像宽度
    • 正负:正数向右、负数向左
  • ty:Y 轴偏移
    • 范围:- 图像高度~图像高度
    • 正负:正数向下、负数向上

逐个参数详细说明

1. Mat src

  • 作用:输入原始图像矩阵
  • 要求:必须是已经加载、非空的有效Mat,支持单通道 / 多通道灰度图、彩色图
  • 注意:函数不会修改原图,只读取像素

2. Mat dst

  • 作用:输出变换后的图像矩阵
  • 大小由第 4 个参数dsize决定,通道数、数据类型和src保持一致
  • 使用完必须Dispose(),建议配合using防止内存泄漏

3. Mat M 【核心变换矩阵】

  • 格式强制要求2 行 3 列,数据类型必须是 CV_32F(float) / CV_64F(double)
  • 矩阵含义(仿射变换通用公式): [x′y′​]=[M00​M10​​M01​M11​​M02​M12​​]⋅​xy1​​
  • 平移场景:M00​=1,M01​=0,M02​=OffsetX; M10​=0,M11​=1,M12​=OffsetY
  • 旋转 + 平移:用GetRotationMatrix2D生成该矩阵

4. Size dsize

  • 作用:指定输出图像dst的宽、高
  • 常用写法:src.Size() → 输出尺寸和原图一致
  • 若设置更大尺寸:可以把图像平移到原图可视区域外,保留完整像素不被裁剪
  • 若设置更小尺寸:超出部分会被直接裁剪

5. InterpolationFlags flags 插值方式

图像变换后像素坐标大概率是小数,需要通过插值计算新像素值,常用枚举:

表格

枚举值说明使用场景
Linear(默认)双线性插值,平滑效果好平移、缩放、旋转绝大多数场景推荐
Nearest最近邻插值,速度最快,容易锯齿二值图像、掩码、像素标签图,追求极致性能
Cubic双三次插值,画质最细腻,计算最慢小图放大、需要高精度视觉效果
Area像素区域重采样图像缩小场景,抗锯齿效果好
Lanczos4兰索斯插值,高精度放大专业图像放大

6. BorderTypes borderMode 边界填充模式

当像素变换后坐标超出原图宽高范围时,用哪种方式填充空白区域:

  1. Constant(默认):固定纯色填充,配合第 7 个参数borderValue设置颜色(你的黑色背景就是这个)
  2. Replicate:复制图像最边缘像素向外延展,不会出现黑边,适合图像配准场景
  3. Wrap:循环平铺图像,类似壁纸重复
  4. Reflect:镜像反射填充
  5. Reflect101:镜像填充(边缘像素只镜像一次,最常用的无黑边填充)

7. Scalar borderValue

  • 仅在 borderMode = BorderTypes.Constant 时生效
  • 边界填充的颜色:
    • 灰度图:Scalar.Black / Scalar.White
    • BGR 彩色图:new Scalar(0,0,0)黑色、new Scalar(255,255,255)白色

底层坐标计算公式

对原图每个像素 (x,y):

xnew​ynew​​=M00​⋅x+M01​⋅y+M02​=M10​⋅x+M11​⋅y+M12​​​

如果 (xnew​,ynew​) 超出原图范围,就按borderMode填充边界色;否则用插值取原图像素。

public override Mat Execute(Mat src)
{
    if (src == null || src.Empty()) return new Mat();

    Mat dst = new Mat();
    // 生成平移矩阵
    Mat transMat = Cv2.GetRotationMatrix2D(new Point2f(0, 0), 0, 1);
    transMat.Set(0, 2, OffsetX);
    transMat.Set(1, 2, OffsetY);

    // 执行仿射变换
    Cv2.WarpAffine(
        src,
        dst,
        transMat,
        src.Size(),
        InterpolationFlags.Linear,
        BorderTypes.Constant,
        Scalar.Black
    );

    transMat.Dispose(); // 释放矩阵
    return dst;
}

copyright @重庆教主 WPF中文网 联系站长:(QQ)23611316 (微信)movieclip (QQ群).NET小白课堂:864486030 | 本文由WPF中文网原创发布,谢绝转载 渝ICP备2023009518号-1