OpenCV实现仿射变换
OpenCV实现仿射变换涉及两个主要函数——gerRotationMatrix2D和warpAffine,前者可以根据旋转角度,缩放因子等获得旋转矩阵,后者可以根据已知的变换矩阵实现一些简单的重映射。
cv::getRotationMatrix2D函数
函数原型1
2
3
4
5cv::Mat cv::getRotationMatrix2D(
Point2f center,
double angle,
double scale
)
- center: 原图像的旋转中心
- angle: 图像旋转角度,正逆负顺
- scale: 缩放系数
cv::warpAffine函数
函数原型1
2
3
4
5
6
7
8
9void cv::warpAffine(
InputArray src,
OutputArray dst,
InputArray M,
Size dsize,
int flags = INTER_LINEAR,
int borderMode = BORDER_CONSTANT,
const Scalar& borderValue = Scalar()
)
- src: 输入图像
- dst: 输出图像
- M: 2$\times$3的变换矩阵
- dsize: 图像输出尺寸
- flags: 插值算法标识符,默认值为INTER_LINEAR,常用插值算法如下
- INTER_NEAREST: 最临近插值算法
- INTER_LINEAR: 线性插值算法
- INTER_CUBIC: 双立方插值算法
- INTER_AREA: 区域插值算法(使用像素区域关系的重采样时图像抽取的首选方法,但是当图像被放大,它类似于INTER_NEAREST方法)
- INTER_LANCZOS4: Lanczos插值(超过8$\times$8邻域的插值算法
- INTER_MAX: 用于插值的掩模版
- WARP_FILL_OUTLIERS: 标志位,用于填充目标图像的像素值,如果其中的一些值对应于原图像中的异常值,那么这些值将被设置为0
- WARP_INVERSE_MAP: 标志位,反变换
- borderMode: 边界像素模式,默认值为BORDER_CONSTANT
- borderValue: 边界取值,有默认值为Scalar(),即为0
图像翻转 - cv::flip(InputArray src, OutputArray dst, int flipCode)
- src: 输入矩阵
- dst: 翻转后矩阵,类型与src一致
- flipCode: 翻转模式,flipCode==0垂直翻转(沿X轴翻转),flipCode>0水平翻转(沿Y轴翻转),flipCode<0水平垂直翻转(先沿X轴翻转,再沿Y轴翻转,等价于旋转180°)
cv::Mat重载运算符operate()
函数原型1
2
3
4inline Mat Mat::operator()( Range _rowRange, Range _colRange ) const
{
return Mat(*this, _rowRange, _colRange);
}
除了分别传入行列的范围外,还可以直接传入cv::Rect
类来截取图像中的指定区域。1
2
3
4
5cv::Mat img, target_img;
cv::Point2f center;
int width, height;
cv::Rect target = cv::Rect(center.x, center.y, width, height);
target_img = img(target);
如何截取旋转矩形内的图像
由于旋转矩形不是常规矩形(与轴平行),所以首先要将图像作旋转变化,旋转中心即为旋转矩形中心,使得旋转矩形内部的图像在窗口中是与坐标轴平行的,然后从旋转矩阵得到一般矩阵,通过cv::Mat
的重载运算符operate()
得到局部图像。
1 | //const cv::Mat &image, const cv::RotatedRect &rect |
其中用到的函数是用来保证target
矩形是正常的,否则可能会报错。
1 | bool makeRectSafe(cv::Rect & rect, cv::Size size) { |