二维仿射变换,顾名思义就是在二维平面内,对对象进行平移、旋转、缩放等变换的行为(当然还有其他的变换,这里仅论述这三种最常见的)。

Halcon中进行仿射变换的常见步骤如下:

① 通过hom_mat2d_identity算子创建一个初始化矩阵(即[1.0, 0.0, 0.0, 0.0, 1.0, 0.0]);

② 在初始化矩阵的基础上,使用hom_mat2d_translate(平移)、hom_mat2d_rotate(旋转)、hom_mat2d_scale(缩放)等生成仿射变换矩阵;(这几个算子可以叠加或者重复使用

③ 根据生成的变换矩阵执行仿射变换,执行仿射变换的算子通常有:affine_trans_image、affine_trans_region、affine_trans_contour_xld,即不管对于图像、区域、XLD都可以执行仿射变换。

下面用一个完整程序分别展示hom_mat2d_translate(平移)、hom_mat2d_rotate(旋转)、hom_mat2d_scale(缩放)这三个算子的的具体功能。(特别要注意程序注释部分)

hom_mat2d_translate( : : HomMat2D, Tx, Ty : HomMat2DTranslate)

hom_mat2d_rotate( : : HomMat2D, Phi, Px, Py : HomMat2DRotate)

hom_mat2d_scale( : : HomMat2D, Sx, Sy, Px, Py : HomMat2DScale)

程序所用图片如下:

 1 read_image (Image, 'hogn-1.jpg')2 threshold (Image, Region, 0, 200)3 opening_circle (Region, Region, 1.5)4 connection (Region, ConnectedRegions)5 select_shape_std (ConnectedRegions, SelectedRegions, 'max_area', 70)6 *得到变换的中心点7 area_center (SelectedRegions, Area, Row, Column)8 dev_set_draw ('margin')9
10 *hom_mat2d_translate中的两个参数的意思是:Tx和Ty分别代表Row方向和Column方向的平移量
11 dev_display (Image)
12 disp_cross (3600, Row, Column, 10, 40)
13 hom_mat2d_identity (HomMat2DIdentity)
14 hom_mat2d_translate (HomMat2DIdentity,30, 150, HomMat2DTranslate)
15 affine_trans_region (Region, RegionAffineTrans, HomMat2DTranslate, 'nearest_neighbor')
16
17 *hom_mat2d_rotate中的三个参数的意思是:旋转角度(逆时针为正,弧度制),旋转中心的row和column值
18 dev_display (Image)
19 disp_cross (3600, Row, Column, 10, 40)
20 hom_mat2d_rotate (HomMat2DIdentity, rad(20), Row, Column, HomMat2DRotate)
21 affine_trans_region (Region, RegionAffineTrans, HomMat2DRotate, 'nearest_neighbor')
22
23 *hom_mat2d_scale中的四个参数的意思是:Sx和Sy分别代表Row方向和Column方向的缩放系数,缩放中心的row和column值
24 dev_display (Image)
25 disp_cross (3600, Row, Column, 10, 40)
26 hom_mat2d_scale (HomMat2DIdentity, 2.0, 1.05, Row, Column, HomMat2DScale)
27 affine_trans_region (Region, RegionAffineTrans, HomMat2DScale, 'nearest_neighbor')

效果分别如下:

有时候,并不需要创建初始化矩阵也可以执行仿射变换,例如vector_angle_to_rigid算子就是如此。

vector_angle_to_rigid( : : Row1, Column1, Angle1, Row2, Column2, Angle2 : HomMat2D)

该算子意思是:先将图像旋转,旋转角度为(Angle2 - Angle1) (逆时针为正),旋转中心坐标是(Row1, Column1)。再将原图的点(Row1, Column1)一一对应移到点 (Row2, Column2)上,移动的row和column方向的位移分别是( Row2 - Row1)、( Column2 - Column1),

如果Row1 = Row2, Column1 = Column2,那么就完整等价于旋转变换。可以执行下面的程序感受一下:

 1 read_image (Image, 'hogn-1.jpg')2 Row := 1003 Column := 2004 dev_display (Image)5 6 7 for Index := 1 to 150 by 1  8     vector_angle_to_rigid (Row, Column, 0, Row, Column, rad(10), HomMat2D)
 9     disp_cross (3600, 100, 200, 10, 40)
10     affine_trans_image (Image, ImageAffinTrans, HomMat2D, 'nearest_neighbor', 'false')
11     copy_image (ImageAffinTrans, Image)
12 endfor

可以将vector_angle_to_rigid理解为同时执行旋转变换和平移变换。最难弄明白的是旋转中心是什么?下面的程序可以说明如果先旋转后平移,那么旋转中心是(Row1, Column1),而不是 (Row2, Column2)。(如果先平移后旋转,那么结论刚好相反,大家可以试试)

 1 read_image (Image, 'hogn-1.jpg')2 Row1 := 1003 Column1 := 1004 5 Row2 := 1006 Column2 := 2007 dev_display (Image)8 *用vector_angle_to_rigid实现缩放、平移9 vector_angle_to_rigid (Row1, Column1, 0, Row2, Column2, rad(10), HomMat2D)
10 affine_trans_image (Image, ImageAffinTrans, HomMat2D, 'nearest_neighbor', 'false')
11
12 *分两步依次执行缩放、平移
13 hom_mat2d_identity (HomMat2DIdentity)
14 hom_mat2d_rotate (HomMat2DIdentity, rad(10) - 0, Row1, Column1, HomMat2DRotate)
15 hom_mat2d_translate (HomMat2DRotate,Row2 - Row1, Column2 - Column1, HomMat2DTranslate)
16 *观察图像ImageAffinTrans和ImageAffinTrans_2能够完全重合
17 affine_trans_image (Image, ImageAffinTrans_2, HomMat2DTranslate, 'nearest_neighbor', 'false')
18
19 disp_cross (3600, Row1, Column1, 10, 40)

vector_angle_to_rigid最常用到的场合一般是模板匹配之类的算法场合,通常用在find_shape_model等算子后面。

下面用一个例子说明一下仿射变换的综合应用,即当图片旋转90°时,想办法变换Region使之能够翻转到对应的位置。

将图片顺时针翻转90°的方法可以是:rotate_image (image, ImageRotate, -90, 'constant')。

但其实它不仅经过了旋转变换、还进行了平移变换,最明显的证据就是:翻转前后的图像,他们的中心点坐标不一样。完整程序如下:

 1 read_image (image, 'C:/Users/happy xia/Desktop/dynPic.png')2 binary_threshold (image, Region, 'max_separability', 'dark', UsedThreshold)3 dev_set_draw ('margin')4 connection (Region, ConnectedRegions)5 select_shape_std (ConnectedRegions, SelectedReg, 'max_area', 70)6 area_center (image, Area, Row, Column)
 7 8 rotate_image (image, ImageRotate, -90, 'constant')
 9 area_center (ImageRotate, Area2, Row2, Column2)
10
11 hom_mat2d_identity (HomMat2DIdentity)
12 hom_mat2d_rotate (HomMat2DIdentity, -rad(90), Row, Column, HomMat2DRotate)
13 hom_mat2d_translate (HomMat2DRotate,Row2 - Row, Column2 - Column, HomMat2DTranslate)
14
15 affine_trans_region (SelectedReg, RegionAffineTrans, HomMat2DTranslate, 'constant')

该算法顺利达到了目的——图像翻转以后,原先生成的Region也翻转到了对应的位置。

注意:用rotate_image 算子旋转图像时,如果旋转角度不是0°、90°、180°、270°等角度,那么图像其实只做了旋转变换,而没有进行平移变换。

Halcon:二维仿射变换实例探究相关推荐

  1. halcon二维码识别简单案例

    目录 二维码种类 ​编辑 halcon 二维码识别调用算子步骤 1.创建模型--create_data_code_2d_model( SymbolType, GenParamName, GenPara ...

  2. python随机生成二维列表_对python产生随机的二维数组实例详解

    对python产生随机的二维数组实例详解 最近找遍了python的各个函数发现无法直接生成随机的二维数组,其中包括random()相关的各种方法,都没有得到想要的结果.最后在一篇博客中受到启发,通过列 ...

  3. Halcon二维码扫描算法总结

           近期要往一个大型软件里面增加一个扫码工具,想到基于halcon算子进行开发,记录一下开发过程中的采坑和要点.         刚开始拿到现场的二维码数据集,基于halcon进行测试,发现 ...

  4. 编程实现多边形的平移、比例(缩放)、旋转、对称和错切等二维仿射变换(大有门道)

    这是计算机图形学基础的一个课后题,其实完全可以直接用OpenGL提供的几何变换的函数轻松的实现,但是毕竟学就要学明白,仔细写这个题一是为了回顾一下各种变换对应的变换矩阵和数学规律,二是加深一下对交互的 ...

  5. python中的二维数组_Python中的二维数组实例(list与numpy.array)

    关于python中的二维数组,主要有list和numpy.array两种. 好吧,其实还有matrices,但它必须是2维的,而numpy arrays (ndarrays) 可以是多维的. 我们主要 ...

  6. php二维数组实例_什么是php二维数组?php二维数组实例详解

    什么是php二维数组? 二维数组又称为矩阵,本质上是以数组作为数组元素的数组,一个数组的元素如果是一维数组,那么我们就称这个数组是二维数组. PHP二维数组实例详解 我们之前的一篇文章<PHP数 ...

  7. Halcon 二维码

    目录 1. 二维码 1.1 定义 1.2 结构 1.3 原理 2. Halcon识别二维码基本流程 3. 难读取的二维码(码制不能错) 3.1 点状二维码 3.2 有噪声的二维码 3.3 投影变换(透 ...

  8. Zxing和QR CODE 生成与解析二维码实例(普通篇)

    首先下载对应的jar包,本实例用的是Zxing2.2jar 下载地址:http://download.csdn.net/detail/gao36951/8161861 Zxing是Google提供的关 ...

  9. Zxing和QR CODE 生成与解析二维码实例(带logo篇)

    上一篇介绍了普通的二位码的生成与解析,本篇来介绍两种工具类生成带Logo的二维码的实例 下载jar包地址:http://download.csdn.net/detail/gao36951/816186 ...

最新文章

  1. 不平等加剧与问责机制:纽约大学AI Now研究所2018 AI现状报告 | 报告
  2. 转图像偏微分方程不适定问题
  3. Java项目导出为可执行jar包,并在windows/linux下运行
  4. c语言学生成绩删除功能,c语言学生成绩管理系统程序设计,有添加,查找,删除,输出,修改,排序等功能!!!...
  5. containerd项目正式从CNCF毕业
  6. Web笔记-html中svg的基本使用
  7. html5 多文件选择
  8. java复制arraylist_Java - 复制ArrayList
  9. C++_数据类型_算术运算符_取模运算_递增递减运算_赋值运算符_比较运算符---C++语言工作笔记014
  10. MySQL 锁(行锁、表锁、页锁、乐观锁、悲观锁等)
  11. 入门到精通pl/sql编程(千里之行始于足下)之触发器
  12. mob AndroidStudio 短信SDK集成
  13. Musical Christmas Lights——一个圣诞树灯光✨随音乐节奏改变的前端开源项目
  14. 浅谈单片机、ARM和DSP的异同——非常透彻
  15. PHP递归算法的简单实例
  16. java 打印 日历 详细 注解_java 打印日历
  17. 计算机网络ftp客户端实验,计算机网络实验报告FTP客户端.doc
  18. EPSON机械手跟相机搭配走tcp ip协议,及跟plc通讯将手动操作部分映射到触摸屏
  19. lgg6 android 9,【LGG6评测】18:9奇葩比例没采用骁龙835 LG G6解析(全文)_LG G6_手机评测-中关村在线...
  20. 配置springboot jsp页面跳转

热门文章

  1. Ueditor百度编辑器中的 setContent()方法的使用
  2. Java怎样处理EXCEL的读取
  3. CDN架构以及原理分析
  4. 微软ASP.NET站点部署指南(3):使用Web.Config文件的Transformations
  5. 您不能不知的ToString()方法
  6. 关于Services.exe开机CPU内存使用暴增解决方案
  7. NSString拼接字符串和NSPredicate详解
  8. VS(C++)配置Halcon(一次配置,永久使用)
  9. python自动化第三周---文件读写
  10. 关于Unity中NGUI的Pivot和锚点