转自 http://www.cnblogs.com/dupuleng/articles/4055020.html

随笔- 1  文章- 185  评论- 14 

仿射变换详解 warpAffine

 

今天遇到一个问题是关于仿射变换的,但是由于没有将仿射变换的具体原理型明白,看别人的代码看的很费解,最后终于在师兄的帮助下将原理弄明白了,我觉得最重要的是理解仿射变换可以看成是几种简单变换的复合实现,

具体实现形式即将几种简单变换的变换矩阵M相乘,这样就很容易理解啦


定义:仿射变换的功能是从二维坐标到二维坐标之间的线性变换,且保持二维图形的“平直性”和“平行性”。仿射变换可以通过一系列的原子变换的复合来实现,包括平移,缩放,翻转,旋转和剪切。

这类变换可以用一个3*3的矩阵M来表示,其最后一行为(0,0,1)。该变换矩阵将原坐标为(x,y)变换为新坐标(x',y'),

opencv中相应的函数是:

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

Parameters:

  • src – input image.
  • dst – output image that has the size dsize and the same type as src .
  • M –  transformation matrix,最重要的东东了,本文中着重讲M的构造
  • dsize – size of the output image.
  • flags – combination of interpolation methods (see resize() ) and the optional flag WARP_INVERSE_MAP that means that M is the inverse transformation (  ).
  • borderMode – pixel extrapolation method (see borderInterpolate()); when borderMode=BORDER_TRANSPARENT , it means that the pixels in the destination image corresponding to the “outliers” in the source image are not modified by the function.
  • borderValue – value used in case of a constant border; by default, it is 0.

下面介绍一些典型的仿射变换:

(1)平移,将每一点移到到(x+t , y+t),变换矩阵为

(2)缩放变换  将每一点的横坐标放大或缩小sx倍,纵坐标放大(缩小)到sy倍,变换矩阵为

(3)旋转变换原点:目标图形围绕原点顺时针旋转Θ 弧度,变换矩阵为

(4) 旋转变换  :目标图形以(x , y )为轴心顺时针旋转θ弧度,变换矩阵为

相当于两次平移与一次原点旋转变换的复合,即先将轴心(x,y)移到到原点,然后做旋转变换,最后将图片的左上角置为图片的原点,即

有的人可能会说为什么这么复杂呢,那是因为在opencv的图像处理中,所有对图像的处理都是从原点进行的,而图像的原点默认为图像的左上角,而我们对图像作旋转处理时一般以图像的中点为轴心,因此就需要做如下处理

如果你觉得这样很麻烦,可以使用opencv中自带的Mat getRotationMatrix2D(Point2f center, double angle, double scale)函数获得变换矩阵M,

  center:旋转中心

  angle:旋转弧度,一定要将角度转换成弧度

  scale:缩放尺度

它得到的矩阵是:

其中α = scale * cos( angle ) , β = scale  * sing( angle )  , ( center.x , center.y ) 表示旋转轴心

但是不得不说opencv的文档以及相关书籍中都把这个矩阵写错了,如下:

建议大家自己通过下式验证一下,即首先将轴心(x,y)移到原点,然后做旋转平绽放变换,最后再将图像的左上角转换为原点

没有去研究该函数的源码,不晓得源码中到底怎么写的,但是在别人的博客中看到这个函数貌似需要修正


opencv中还有一个函数:Mat getAffineTransform(InputArray src, InputArray dst)

 它通过三组点对就可以获得它们之间的仿射变换,如果我们在一组图像变换中知道变换后的三组点,那么我们就可以利用该函数求得变换矩阵,然后对整张图片进行仿射变换

还有一种与仿射变换经常混淆的变换为透视变换,透视变换需要四组点对才能确定变换矩阵,由于仿射变换保持“平直性”与“平行性”,因此只需要三组点对,而透视变换没有这种约束,故需要四组点对

 
分类: opencv

