Halcon学习---02仿射变换的应用

本文详细介绍了Halcon中的仿射变换步骤,包括创建初始化矩阵、平移、旋转和缩放操作。通过实例展示了如何使用这些操作对图像、区域和轮廓进行变换,并解释了vector_angle_to_rigid算子的用法。此外,还探讨了在模板匹配和跟随被测物体对齐等场景中的应用。最后,提供了一个综合应用案例,演示了如何通过仿射变换解决图片旋转90度后Region的翻转问题。
摘要由CSDN通过智能技术生成

(一)步骤

  • 通过hom_mat2d_identity算子创建一个初始化矩阵

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

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

 

(二)实例1

  • 在Halcon例程中方法--->几何转换--->affine_trans_region.hdev

 dev_close_window ()
 dev_open_window (0, 0, 512, 512, 'white', WindowID)
 dev_set_color ('black')
  
 *在图形窗口中任意画一个图形,用鼠标右键确认
 draw_region (Region, WindowID)
 *初始化一个变换矩阵
 hom_mat2d_identity (HomMat2DIdentity)
 *通过给定旋转角度(顺时针为负,逆时针为正),旋转原点得到旋转矩阵
 hom_mat2d_rotate (HomMat2DIdentity, -0.3, 256, 256, HomMat2DRotate)
 *通过给定X、Y方向缩放尺度,缩放原点得到缩放矩阵
 hom_mat2d_scale (HomMat2DRotate, 1.5, 1.5, 256, 256, HomMat2DScale)
 *最后得到仿射变换图片
 affine_trans_region (Region, RegionAffineTrans, HomMat2DScale, 'false')
  
 dev_clear_window ()
 dev_set_draw ('margin')
 dev_set_color ('red')
 dev_display (Region)
 dev_set_color ('green')
 dev_display (RegionAffineTrans)
添加旋转与缩放

 

(三)实例2

read_image (Image, 'E:/Halcon/算法/09几何变换/仿射变换/hogn.jpg')  

dev_close_window()  

dev_open_window_fit_image(Image, 0, 0, -1, -1, WindowHandle)  dev_display(Image)  ​  

*预处理  

threshold (Image, Region, 0, 200)  

opening_circle (Region, Region, 1.5)  

connection (Region, ConnectedRegions)  

select_shape_std (ConnectedRegions, Region, 'max_area', 70)  

*得到长条区域的中心点  

area_center (Region, Area, Row, Column)  

dev_set_draw ('margin')

  • 平移

dev_display (Image)
disp_cross (WindowHandle, Row, Column, 10, 40)
hom_mat2d_identity (HomMat2DIdentity)
hom_mat2d_translate (HomMat2DIdentity,30, 150, HomMat2DTranslate)
affine_trans_region (Region, RegionAffineTrans, HomMat2DTranslate, 'nearest_neighbor')

  • 旋转90度

dev_display (Image)
disp_cross (WindowHandle, Row, Column, 10, 40)
hom_mat2d_rotate (HomMat2DIdentity, rad(90), Row, Column, HomMat2DRotate)
affine_trans_region (Region, RegionAffineTrans, HomMat2DRotate, 'nearest_neighbor')

  • 缩放

dev_display (Image)
disp_cross (WindowHandle, Row, Column, 10, 40)
hom_mat2d_scale (HomMat2DIdentity, 2.0, 1.05, Row, Column, HomMat2DScale)
affine_trans_region (Region, RegionAffineTrans, HomMat2DScale, 'nearest_neighbor')

  •  测试窗口跟随被测物体对齐,适用于定位

dev_display(ImageRotate)
gen_rectangle2(Rectangle, 100, 100, rad(15), 50, 20)
gen_circle(Circle, 50, 100, 30)
*对矩形进行仿射变换---平移+旋转,得到矩形变换的矩阵
hom_mat2d_identity(HomMat2DIdentity2)
vector_angle_to_rigid( 100, 100, rad(15), 200, 200, rad(15), HomMat2D1)
affine_trans_region(Rectangle, RegionAffineTrans2, HomMat2D1, 'nearest_neighbor')

