转自 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. Gitlab上如何给指定人员在指定项目里设置指定权限,给项目设置保护

    一.在Gitlab页面里,点击Project,找到指定的Project里: 二.点击Members,可以添加人员,并给指定的人员设置权限 三.点击Protected Branches,可以给Proje ...

  2. GridView的简单使用

    测试代码: activity_main.xml: <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/a ...

  3. C#中的索引器的简单理解和用法

    索引器是一种特殊的类成员,它能够让对象以类似数组的方式来存取,使程序看起来更为直观,更容易编写. 1.索引器的定义 C#中的类成员可以是任意类型,包括数组和集合.当一个类包含了数组和集合成员时,索引器 ...

  4. 剑指offer--13.二进制中1的个数

    就是猜测试数据没有负数,哈哈 ----------------------------------------------------------------- 时间限制:1秒 空间限制:32768K ...

  5. fiddler抓包

    1.fiddler安装 下载exe安装文件,傻瓜式安装 2.fiddler配置 点击Tools -->Telerik Fiddler Options -->Https,进入以下对话框 Ht ...

  6. Linux-CentOS7 安装VMware Workstation 12

    转自:http://blog.csdn.net/aoshilang2249/article/details/48656107 1.下载VMware 衔接地址 http://www.vmware.com ...

  7. JavaScript 中事件绑定的三种方式

    以下是在 JS 中事件绑定的三种方式.   1. HTML onclick attribute     <button type="button" id="uplo ...

  8. 机器学习:集成学习(集成学习思想、scikit-learn 中的集成分类器)

    一.集成学习的思想 集成学习的思路:一个问题(如分类问题),让多种算法参与预测(如下图中的算法都可以解决分类问题),在多个预测结果中,选择出现最多的预测类别做为该样本的最终预测类别: 生活中的集成思维 ...

  9. codeforce 103B Cthulhu

    B. Cthulhu time limit per test 2 seconds memory limit per test 256 megabytes input standard input ou ...

  10. 开发环境入门 linux基础 基本操作命令(部分) 文本结构和基本命令

    文本结构和基本命令 linux系统中系统提示符:$ 表示普通用户 su  root切换用户命令(用户名 root),输入密码,切换到其他用户状态 root 命令提示符:# exit 退出当前用户,返回 ...