仿射变换的基本概念

仿射变换是一种二维坐标(x, y)到二维坐标(u, v)的线性变换,其数学表达式形式如下:

对应的齐次坐标矩阵表示形式为:

仿射变换保持了二维图形的“平直性”(直线经仿射变换后依然为直线)和“平行性”(直线之间的相对位置关系保持不变,平行线经仿射变换后依然为平行线,且直线上点的位置顺序不会发生变化)。

非共线的三对对应点可以确定一个唯一的仿射变换。

几种常见的仿射变换形式:

  • 平移变换

数学形式:

矩阵形式:

  • 缩放变换

矩阵形式:

  • 旋转变换

矩阵形式:

仿射变换形式汇总图:

OpenCV 中实现仿射变换,一般涉及到 getRotationMatrix2D warpAffine 这两个函数:

计算二维旋转变换矩阵:getRotationMatrix2D 函数

Mat getRotationMatrix2D(Point2f center, double angle, double scale);

  • center,源图像的旋转中心。最终旋转中心会映射到输出图像同样位置上,即如果(0,0)是旋转中心,那么输出图像旋转中心同样是(0,0)。 
  • angle,旋转角度。角度 > 0,表示逆时针旋转(坐标原点是左上角)。
  • scale,缩放系数。

进行仿射变换:warpAffine 函数

void warpAffine(InputArray src, OutputArray dst, InputArray M, Size dsize, int flags = INTER_LINEAR, int borderMode = BORDER_CONSTANT, const Scalar& boederValue = Scalar());

  • src,输入图像,即原图像,填 Mat 类对象那个即可。
  • dst,输出图像,需要和源图像有一样的类型。
  • M,2×3 的变换矩阵。因为变换矩阵第三行形式固定,所以忽略。
  • dsize,输出图像的尺寸。
  • flags,插值的标识符。默认为 INTER_LINEAR (线性插值)。插值就是根据已知数据点(条件),来预测未知数据点值得方法。在尺寸调整过程中,图像的大小可能发生改变。此时像素与像素之间的关系就不是一一对应关系,因此在尺寸调整过程中,可能会涉及到像素值的插值计算。可选插值方式如下:

INTER_NEAREST(最近邻差值)

INTER_LINEAR(线性插值,默认)

INTER_AREA(区域插值,利用像素区域关系的重采样插值)

INTER_CUBIC(三次样条插值,超过 4×4 像素邻域内的双三次插值)

INTER_LANCZOS4(Lanczos 插值,超过 8×8 像素邻域的 Lanczos 插值)

  • borderValue ,只有当 borderMode取值为 BORDER_CONSTANT 时,这个参数才会被使用,边界会被填充成 borderValue 指定的颜色。

代码示例:

#include<opencv.hpp>
#include<iostream>
using namespace std;
using namespace cv;
int main() {
Mat src = imread("C:/Users/齐明洋/Desktop/证件照/1.jpg");
imshow("src", src);
//旋转中心为图像中心
Point center = Point(src.cols / , src.rows / );
Mat M = getRotationMatrix2D(center, , 0.2);
Mat dst;
warpAffine(src, dst, M, src.size()); circle(dst, center, , Scalar(, , ), );
imshow("dst", dst);
waitKey(); }

效果演示:

借鉴博客:https://www.cnblogs.com/shine-lee/p/10950963.html

https://www.cnblogs.com/liekkas0626/p/5238564.html

https://www.cnblogs.com/houkai/p/6660272.html

最新文章

  1. 1-Spark高级数据分析-第一章 大数据分析
  2. opendove中的odgw所需要的内核模块
  3. ecshop登陆后价格可见,会员注册登陆才能显示价格
  4. 团队博客——Sprint计划会议1
  5. ZooKeeper笔记--集群安装配置 【转】
  6. 单调队列-hdu-3415-Max Sum of Max-K-sub-sequence
  7. iOS中怎样加入自己定义的字体
  8. POJ 2155 D区段树
  9. .NET MVC4 实训记录之二(扩展WebSecurity模型下的UserProfile表)
  10. 利用xcopy命令实现本地文件复制到远程服务器的方法
  11. 介绍几个python的音频处理库
  12. Node闲谈之Buffer
  13. Centos7搭建Confluence破解版
  14. 新概念英语(1-69)The car race
  15. Transaction rolled back because it has been marked as rollback-only
  16. Calendar代替Date常用方法小记
  17. JVM 字节码(三)异常在字节码中的处理(catch 和 throws)
  18. angular 4 和django 1.11.1 前后端交互 总结
  19. css重难点笔记
  20. [转]URL汉字编码问题(及乱码解决)

热门文章

  1. php---&gt;单例模式封装mysql操作类
  2. springIOC源码接口分析(八):AutowireCapableBeanFactory
  3. 【大白话系列】MySQL 学习总结 之 初步了解 MySQL 的架构设计
  4. gulp的简单打包示例(一)
  5. Mysql 安装出现error Nr.1045
  6. css3 动画 示例
  7. 20200223--python学习第15天
  8. Effective Java, Third Edition
  9. Linux 服务器注意事项
  10. awk sed 命令