算法: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′]=[M00M10M01M11M02M12]⋅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 边界填充模式
当像素变换后坐标超出原图宽高范围时,用哪种方式填充空白区域:
Constant(默认):固定纯色填充,配合第 7 个参数borderValue设置颜色(你的黑色背景就是这个)Replicate:复制图像最边缘像素向外延展,不会出现黑边,适合图像配准场景Wrap:循环平铺图像,类似壁纸重复Reflect:镜像反射填充Reflect101:镜像填充(边缘像素只镜像一次,最常用的无黑边填充)
7. Scalar borderValue
- 仅在
borderMode = BorderTypes.Constant时生效 - 边界填充的颜色:
- 灰度图:
Scalar.Black/Scalar.White - BGR 彩色图:
new Scalar(0,0,0)黑色、new Scalar(255,255,255)白色
- 灰度图:
底层坐标计算公式
对原图每个像素 (x,y):
xnewynew=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;
}
若文章对您有帮助,可以激励一下我哦,祝您平安幸福!
| 微信 | 支付宝 |
|---|---|
![]() |
![]() |