仿射变换详解 warpAffine的更多相关文章

  1. EasyPR--开发详解

    我正在做一个开源的中文车牌识别系统,Git地址为:https://github.com/liuruoze/EasyPR. 我给它取的名字为EasyPR,也就是Easy to do Plate Reco ...

  2. SIFT算法详解(转)

    http://blog.csdn.net/zddblog/article/details/7521424 目录(?)[-] 尺度不变特征变换匹配算法详解 Scale Invariant Feature ...

  3. 【转】 SIFT算法详解

    尺度不变特征变换匹配算法详解Scale Invariant Feature Transform(SIFT)Just For Fun zdd  zddmail@gmail.com 对于初学者,从Davi ...

  4. 【好程序员笔记分享】——UIView与CALayer详解

    -iOS培训,iOS学习-------型技术博客.期待与您交流!------------ UIView与CALayer详解 研究Core Animation已经有段时间了,关于Core Animati ...

  5. 高斯消元法(Gauss Elimination)【超详解&模板】

    高斯消元法,是线性代数中的一个算法,可用来求解线性方程组,并可以求出矩阵的秩,以及求出可逆方阵的逆矩阵.高斯消元法的原理是:若用初等行变换将增广矩阵 化为 ,则AX = B与CX = D是同解方程组. ...

  6. SIFT算法详解

    尺度不变特征变换匹配算法详解Scale Invariant Feature Transform(SIFT)Just For Fun zdd  zddmail@gmail.com or (zddhub@ ...

  7. 转:sift算法详解

    转自:http://blog.csdn.net/pi9nc/article/details/23302075 对于初学者,从David G.Lowe的论文到实现,有许多鸿沟,本文帮你跨越. 1.SIF ...

  8. SIFT算法详解(转)

    原文地址 http://blog.csdn.net/pi9nc/article/details/23302075 尺度不变特征变换匹配算法详解 Scale Invariant Feature Tran ...

  9. Linq之旅:Linq入门详解(Linq to Objects)

    示例代码下载:Linq之旅:Linq入门详解(Linq to Objects) 本博文详细介绍 .NET 3.5 中引入的重要功能:Language Integrated Query(LINQ,语言集 ...

随机推荐

  1. 20 Python 常用模块

    collections模块 在内置数据类型(dict.list.set.tuple)的基础上,collections模块还提供了几个额外的数据类型:Counter.deque.defaultdict. ...

  2. redis_学习_02_redis 可视化工具 Redis Desktop Manager

    二.参考资料 1.Redis可视化工具Redis Desktop Manager使用 2.超好用的Redis管理及监控工具,使用后可大大提高你的工作效率!

  3. css Flex布局(一)

    网页布局(layout) 布局的传统解决方案,基于盒状模型,依赖 display属性 + position属性 + float属性.它对于那些特殊布局非常不方便,比如,垂直居中就不容易实现. 6个属性 ...

  4. Tomcat的安装与环境配置

    首先,下载地址为:http://tomcat.apache.org/,在左侧的列表中找到Download,找到自己要下载的Tomcat的版本.我下载的是Tomcat 7. 进入后出现如上右图界面.我选 ...

  5. Long Jumps(二分查找lower_bound()函数的运用)

    Valery is a PE teacher at a school in Berland. Soon the students are going to take a test in long ju ...

  6. LeetCode Sum of Square Numbers

    原题链接在这里:https://leetcode.com/problems/sum-of-square-numbers/description/ 题目: Given a non-negative in ...

  7. 学习动态性能表(10)--v$session_longops

    学习动态性能表 第十篇--V$SESSION_LONGOPS  2007.6.7 本视图显示运行超过6秒的操作的状态.包括备份,恢复,统计信息收集,查询等等. 要监控查询执行进展状况,你必须使用cos ...

  8. BZOJ1999 树网的核[数据加强版]

    1999: [Noip2007]Core树网的核 Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 1214  Solved: 336[Submit][St ...

  9. oracle如何查看表空间

    1.用户 查看当前用户的缺省表空间 SQL>select username,default_tablespace from user_users; 查看当前用户的角色 SQL>select ...

  10. 深入理解java虚拟机 精华总结(面试)(转)

    一.运行时数据区域 3 1.1 程序计数器 3 1.2 Java虚拟机栈 3 1.3 本地方法栈 3 1.4 Java堆 3 1.5 方法区 3 1.6 运行时常量池 4 二. hotspot虚拟机对 ...