OpenCV学习笔记(十五):图像仿射变换:warpAffine(),getRotationMatrix2D()

OpenCV学习笔记(十五):图像仿射变换:warpAffine(),getRotationMatrix2D()

一个任意的仿射变换都能表示为乘以一个矩阵(线性变换)接着再加上一个向量(平移)的形式。
仿射变换(Affine Transformation或 Affine Map),是指在几何中**一个向量空间进行一次线性变换并接上一个平移,变换为另一个向量空间的过程。**它保持了二维图形的==“平直性”(即:直线经过变换之后依然是直线)和“平行性”==(即:二维图形之间的相对位置关系保持不变,平行线依然是平行线,且直线上点的位置顺序不变)。
那么, 我们能够用仿射变换来表示如下三种常见的变换形式:

1)旋转,rotation (线性变换)
2)平移,translation(向量加)
3)缩放,scale(线性变换)
OpenCV学习笔记(十五):图像仿射变换:warpAffine(),getRotationMatrix2D()_第1张图片

1、warpAffine()函数

void warpAffine(
InputArray src,						// 源图像
OutputArray dst, 					// 函数调用后的运算结果
InputArray M, 						// 2×3的变换矩阵
Size dsize, 						// 表示输出图像的尺寸
int flags=INTER_LINEAR, 			// 插值方法的标识符
intborderMode=BORDER_CONSTANT, 		// 边界像素模式
const Scalar& borderValue=Scalar()	// 在恒定的边界情况下取的值
)

2、getAffineTransform()函数

计算3个二维点对之间的仿射变换矩阵H(2行x3列),自由度为6.

Mat cv::getAffineTransform(	
const Point2f 	src[],			// 源图像中三角形顶点的坐标(3点)	
const Point2f 	dst[] 			// 目标图像中三角形顶点的坐标(3点)
)

在这里插入图片描述
其中
在这里插入图片描述

2、getRotationMatrix2D()函数


Mat getRotationMatrix2D(
Point2f center,						// 表示源图像的旋转中心
double angle, 						// 旋转角度。角度为正值表示向逆时针旋转(坐标原点是左上角)
double scale, 						// 缩放系数
)

此函数计算以下矩阵
OpenCV学习笔记(十五):图像仿射变换:warpAffine(),getRotationMatrix2D()_第2张图片

1、示例一:

#include <opencv2/opencv.hpp>

using namespace cv;
using namespace std;

#define WINDOW_NAME "重映射"        //为窗口标题定义的宏

Mat g_srcImage, g_dstImage;
Mat g_map_x, g_map_y;

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);


    Mat src = imread("F:/C++/2. OPENCV 3.1.0/TEST/7.jpg");

    Mat dst_warp, dst_warpRotateScale;
    Point2f srcPoints[3];//原图中的三点
    Point2f dstPoints[3];//目标图中的三点

    //第一种仿射变换的调用方式:三点法
    //三个点对的值,只要知道变换后图的三个点坐标,就可实现仿射变换
    srcPoints[0] = Point2f(0, 0);
    srcPoints[1] = Point2f(0, src.rows - 1);
    srcPoints[2] = Point2f(src.cols - 1, 0);

    //映射后的三个坐标值
    dstPoints[0] = Point2f(0, src.rows*0.3);
    dstPoints[1] = Point2f(src.cols*0.25, src.rows*0.75);
    dstPoints[2] = Point2f(src.cols*0.75, src.rows*0.25);
    Mat M1 = getAffineTransform(srcPoints, dstPoints);//计算变换矩阵
    cout<<"M1= "<<M1<<endl;
    warpAffine(src, dst_warp, M1, src.size());//仿射变换

    //第二种仿射变换的调用方式:直接指定角度和比例
    //旋转加缩放
    Point2f center(src.cols/2, src.rows/2);//旋转中心
    //Point2f center(0, 0);//旋转中心
    double angle = 45;//逆时针旋转45度
    double scale = 0.5;//缩放比例

    Mat M2 = getRotationMatrix2D(center, angle, scale);//计算旋转加缩放的变换矩阵
    cout<<"M2= "<<M2<<endl;
    warpAffine(src, dst_warpRotateScale, M2, src.size());//仿射变换

    imshow("原始图", src);
    imshow("仿射变换1", dst_warp);
    imshow("仿射变换2", dst_warpRotateScale);

    waitKey(0);
    return a.exec();
}

OpenCV学习笔记(十五):图像仿射变换:warpAffine(),getRotationMatrix2D()_第3张图片
OpenCV学习笔记(十五):图像仿射变换:warpAffine(),getRotationMatrix2D()_第4张图片
2、示例二,旋转动画:

#include <opencv2/opencv.hpp>

using namespace cv;
using namespace std;

#define PIC_BEGIN_NUM 100  //这里定义你的起始图片编号
#define ANGLE_START 0  //旋转角度的开始
#define ANGLE_END  360  //旋转角度的结束
#define ANGLE_STEP 1 //旋转角度步长

int main()
{
    Mat srcImg = imread("F:/C++/2. OPENCV 3.1.0/TEST/7.jpg");
    imshow("source", srcImg);

    //char file[256]; // 文件写出路径
    //int count = PIC_BEGIN_NUM;
    Point center(srcImg.cols / 2, srcImg.rows / 2);     //图片中心为旋转点
    namedWindow("warpAffine",1);
    // 循环显示
    for (int tp = ANGLE_START; tp < ANGLE_END; tp += ANGLE_STEP)
    {
      Mat tpimg;
      Mat rotMatS = getRotationMatrix2D(center, tp, 0.5); //图片缩小到原来的0.5倍
      warpAffine(srcImg, tpimg, rotMatS, srcImg.size(), 1, 0, Scalar(0, 0, 0));//填充黑色背景
      imshow("warpAffine",tpimg);
      //sprintf(file, "F:/C++/2. OPENCV 3.1.0/TEST/%d.jpg", count++);  //旋转图片以1.jpg  2.jpg 的名字格式保存
      //imwrite(file, tpimg);
       waitKey(30);
    }
    waitKey(0);
    return 0;
}

OpenCV学习笔记(十五):图像仿射变换:warpAffine(),getRotationMatrix2D()_第5张图片

你可能感兴趣的:(OpenCV)