Halcon图像处理实战:仿射变换五大操作详解(平移、旋转、缩放、斜切、镜像)

1. 仿射变换:图像处理的“橡皮泥”艺术

大家好,我是老张,在机器视觉这行摸爬滚打十多年了,用过不少软件,但Halcon一直是我的心头好。今天咱们不聊那些高深莫测的算法,就聊聊一个非常基础但又无比强大的工具——仿射变换。你可以把它想象成玩橡皮泥,平移、旋转、缩放、斜切、镜像,就像你用手去捏、去拉、去压一块图像“橡皮泥”,把它变成你想要的样子。听起来是不是挺简单的?但就是这些基础操作,构成了我们做视觉定位、尺寸测量、缺陷检测的基石。很多新手朋友一上来就被“齐次矩阵”、“变换矩阵”这些词吓到了,其实没那么复杂,跟着我的思路,用几个实际的例子走一遍,你就能轻松上手。

简单来说,仿射变换就是保持图像中“直线还是直线,平行线还是平行线”的一种变换。无论你怎么折腾这块“橡皮泥”,上面的格子线虽然会变形,但绝不会变成曲线。在Halcon里,我们所有的操作都围绕一个核心展开:变换矩阵。你不用自己去推导复杂的数学公式,Halcon已经提供了一系列超级好用的算子(你可以理解为函数)来帮你生成这个矩阵。我们的工作流程就像搭积木:先创建一个“单位矩阵”作为起点,然后往上面叠加你想要的平移、旋转等操作指令,最后把这个综合指令(矩阵)交给一个“执行者”,让它去改变图像。接下来,我就带你把这五大操作一个个拆开,用最直白的代码和效果图,让你彻底搞明白。

2. 平移:给图像“搬个家”

平移是最直观的变换,就是把整张图在平面上挪个位置。想象一下,你在电脑桌面上拖动一个窗口,就是平移。在视觉项目里,这太常用了。比如,你相机拍到的产品位置每次都有点偏差,你需要先把图像“对齐”到一个标准位置,再进行后续检测,这时候平移就是第一步。

在Halcon里,实现平移只需要三步。第一步,用 hom_mat2d_identity 创建一个干净的“画板”,也就是单位矩阵。第二步,用 hom_mat2d_translate 告诉这个画板:“我要横向(X方向)移动Tx个像素,纵向(Y方向)移动Ty个像素”。第三步,用 affine_trans_image 这个“执行者”,拿着第二步生成的指令,去实际移动你的图像。

这里有个关键点需要注意:平移的距离是以像素为单位的。Tx为正,图像向右移;为负,向左移。Ty为正,图像向下移;为负,向上移。这个和Halcon的图像坐标系有关(原点在左上角)。我刚开始用的时候,经常把正负搞反,导致图像“跑飞”了,调试了半天才发现是方向问题。

我们来看一段实战代码,假设我有一张叫 Image 的图片,我想把它往右下角各移动150个像素:

* 读取原始图像
read_image (Image, 'part.png')
* 创建一个单位矩阵作为变换起点
hom_mat2d_identity (HomMat2DIdentity)
* 生成一个平移矩阵:X方向移150,Y方向移150
hom_mat2d_translate (HomMat2DIdentity, 150, 150, HomMat2DTranslate)
* 应用变换,使用‘constant’模式填充空白区域(通常填充灰色)
affine_trans_image (Image, ImageAffineTrans, HomMat2DTranslate, 'constant', 'false')

运行后,你会发现原图整个“搬家”到了右下角,原来左上角的位置空了出来,被填充成了灰色(‘constant’参数的效果)。在实际项目中,我经常用平移来做ROI(感兴趣区域)的微调。比如我的检测区域模板是固定的,但这次拍到的产品整体偏左了5个像素,我不用重新画ROI,直接生成一个平移矩阵(Tx=5, Ty=0),把整个检测区域向右平移5像素就行了,非常高效。

2.1 平移的“组合拳”:先旋转再平移 vs 先平移再旋转

这里我要分享一个容易踩的坑:变换的顺序至关重要。因为矩阵乘法不满足交换律。什么意思呢?比如你想让一个图像先旋转45度,再向右平移100像素。和你先向右平移100像素,再旋转45度,得到的结果是完全不同的!

你可以把变换矩阵想象成一套连续的指令清单。hom_mat2d_identity 是张空白清单。当你调用 hom_mat2d_rotate 时,你在清单上写下了“旋转”指令。接着你再调用 hom_mat2d_translate,是在“旋转”指令后面又追加了“平移”指令。最终 affine_trans_image 是严格按照清单从前到后的顺序执行的。

* 顺序A:先旋转,后平移(围绕原点旋转后,再移动)
hom_mat2d_identity (HomMat2DIdentity)
hom_mat2d_rotate (HomMat2DIdentity, rad(45), 0, 0, HomMat2DRotate) * 在原点旋转45度
hom_mat2d_translate (HomMat2DRotate, 100, 0, HomMat2DFinal) * 然后平移
affine_trans_image (Image, ImageResultA, HomMat2DFinal, 'constant', 'false')

* 顺序B:先平移,后旋转(先移动,再围绕原点旋转)
hom_mat2d
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值