*根据矩形的变换矩阵进行圆的仿射变换
affine_trans_point_2d(HomMat2D1, 50, 100, Qx, Qy)
gen_circle(Circle1, Qx, Qy, 30)

 

(四)实例3---强调一下vector_angle_to_rigid算子

  • 有时候,并不需要创建初始化矩阵也可以执行仿射变换

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

  • 如果Row1 = Row2, Column1 = Column2,那么就完整等价于旋转变换

 // 根据点和角度计算刚性仿射变换矩阵,支持旋转和平移
 vector_angle_to_rigid(Row1,Column1, // 原始行列坐标
                       Angle1, // 原始点角度
                       Row2,Column2, // 变换的目的点行列坐标
                       Angle2, // 变换的目的点角度
                       HomMat2D) // 输出仿射变换矩阵

read_image (Image, 'E:/Halcon/算法/09几何变换/仿射变换/hogn.jpg')
dev_open_window_fit_image(Image, 0, 0, -1, -1, WindowHandle)
Row := 100
Column := 200
dev_display (Image)

for Index := 1 to 150 by 1  
    vector_angle_to_rigid (Row, Column, 0, Row, Column, rad(10), HomMat2D)
    disp_cross (WindowHandle, 100, 200, 10, 40)
    affine_trans_image (Image, ImageAffinTrans, HomMat2D, 'nearest_neighbor', 'false')
    copy_image (ImageAffinTrans, Image) 
endfor

  • 可以将vector_angle_to_rigid理解为同时执行旋转变换和平移变换。最难弄明白的是旋转中心是什么?

  • 下面的程序可以说明如果先旋转后平移,那么旋转中心是(Row1, Column1),而不是 (Row2, Column2)

  • 如果先平移后旋转,那么旋转中心是(Row2, Column2),而不是 (Row1, Column1)

read_image (Image, 'E:/Halcon/算法/09几何变换/仿射变换/hogn.jpg')
dev_open_window_fit_image(Image, 0, 0, -1, -1, WindowHandle)
Row1 := 100
Column1 := 100
Row2 := 100
Column2 := 200
dev_display (Image)

binary_threshold(Image, Region, 'max_separability', 'dark', UsedThreshold)
connection(Region, ConnectedRegions)
dev_set_color('blue')
select_shape_std(ConnectedRegions, SelectedRegions, 'max_area', 70)
area_center(SelectedRegions, Area, Row, Column)
disp_cross(WindowHandle, Row, Column, 10, 45)

*用vector_angle_to_rigid实现缩放、平移
vector_angle_to_rigid (Row1, Column1, 0, Row2, Column2, rad(10), HomMat2D)
affine_trans_image (Image, ImageAffinTrans, HomMat2D, 'nearest_neighbor', 'false')

*分两步依次执行缩放、平移
hom_mat2d_identity (HomMat2DIdentity)
hom_mat2d_translate(HomMat2DIdentity, Row2 - Row1, Column2 - Column1, HomMat2DTranslate1)
hom_mat2d_rotate (HomMat2DTranslate1, rad(10) - 0, Row1, Column1, HomMat2DRotate)

*观察图像ImageAffinTrans和ImageAffinTrans_2能够完全重合
affine_trans_image (Image, ImageAffinTrans_2, HomMat2DRotate, 'nearest_neighbor', 'false')

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

 

(五)实例4---测试窗口跟随被测物体对齐

*读取模版图像
read_image (Image, 'image/board-01.png')
get_image_size (Image, Width, Height)
dev_open_window (0, 0, Width, Height, 'black', WindowHandle)
dev_display (Image)
dev_set_draw ('margin')

*创建形状模板
draw_rectangle2 (WindowHandle, Row, Column, Phi, Length1, Length2)
gen_rectangle2 (Rectangle, Row, Column, Phi, Length1, Length2)
reduce_domain (Image, Rectangle, ImageReduced)

