OpenCV笔记(二十)——Affine Transformations仿射变换

仿射变换的作用是将图像做旋转、拉伸。

仿射变换是通过一个中间矩阵来使源图像像素的位置变换到指定的目标图像的像素的位置,原理类似于上文的remapping。

所以仿射变换也是矩阵的一种运用。

于是仿射变换一般分成两步:第一、寻找变换的中间矩阵;第二、进行变换。

要找到变换的中间矩阵,一般使用三个点来寻找它,因为用三角形我们可以表现出变换的尺度和角度。在OpenCV中,我们使用getAffineTransform。

进行变换时,我们使用warpAffine函数。

Mat getAffineTransform(InputArray src, InputArray dst)

src和dst使用Point2f是数组(大小为3)即可。

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

这里的M就是上面getAffineTransform得到的返回值。

dsize是输出的尺寸,取dst的尺寸就行。

另外,可以使用getRotationMatrix2D来得到M。

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

center为旋转之后的图像的中心

angle为旋转的角度,正为逆时针,负为顺时针。

scale为缩放的因子,比如可以为0.5

OpenCV当中的例子:

 1 /**
 2  * @function Geometric_Transforms_Demo.cpp
 3  * @brief Demo code for Geometric Transforms
 4  * @author OpenCV team
 5  */
 6
 7 #include "opencv2/highgui/highgui.hpp"
 8 #include "opencv2/imgproc/imgproc.hpp"
 9 #include <iostream>
10 #include <stdio.h>
11
12 using namespace cv;
13 using namespace std;
14
15 /// Global variables
16 const char* source_window = "Source image";
17 const char* warp_window = "Warp";
18 const char* warp_rotate_window = "Warp + Rotate";
19
20 /**
21  * @function main
22  */
23 int main( int, char** argv )
24 {
25   Point2f srcTri[3];
26   Point2f dstTri[3];
27
28   Mat rot_mat( 2, 3, CV_32FC1 );
29   Mat warp_mat( 2, 3, CV_32FC1 );
30   Mat src, warp_dst, warp_rotate_dst;
31
32   /// Load the image
33   src = imread( argv[1], 1 );
34
35   /// Set the dst image the same type and size as src
36   warp_dst = Mat::zeros( src.rows, src.cols, src.type() );
37
38   /// Set your 3 points to calculate the  Affine Transform
39   srcTri[0] = Point2f( 0,0 );
40   srcTri[1] = Point2f( src.cols - 1.f, 0 );
41   srcTri[2] = Point2f( 0, src.rows - 1.f );
42
43   dstTri[0] = Point2f( src.cols*0.0f, src.rows*0.33f );
44   dstTri[1] = Point2f( src.cols*0.85f, src.rows*0.25f );
45   dstTri[2] = Point2f( src.cols*0.15f, src.rows*0.7f );
46
47   /// Get the Affine Transform
48   warp_mat = getAffineTransform( srcTri, dstTri );
49
50   /// Apply the Affine Transform just found to the src image
51   warpAffine( src, warp_dst, warp_mat, warp_dst.size() );
52
53   /** Rotating the image after Warp */
54
55   /// Compute a rotation matrix with respect to the center of the image
56   Point center = Point( warp_dst.cols/2, warp_dst.rows/2 );
57   double angle = -50.0;
58   double scale = 0.6;
59
60   /// Get the rotation matrix with the specifications above
61   rot_mat = getRotationMatrix2D( center, angle, scale );
62
63   /// Rotate the warped image
64   warpAffine( warp_dst, warp_rotate_dst, rot_mat, warp_dst.size() );
65
66
67   /// Show what you got
68   namedWindow( source_window, WINDOW_AUTOSIZE );
69   imshow( source_window, src );
70
71   namedWindow( warp_window, WINDOW_AUTOSIZE );
72   imshow( warp_window, warp_dst );
73
74   namedWindow( warp_rotate_window, WINDOW_AUTOSIZE );
75   imshow( warp_rotate_window, warp_rotate_dst );
76
77   /// Wait until user exits the program
78   waitKey(0);
79
80   return 0;
81 }
时间: 2024-07-29 00:49:33

OpenCV笔记(二十)——Affine Transformations仿射变换的相关文章

《Programming in Lua 3》读书笔记(二十二)

日期:2014.8.6 PartⅣ The C API 26 Extending Your Application 使用Lua很重要的一点是用来做配置语言.配合主语言做一些功能的配置. 26.1 The Basics 有的时候程序需要配置一些功能信息,很多时候可能有许多别的方法比用lua做配置要更简单:如使用环境变量或者读取文件,读取文件涉及到文件的解析.如果使用Lua进行配置的话,相当于用lua文件替代了要读取的如csv.txt文件等. 使用Lua进行配置的时候,就需要使用Lua API去控制

