第六章 - 图像变换 - 图像拉伸、收缩、扭曲、旋转[1] - 仿射变换(cvWarpAffine)
拉伸、收缩、扭曲、旋转是图像的几何变换,在三维视觉技术中大量应用到这些变换,又分为仿射变换和透视变换。仿射变换通常用单应性建模,利用cvWarpAffine解决密集映射,用cvTransform解决稀疏映射。仿射变换可以将矩形转换成平行四边形,它可以将矩形的边压扁但必须保持边是平行的,也可以将矩形旋转或者按比例变化。透视变换提供了更大的灵活性,一个透视变换可以将矩阵转变成梯形。当然,平行四边形也是梯形,所以仿射变换是透视变换的子集。
本小节实现图像的仿射变换。
------------------------------------------------------------------------------------
以下是本例程用到的方法:
CloneImage
制作图像的完整拷贝
IplImage* cvCloneImage(
const IplImage* image );
image
原图像.
函数 cvCloneImage
制作图像的完整拷贝包括头、ROI和数据
-----------------------------
GetAffineTransform
由三对点计算仿射变换
CvMat* cvGetAffineTransform( const CvPoint2D32f* src,const
CvPoint2D32f* dst, CvMat* map_matrix );
src
输入图像的三角形顶点坐标。
dst
输出图像的相应的三角形顶点坐标。
map_matrix
指向2×3输出矩阵的指针。
函数cvGetAffineTransform计算满足以下关系的仿射变换矩阵:
这里,dst(i)=
(x'i,y'i),src(i)=
(xi,yi),i = 0..2.
-----------------------------
WarpAffine
对图像做仿射变换
void cvWarpAffine( const CvArr* src, CvArr* dst, constCvMat*
map_matrix,
int
flags=CV_INTER_LINEAR+CV_WARP_FILL_OUTLIERS,
CvScalar fillval=cvScalarAll(0) );
src
输入图像.
dst
输出图像.
map_matrix
2×3 变换矩阵
flags
插值方法和以下开关选项的组合:
· CV_WARP_FILL_OUTLIERS -
填充所有输出图像的象素。如果部分象素落在输入图像的边界外,那么它们的值设定为 fillval.
· CV_WARP_INVERSE_MAP - 指定
map_matrix是输出图像到输入图像的反变换,因此可以直接用来做象素插值。否则, 函数从 map_matrix 得到反变换。
fillval
用来填充边界外面的值
函数 cvWarpAffine 利用下面指定的矩阵变换输入图像:
- 如果没有指定 CV_WARP_INVERSE_MAP ,
- 否则,
函数与 cvGetQuadrangleSubPix 类似,但是不完全相同。cvWarpAffine
要求输入和输出图像具有同样的数据类型,有更大的资源开销(因此对小图像不太合适)而且输出图像的部分可以保留不变。而 cvGetQuadrangleSubPix
可以精确地从8位图像中提取四边形到浮点数缓存区中,具有比较小的系统开销,而且总是全部改变输出图像的内容。要变换稀疏矩阵,使用 cxcore 中的函数
cvTransform 。
-----------------------------
2DRotationMatrix |
2DRotationMatrix CvMat* [ α β | (1-α)*center.x - where |
------------------------------------------------------------------------------------
/*code*/
- #include <highgui.h>
- #include <cv.h>
- int main(int argc, char** argv)
- {
- CvPoint2D32f srcTri[3], dstTri[3]; //二维坐标下的点,类型为浮点
- CvMat* rot_mat = cvCreateMat( 2, 3, CV_32FC1 ); //多通道矩阵
- CvMat* warp_mat = cvCreateMat( 2, 3, CV_32FC1 );
- IplImage *src, *dst;
- if( argc == 2 && ( ( src = cvLoadImage( argv[1], 1 ) ) != 0 ) )
- {
- dst = cvCloneImage( src ); //制作图像的完整拷贝
- dst ->origin = src ->origin;
- /*
- int origin; /* 0 - 顶—左结构,
- 1 - 底—左结构 (Windows bitmaps 风格)
- */
- cvZero( dst ); //清空数组
- //计算矩阵仿射变换
- srcTri[0].x = 0;
- srcTri[0].y = 0;
- srcTri[1].x = src -> width - 1; //缩小一个像素
- srcTri[1].y = 0;
- srcTri[2].x = 0;
- srcTri[2].y = src -> height - 1;
- //改变目标图像大小
- dstTri[0].x = src -> width * 0.0;
- dstTri[0].y = src -> height * 0.33;
- dstTri[1].x = src -> width * 0.85;
- dstTri[1].y = src -> height * 0.25;
- dstTri[2].x = src -> width * 0.15;
- dstTri[2].y = src -> height * 0.7;
- cvGetAffineTransform( srcTri, dstTri, warp_mat ); //由三对点计算仿射变换
- cvWarpAffine( src, dst, warp_mat ); //对图像做仿射变换
- cvCopy( dst, src ); //将dst拷贝给src
- //计算旋转仿射变换
- CvPoint2D32f center = cvPoint2D32f( src -> width / 2, src -> height / 2 );
- double angle = -50.0; //旋转角度,负值表示顺时针
- double scale = 0.6; //各项同性的尺度因子
- cv2DRotationMatrix( center, angle, scale, rot_mat );
- cvWarpAffine( src, dst, rot_mat ); //将src仿射变换存入dst
- //输出
- cvNamedWindow( "Affine_Transform", 1 );
- cvShowImage( "Affine_Transform", dst ); //最终是输出dst
- cvWaitKey();
- }
- cvReleaseImage( &dst );
- cvReleaseMat( &rot_mat );
- cvReleaseMat( &warp_mat );
- return 0;
- }
第六章 - 图像变换 - 图像拉伸、收缩、扭曲、旋转[1] - 仿射变换(cvWarpAffine)的更多相关文章
- 第六章 - 图像变换 - 图像拉伸、收缩、扭曲、旋转[2] - 透视变换(cvWarpPerspective)
透视变换(单应性?)能提供更大的灵活性,但是一个透视投影并不是线性变换,因此所采用的映射矩阵是3*3,且控点变为4个,其他方面与仿射变换完全类似,下面的例程是针对密集变换,稀疏图像变换则采用cvPer ...
- 第五、六章:图像&链接
图像有很多存储格式:JPEG.png.gif等,它们的文件大小也不同,使用的图片类型对于页面响应速度有不同的要求.下面就会简单阐述不同的格式的图片的特点. 1.JPEG格式 JPEG格式适用于彩色照片 ...
- o'Reill的SVG精髓(第二版)学习笔记——第六章
第六章:坐标系统变换 想要旋转.缩放或者移动图片到新的位置.可以给对应的SVG元素添加transform属性. 6.1 translate变换 可以为<use>元素使用x和y属性,以在特性 ...
- OpenCV2:第六章 图像几何变换
一.简介 图像的几何变换有距离变换 坐标映射 平移 镜像 旋转 缩放 仿射变换等 二.重映射 把一张图像重新排列像素,比如倒置 CV_EXPORTS_W void remap( InputArr ...
- Android群英传笔记——第六章:Android绘图机制与处理技巧
Android群英传笔记--第六章:Android绘图机制与处理技巧 一直在情调,时间都是可以自己调节的,不然世界上哪有这么多牛X的人 今天就开始读第六章了,算日子也刚好一个月了,一个月就读一半,这效 ...
- 精通Web Analytics 2.0 (8) 第六章:使用定性数据解答”为什么“的谜团
精通Web Analytics 2.0 : 用户中心科学与在线统计艺术 第六章:使用定性数据解答"为什么"的谜团 当我走进一家超市,我不希望员工会认出我或重新为我布置商店. 然而, ...
- Laxcus大数据管理系统2.0(8)- 第六章 网络通信
第六章 网络通信 Laxcus大数据管理系统网络建立在TCP/IP网络之上,从2.0版本开始,同时支持IPv4和IPv6两种网络地址.网络通信是Laxcus体系里最基础和重要的一环,为了能够利用有限的 ...
- 第六章 Qt布局管理器Layout
第六章 Qt布局管理器Layout 大家有没有发现一个现象,我们放置一个组件,给组件最原始的定位是给出这个控件的坐标和宽高值,这样Qt就知道这个组件的位置.当用户改变窗口的大小,组件还静静地呆在原来的 ...
- Android群英传》读书笔记 (3) 第六章 Android绘图机制与处理技巧 + 第七章 Android动画机制与使用技巧
第六章 Android绘图机制与处理技巧 1.屏幕尺寸信息屏幕大小:屏幕对角线长度,单位“寸”:分辨率:手机屏幕像素点个数,例如720x1280分辨率:PPI(Pixels Per Inch):即DP ...
随机推荐
- P2320 [HNOI2006]鬼谷子的钱袋
洛谷2320 06湖南 鬼谷子的钱袋 来源 题目描述 鬼谷子非常聪明,正因为这样,他非常繁忙,经常有各诸侯车的特派员前来向他咨询时政.有一天,他在咸阳游历的时候,朋友告诉他在咸阳最大的拍卖行(聚宝商行 ...
- URAL 1915 Titan Ruins: Reconstruction of Bygones(思路)
搞这个题差不多是从比赛开始到结束. 从自信慢慢的看题一直到wrong到死. 这个题目可以说成是思路题,以为我们只要明白一点,这道题就成了纯暴力的水题, 那就是当操作数不足栈中数字数目的时候,我们就没有 ...
- poj 1556 The Doors
The Doors Time Limit: 1000 MS Memory Limit: 10000 KB 64-bit integer IO format: %I64d , %I64u Java ...
- Delphi 的字符及字符串[5] - 字符串与 Windows API
先说赋值: //赋值方法1: 给直接量 begin SetWindowText(Handle, '新标题'); end; //赋值方法2: 定义它要的类型 var p: PChar; begi ...
- azure存储压测的问题(农码主观意识太强被坑了)
由于公司想把部份业务迁到windowsazure,主要是应用winodwsazure的存储;在方案中为了体现存储的可靠性所以对winodwsazure存储进行了一系列的测试.但在读取压力测试环节中发现 ...
- MongoDB中的高级查询(二)
$mod取模运算 查询index对5取模运算等于1的数据. $not $not是元条件句,即可以用在任何其他条件之上.查询index对5取模运算不等于1的数据. $exists判断字段是否存在 查询出 ...
- JWT【JSON Web Token】 简述
draft: http://self-issued.info/docs/draft-ietf-oauth-json-web-token.html http://tools.ietf.org/html/ ...
- ajax请求的异步嵌套问题分析
(本文章以as3代码为例) 问题的产生 在前端开发时,经常会使用到Ajax(Asynchronous Javascript And XML)请求向服务器查询信息(get)或交换数据(post),aja ...
- RegexKit: A Regular Expression Toolbox Based On NW.js(Node-Webkit) And Other Greate Open Source Projects.
RegexKit RegexKit: A Regular Expression Toolbox Based On NW.js(Node-Webkit) And Other Greate Open So ...
- webpy使用笔记(二) session/sessionid的使用
webpy使用笔记(二) session的使用 webpy使用系列之session的使用,虽然工作中使用的是django,但是自己并不喜欢那种大而全的东西~什么都给你准备好了,自己好像一个机器人一样赶 ...