*确定金字塔层数
determine_shape_model_params(ImageReduced, 'auto', 0, rad(360), 0.9, 1.1, 'auto', 'use_polarity', 'auto', 'auto', 'all', ParameterName, ParameterValue)
*用形状模板创建形状模型
create_shape_model (ImageReduced, 3, 0, rad(360), 'auto', 'none', 'use_polarity', 30, 10, ModelID)
*在模版图像中搜索模版
find_shape_model (Image, ModelID, 0, rad(360), 0.4, 1, 0, 'least_squares', 0, 0.7, ModelRow, ModelColumn, ModelAngle, ModelScore)
*获取模版轮廓
get_shape_model_contours (ShapeModel, ModelID, 1)
stop ()

*自定义测试窗口ROI
dev_display (Image)
draw_rectangle2 (WindowHandle, Row, Column, Phi, Length1, Length2)
OffsetRow:=Row-ModelRow
OffsetColumn:=Column-ModelColumn
*根据模版坐标位置和ROI窗口生成新的测试窗口
gen_rectangle2 (Rectangle, ModelRow+OffsetRow, ModelColumn+OffsetColumn, Phi,Length1, Length2)


*连续图像采集
* Image Acquisition 01: Code generated by Image Acquisition 01
list_image_files('E:/Halcon/视频教程/Halcon视频教程 第1套/5.Halcon中级视频教程/配套教程/02测试窗口跟随被测物体对齐(仿射变换)/image', 'png', [], ImageFiles)

*测试窗口跟随被测物体对齐
for Index := 0 to |ImageFiles| - 1 by 1
          read_image (Image, ImageFiles[Index])
          dev_display (Image)
          RowCheck:=0
          ColumnCheck:=0
          AngleCheck:=0
          Score:=0
          *在搜索图像中寻找模版
          find_shape_model (Image, ModelID, 0, rad(360), 0.4, 1, 0, 'least_squares', 0, 0.7, RowCheck, ColumnCheck, AngleCheck, Score)
          *生成2D齐次变换矩阵
          hom_mat2d_identity (HomMat2DIdentity)
          *添加偏移转换到2D齐次变换矩阵上
          hom_mat2d_translate (HomMat2DIdentity, RowCheck, ColumnCheck, HomMat2DTranslate)
          *添加旋转转换到2D齐次变换矩阵上
          hom_mat2d_rotate (HomMat2DTranslate, AngleCheck, RowCheck, ColumnCheck, HomMat2DRotate)
          *对模版形状进行仿射变换
          affine_trans_contour_xld (ShapeModel, ShapeModelTrans, HomMat2DRotate)
          *显示仿射变换后的模版形状
          dev_display (ShapeModelTrans)
          
          *对OffsetRow, OffsetColumn这两个坐标执行仿射变换
          affine_trans_pixel (HomMat2DRotate, OffsetRow, OffsetColumn, OutLeftRow, OutLeftColumn)
          *生成要跟随被测物的测试窗口ROI
          gen_rectangle2 (OutRectangle, OutLeftRow, OutLeftColumn, Phi+AngleCheck, Length1, Length2)
          *显示图像
          dev_display (Image)
          *显示测试窗口ROI
          dev_display (OutRectangle)
          stop()
endfor

 

(六)仿射变换的综合应用

  • 当图片旋转90°时,想办法变换Region使之能够翻转到对应的位置

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

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

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

 read_image (image, 'E:/Halcon/算法/09几何变换/仿射变换/仿射变换的综合应用.png')
 binary_threshold (image, Region, 'max_separability', 'dark', UsedThreshold)
 dev_set_draw ('margin')
 connection (Region, ConnectedRegions)
 select_shape_std (ConnectedRegions, SelectedReg, 'max_area', 70)
 area_center (image, Area, Row, Column)
 ​
 rotate_image (image, ImageRotate, -90, 'constant')
 area_center (ImageRotate, Area2, Row2, Column2)
 ​
 hom_mat2d_identity (HomMat2DIdentity)
 hom_mat2d_rotate (HomMat2DIdentity, -rad(90), Row, Column, HomMat2DRotate)
 hom_mat2d_translate (HomMat2DRotate,Row2 - Row, Column2 - Column, HomMat2DTranslate)
 ​
 affine_trans_region (SelectedReg, RegionAffineTrans, HomMat2DTranslate, 'constant')
  • 3
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

盾山狂热粉

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值