马哥学习笔记二十四——分布式复制快设备drbd

DRBD: 主从 primary: 可执行读.写操作 secondary: 文件系统不能挂载 DRBD: dual primay, 双主(基于集群文件系统的高可用集群) 磁盘调度器:合并读请求,合并写请求: Procotol:drbd数据同步协议 A: Async, 异步  数据发送到本机tcp/ip协议栈 B:semi sync, 半同步  数据发送到对方tcp/ip协议 C:sync, 同步  数据到达对方存储设备 DRBD Source: DRBD资源 资源名称:可以是除了空白字符外的任意

【Unity 3D】学习笔记二十八:unity工具类

unity为开发者提供了很多方便开发的工具,他们都是由系统封装的一些功能和方法.比如说:实现时间的time类,获取随机数的Random.Range( )方法等等. 时间类 time类,主要用来获取当前的系统时间. using UnityEngine; using System.Collections; public class Script_04_13 : MonoBehaviour { void OnGUI() { GUILayout.Label("当前游戏时间:" + Time.t

angular学习笔记(二十八)-$http(6)-使用ngResource模块构建RESTful架构

ngResource模块是angular专门为RESTful架构而设计的一个模块,它提供了'$resource'模块,$resource模块是基于$http的一个封装.下面来看看它的详细用法 1.引入angular-resource.min.js文件 2.在模块中依赖ngResourece,在服务中注入$resource var HttpREST = angular.module('HttpREST',['ngResource']); HttpREST.factory('cardResource

Android学习笔记二十九之SwipeRefreshLayout、RecyclerView和CardView

Android学习笔记二十九之SwipeRefreshLayout.RecyclerView和CardView 前面我们介绍了AlertDialog和几个常用的Dialog,ProgressDialog进度条提示框.DatePickerDialog日期选择对话框和TimePickerDialog时间选择对话框.这一节我们介绍几个新的API控件SwipeRefreshLayout.RecyclerView和CardView,这几个API控件都是google在Android5.0推出的.下面我们来学

【Unity 3D】学习笔记二十六:unity游戏脚本(六)

在3D游戏世界中,任何一个游戏对象在创建的时候都会附带Transform(变换)组件,并且该组件是无法删除的,也不应该删除.在unity中,Transform面板一共有3个属性: Position  (位置) Rotation(旋转) Scale(缩放) 这三个值都是用来调整游戏对象在游戏界面中的位置,状态等相关参数. Position  (位置) 任何一个游戏对象的三维坐标都保存在Vector3容器中,该容器记录对象在X轴,Y轴,Z轴的坐标.一旦Vector33容器中的坐标发生变化,那么Sce

angular学习笔记(二十六)-$http(4)-设置请求超时

本篇主要讲解$http(config)的config中的timeout项: $http({ timeout: number }) 数值,从发出请求开始计算,等待的毫秒数,超过这个数还没有响应,则返回错误 demo: html: <!DOCTYPE html> <html ng-app = 'HttpGet'> <head> <title>18.4 $http(2)</title> <meta charset="utf-8"

【Unity 3D】学习笔记二十九:游戏实例——简单小地图制作

任何的学习,光看不练是学不好的.所以这次就总结回顾下怎么制作MMROPG类游戏中的小地图.在MMROPG类游戏里,主角在游戏世界里走动时,一般在屏幕右上角都会有一个区域来显示当前游戏场景的小地图.主角在游戏世界里走动,小地图里代表着主角的小标记也会随之移动.那怎么实现咧? 首先需要确定两个贴图,第一个是右上角的小地图背景贴图,应该是从Y轴俯视向下截取主角所在的位置大地图.第二个就是主角的位置大贴图.在本例中,因为没有学习unity地图制作,所以地图用一个面对象代替,主角用立方体代替,使用GUI来

swift 笔记 (二十) —— 泛型

泛型 泛型是为了解决在针对不同数据类型,而做了同一种功能的操作导致的每个类型我们都要写一份代码的问题. 有了泛型,我们可以只写一份逻辑代码,而适应于不同的数据类型. func swapInt(inout num1:Int, inout num2: Int) { var tmp = num1 num1 = num2 num2 = tmp } func swapDouble(inout num1: Double, inout num2:Double) { var tmp = num1 num1 =

Android学习笔记二十之Toast吐司、Notification通知、PopupWindow弹出窗

Android学习笔记二十之Toast吐司.Notification通知.PopupWindow弹出窗 Toast吐司 Toast吐司是我们经常用到的一个控件,Toast是AndroidOS用来显示消息的一种机制,它与Dialog不同,Toast不会获取到焦点,通常显示一段时间之后就会自动消失,下面我们来介绍Toast的几种常用方式: 第一种,默认显示方式,也是最常用的方式: Toast.makeText(MainActivity.this, "这是默认的显示方式", Toast.LE