第六章 - 图像变换 - 图像拉伸、收缩、扭曲、旋转[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 ...
随机推荐
- Java 第四章 选择结构2
第四章 选择结构 (二) switch 选择结构的执行流程是怎样的? switch 选择结构中break关键字的作用? 本章目标 掌握 switch 选择结构 能够综合运用 if 选择结构 和 swi ...
- log4j2自定义输出线程环境信息
在配置日志的输出格式的时候,我们可以按照内置的规则输出日志,但是有时候需要及时输出我们自定义的信息,这时需要借助ThreadContext类. ThreadContext类类似于MDC和NDC,它是一 ...
- [转]正确使用SQLCipher来加密Android数据库 - 朝野布告
参考文档:http://www.tuicool.com/articles/eYNFbuA Android本身自带有不加密的数据库SQLite,如果要保存密码之类的敏感数据在本地的话方法一是使用字段加密 ...
- struts 标签<s:ierator>的简单使用说明
struts 标签<s:ierator>的简单使用说明,只显示<s:ierator> 的前6条数据 <s:iterator value="lstVisitor& ...
- MySql执行多条语句
http://www.cppblog.com/fwxjj/archive/2010/08/05/122258.html说是在连接上设置: //链接时设定 mysql_real_connect( ... ...
- [MSSQL2012]CUME_DIST函数
CUME_DIST函数以某列作为基准,计算其它行相对于基准行数据的比例.差距比例,比较容易理解 先看下测试数据 DECLARE @TestData TABLE( ID INT IDENTITY ...
- [ALM]一步一步搭建MS ALM环境 - 安装域服务器
描述: 搭建并配置域服务器,先安装操作系统,配置网络,安装组件,配置域帐号 步骤: 1,打开Hyper-V Manager,参考[Hyper-V]使用操作系统模板创建新的虚拟机,先完成操作系统的安装, ...
- android相关技能
深读: 如:View.ViewGroup.AdapterView.ListView.GridView.Window.ViewDragHelper.ItemTouchHelper.SurfaceView ...
- 整合GreyBox放大显示图片
<s:iterator value="#request.photoList" id="photo" status="stu"> ...
- 面试求职中需要了解的Java多线程知识
Java中多线程的实现方式 在java的历史版本中,有两种创建多线程程序的方法 1) 通过创建Thread类的子类来实现(Thread类提供了主线程调用其它线程并行运行的机制) 主要步骤: 自定义类继 ...