仿射变换的功能是从二维坐标到二维坐标之间的线性变换,且保持二维图形的“平直性”和“平行性”。仿射变换可以通过一系列的原子变换的复合来实现,包括平移,缩放,翻转,旋转和剪切。
图像旋转和平移是图像处理中常用的一种操作,opencv2和opencv3中对图像的旋转和平移都是通过仿射变换函数cv::warpAffine()来实现的。
void warpAffine(InputArray src, OutputArray dst, InputArray M,
Size dsize, int flags=INTER_LINEAR, int borderMode=BORDER_CONSTANT,
const Scalar& borderValue=Scalar())
InputArray src:输入的图像
OutputArray dst:输出的图像
InputArray M:透视变换的矩阵
Size dsize:输出图像的大小
int flags=INTER_LINEAR:输出图像的插值方法,
int borderMode=BORDER_CONSTANT:图像边界的处理方式
const Scalar& borderValue=Scalar():边界的颜色设置,一般默认是0
getAffineTransform函数函数作用:
主要用于生成仿射变换矩阵,它通过三组点对就可以获得它们之间的仿射变换,如果我们在一组图像变换中知道变换后的三组点,那么我们就可以利用该函数求得变换矩阵,然后对整张图片进行仿射变换
Mat getAffineTransform(InputArray src, InputArray dst)
InputArray src:表示输入的三个点
InputArray dstL:表示输出的三个点
Mat src,rotate_dst;
char* source_window = "Source image";
char* rotate_window = "Rotate";
int main( int argc, char** argv )
{
Point2f srcTri[3];
Point2f dstTri[3];
//定义一个2行3列的矩阵
Mat rot_mat( 2, 3, CV_32FC1 );
/// 加载源图像
src = imread( argv[1], 1 );
/// 设置目标图像的大小和类型与源图像一致
rotate_dst = Mat::zeros( src.rows, src.cols, src.type() );
/// 设置源图像和目标图像上的三组点以计算仿射变换
srcTri[0] = Point2f( 0,0 );
srcTri[1] = Point2f( src.cols - 1, 0 );
srcTri[2] = Point2f( 0, src.rows - 1 );
dstTri[0] = Point2f( src.cols*0.0, src.rows*0.33 );
dstTri[1] = Point2f( src.cols*0.85, src.rows*0.25 );
dstTri[2] = Point2f( src.cols*0.15, src.rows*0.7 );
/// 求得仿射变换
rot_mat = getAffineTransform( srcTri, dstTri );
/// 对源图像应用上面求得的仿射变换
warpAffine( src, rotate_dst, rot_mat, rotate_dst.size() );
double scale = 0.6;
double angle = 80;
/// 计算绕图像中点顺时针旋转80度缩放因子为0.6的旋转矩阵
Point center = Point( rotate_dst.cols/2, rotate_dst.rows/2 );
/// 通过上面的旋转细节信息求得旋转矩阵
rot_mat = getRotationMatrix2D( center, angle, scale );
warpAffine( src, rotate_dst, rot_mat, rotate_dst.size() );
/// 显示结果
imshow( source_window, src );
imshow( rotate_window, rotate_dst );