官方教程
那么: M = [ a 11 a 12 b 11 a 21 a 22 b 21 ] M=\left[ \begin{matrix} a_{11}& a_{12} & b_{11}\\ a_{21} & a_{22} & b_{21}\\ \end{matrix} \right] M=[a11a21a12a22b11b21]
假如使用A、B转换一个图像 X = [ x y ] X=\left[ \begin{matrix} x\\ y\\ \end{matrix} \right] X=[xy]: 目标图像: T = A T=A T=A* [ x y ] + B \left[ \begin{matrix} x\\ y\\ \end{matrix} \right]+B [xy]+B ,或者直接等于: M ∗ [ x y 1 ] = [ a 11 x + a 12 y + b 11 a 21 x + a 22 y + b 21 ] M*\left[ \begin{matrix} x\\ y\\ 1\\ \end{matrix} \right]=\left[ \begin{matrix} a_{11}x+a_{12}y+b_{11}\\ a_{21}x + a_{22}y+b_{21}\\ \end{matrix} \right] M∗⎣⎡xy1⎦⎤=[a11x+a12y+b11a21x+a22y+b21]
对于每个点,都有两个对应的等式,一共有3个点,6个等式;对应 M M M里面的6个参数,所以可以得到唯一的仿射矩阵 M M M
#include
#include
using namespace cv;
using namespace std;
int main(void)
{
Mat src = imread("../res/lena.jpeg", cv::IMREAD_COLOR);
if(src.empty())
{
cout << "cant't load image" << endl;
}
//原图三个点
Point2f srcTri[3];
srcTri[0]=Point2f(0.f,0.f);
srcTri[1]=Point2f(src.cols-1.f,0.f);
srcTri[2]=Point2f(0.f,src.rows-1.f);
//目的图的三个点
Point2f dstTri[3];
dstTri[0]=Point2f(0.f,src.rows*0.33f);
dstTri[1]=Point2f(src.cols*0.85f,src.rows*0.25f);
dstTri[2]=Point2f(src.cols*0.15f,src.rows*0.7f);
//得到仿射矩阵
Mat warp_mat = getAffineTransform(srcTri,dstTri);
//通过仿射矩阵得到目的图像
Mat warp_dst = Mat::zeros(src.rows,src.cols,src.type());
warpAffine(src,warp_dst,warp_mat,warp_dst.size());
///旋转///
Point center = Point(warp_dst.cols/2,warp_dst.rows/2); //定义旋转中心
double angle = -50.0; //旋转角度,负数代表顺时针,单位度
double scale = 1; //缩放比例
Mat rot_mat = getRotationMatrix2D(center,angle,scale); //由上面三个参数得到旋转矩阵
Mat warp_rotate_dst;
warpAffine(warp_dst,warp_rotate_dst,rot_mat,warp_dst.size()); //进行旋转操作
imshow("source image" ,src);
imshow("warp", warp_dst);
imshow("warp+rotate",warp_rotate_dst);
waitKey();
return 0;
};
结果:第一张原图,第二张经过仿射变换之后,第三张再经过顺时针旋转50 ° \degree °的结果
Mat cv::getAffineTransform
(
const Point2f src[], // 原图像的三个顶点
const Point2f dst[] //目的图像的三个顶点
)
void cv::warpAffine void cv::warpAffine
(
InputArray src, // 原图
OutputArray dst, // 目的图,大小是dsize,和原图类型一样
InputArray M, // 2×3 的仿射变换矩阵
Size dsize, // 输出图像大小
int flags = INTER_LINEAR, // 插值方式
int borderMode = BORDER_CONSTANT, // 边界处理方式
const Scalar & borderValue = Scalar() // 如果是CONSTANT型border,此参数是边界的值
)
计算公式:
Mat cv::getRotationMatrix2D
(
Point2f center, //旋转中心
double angle, // 旋转角度(单位: ° \degree °),正数 意味着逆时针
double scale //放大、缩小的比例
)