参考资料
练习题 icon lost
交流讨论
笔记
img lost

OpenCV中的仿射变换

仿射变换:一个任意的仿射变换都能表示为 乘以一个矩阵 (线性变换) 接着再 加上一个向量 (平移).
通常一个图像有三种变换:
1、旋转
2、平移
3、缩放
通常用2X3的矩阵来表示一个仿射变换:

变 换 矩 阵 A = [ a 11 a 12 a 21 a 22 ] 变换矩阵A=\begin{bmatrix}a_{11}&a_{12}\\a_{21}&a_{22}\end{bmatrix} A=[a11a21a12a22]
平 移 变 化 M = [ t x t y ] 平移变化M=\begin{bmatrix} t_x\\t_y \end{bmatrix} M=[txty]
通常将两个变换合为一个: 仿 射 变 换 矩 阵 T = [ a 11 a 12 t x a 21 a 22 t y ] 仿射变换矩阵T=\begin{bmatrix}a_{11}&a_{12}&t_x\\a_{21}&a_{22}&{t_y} \end{bmatrix} 仿T=[a11a21a12a22txty]
假设原坐标为 ( x 原 , y 原 ) (x_原,y_原) (x,y)经过仿射变换:
[ x 新 y 新 ] = [ a 11 a 12 a 21 a 22 ] ∗ [ x 原 y 原 ] + [ t x t y ] \begin{bmatrix}x_新\\y_新 \end{bmatrix}=\begin{bmatrix} a_{11}&a_{12}\\a_{21}&a_{22}\end{bmatrix}*\begin{bmatrix}x_原\\y_原 \end{bmatrix}+\begin{bmatrix}t_x\\t_y \end{bmatrix} [xy]=[a11a21a12a22][xy]+[txty]
以上为仿射变换的分步。
直接使用仿射变换矩阵T:
[ x 新 y 新 ] = [ a 11 a 12 t x a 21 a 22 t y ] ∗ [ x 原 y 原 1 ] \begin{bmatrix} x_新\\y_新\end{bmatrix}=\begin{bmatrix}a_{11}&a_{12}&t_x\\a_{21}&a_{22}&{t_y} \end{bmatrix}*\begin{bmatrix}x_原\\y_原\\1\end{bmatrix} [xy]=[a11a21a12a22txty]xy1

下面是几个函数的API:
利用变换前的点和变换后的点求出仿射变换矩阵:

getAffineTransform(
	原图像的点的集合,
	变换后的图像的点的集合
);

利用旋转角度和缩放比例来求出仿射变换矩阵:

getRotationMatrix2D(
	中心点,
	旋转角度,
	缩放比例
);

最后根据仿射变换矩阵对图像进行操作:

warpAffine(
	输入图像,
	输出图像,
	仿射变换矩阵,
	原图像.size()
);
#include "opencv2/opencv.hpp"
#include <iostream>


using namespace std;
using namespace cv;

int main()
{
    Mat test = Mat::zeros(500,500,CV_8UC3);
    imshow("test",test);
    Point2f p[3];
    Point2f q[3];
    p[0] = Point2f(200,300);
    p[1] = Point2f(400,100);
    p[2] = Point2f(70,80);
    line(test,p[0],p[1],Scalar(255,255,255),3,8);
    line(test,p[0],p[2],Scalar(255,255,255),3,8);
    line(test,p[2],p[1],Scalar(255,255,255),3,8);
    q[0] = Point2f(300,300);
    q[1] = Point2f(500,100);
    q[2] = Point2f(170,80);
    line(test,q[0],q[1],Scalar(255,255,255),3,8);
    line(test,q[0],q[2],Scalar(255,255,255),3,8);
    line(test,q[2],q[1],Scalar(255,255,255),3,8);
    Mat tr = getAffineTransform(p,q);
    cout << tr << endl;
    imshow("test",test);
    Mat src = imread("/home/dynamicw/Project/C++_Project/opencvtest/src/lesson01/source/map.png");
    Mat dst;
    Point center = Point(src.cols/2,src.rows/2);
    double angle = -50.0;
    double scale = 0.6;
    tr = getRotationMatrix2D(center,angle,scale);
    warpAffine(src,dst,tr,src.size());
    imshow("dst",dst);
    waitKey(0);
    return 0;
}
资料来源 OpenCV中的仿射变换
博客作者 qq_25105061
前往答题
我的笔记