Halcon 几何变换之仿射变换

2024-09-06 12:58

本文主要是介绍Halcon 几何变换之仿射变换,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

几何变换包括仿射变换、投影变换、图像变换以及极坐标变换。不同的资料可能会有不同的划分。它们具体的数学表达感性趣的可以自己查找。这里只描述Halcon的仿射变换运用。

Halcon中的放射变换常用的两种方式:旋转以及缩放(当然平移也常用,但是不属于仿射变换)。变换涉及到三个量,一个是待变换的图像或者说矩阵,一个变换矩阵,以及变换后的图像或者矩阵。所以在Halcon中会有两种运用方式。第一种:已知待变换的图像,变换矩阵,求变换后的图像;第二种:已知待变换的图像,变换后的图像,求变换矩阵。

第一种变换流程:
通过hom_mat2d_identity算子创建一个初始化矩阵(本来应该是3*3的单位矩阵,但是在Halcon10版本上看到的却是2*3的矩阵,不过在Halcon12版本上看到是3*3的。至于原因可能是3*3变换矩阵中有一行是固定值,早期版本有可能是为了节省空间在保存中故意缺省)。
在初始化矩阵的基础上,使用hom_mat2d_translate(平移)、hom_mat2d_rotate(旋转)、hom_mat2d_scale(缩放)等生成仿射变换矩阵(这几个算子可以叠加或者重复使用)。
根据生成的变换矩阵执行仿射变换,执行仿射变换的算子通常有:affine_trans_image、affine_trans_region、affine_trans_contour_xld,即不管对于图像、区域、XLD都可以执行仿射变换。
下面具体看看这种变换的示例。可以在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)

结果如图:

 

第二种变换流程:
制订一个标准(模板)。例如下面例子中,就是读入一张合格的一板药片。并对该板药片进行标准化,获得标准化后药片的方向及位置,还有提取感性区域
读入新图片和制订的标准对齐。下面的例子中就是读入一张新的一板药片,并按照标准的位置和方向进行放射变换。
对齐后,和制订的标准图片进行感性区域对比分析。下面的例子就是对比后提取新读入图片的感性区域,分析该药片生成是否合格。
Halcon案例:方法->Blob分析->check_blister.hdev
 

dev_close_window ()
dev_update_off ()
read_image (ImageOrig, 'blister/blister_reference')*自适应图片大小打开图形窗口
dev_open_window_fit_image (ImageOrig, 0, 0, -1, -1, WindowHandle)
set_display_font (WindowHandle, 14, 'mono', 'true', 'false')
dev_set_draw ('margin')
dev_set_line_width (3)
dev_display (ImageOrig)
* 
* 第一步:制订标准
threshold (ImageOrig, Region, 90, 255)
dev_display (Region)
dev_set_color ('green')
*以Region区域为基准,获得该区域的凸性区域,注意和外接图形区分
shape_trans (Region, Blister, 'convex')
dev_display (Blister)
*通过获得区域Blister的图像的几何矩,计算该区域的角度。如果想理解的更深,可以查看图像的几何矩这篇博客
*该夹角大致可以用该区域“外接”椭圆(也是通过图像几何矩得到,当然不是真的外接椭圆)的长轴与水平线的夹角去理解
orientation_region (Blister, Phi)
area_center (Blister, Area1, Row, Column)
*通过一个向量转换到另外一个向量,得到该转换的变换矩阵(一个坐标加方向就是向量)
vector_angle_to_rigid (Row, Column, Phi, Row, Column, 0, HomMat2D)
*对图像进行仿射变换
affine_trans_image (ImageOrig, Image2, HomMat2D, 'constant', 'false')
dev_display (Image2)
*创建一个空对象数组
gen_empty_obj (Chambers)
for I := 0 to 4 by 1Row := 88+I*70for J := 0 to 2 by 1Column := 163 + J*150*创建任意方向的矩形区域gen_rectangle2 (Rectangle, Row, Column, 0, 64, 30)*将区域Rectangle放到Chambers中concat_obj (Chambers, Rectangle, Chambers)endfor
endfor
affine_trans_region (Blister, Blister, HomMat2D, 'false')
*计算两个图像区域的差集
difference (Blister, Chambers, Pattern)
*将不同区域变成连通区域(逻辑上连通),和connection算子是相反操作
union1 (Chambers, ChambersUnion)
*不确定这一步的目的是什么。Blister已经变换了,干嘛还要再求一次Blister的方向,是为了减少误差?
orientation_region (Blister, PhiRef)
*为什么要加π,或许可以从帮助文档中找到原因,或者查看我写的学习Halcon(5.1)博客
PhiRef := rad(180)+PhiRef
area_center (Blister, Area2, RowRef, ColumnRef)
* 
* 
* Each image read will be aligned to this pattern and reduced to the area of interest,
* which is the chambers of the blister
Count := 6
for Index := 1 to Count by 1*第二步:读入新图片,和标准对齐read_image (Image, 'blister/blister_'+Index$'02')threshold (Image, Region, 90, 255)connection (Region, ConnectedRegions)select_shape (ConnectedRegions, SelectedRegions, 'area', 'and', 5000, 9999999)shape_trans (SelectedRegions, RegionTrans, 'convex')* * align pattern along blister of imageorientation_region (RegionTrans, Phi)area_center (RegionTrans, Area3, Row, Column)vector_angle_to_rigid (Row, Column, Phi, RowRef, ColumnRef, PhiRef, HomMat2D)affine_trans_image (Image, ImageAffinTrans, HomMat2D, 'constant', 'false')* * 第三步:对齐后,提取感性区域并分析是否达到要求reduce_domain (ImageAffinTrans, ChambersUnion, ImageReduced)*将三通道图片转换成三个单通道图片decompose3 (ImageReduced, ImageR, ImageG, ImageB)var_threshold (ImageB, Region, 7, 7, 0.2, 2, 'dark')connection (Region, ConnectedRegions0)closing_rectangle1 (ConnectedRegions0, ConnectedRegions, 3, 3)fill_up (ConnectedRegions, RegionFillUp)select_shape (RegionFillUp, SelectedRegions, 'area', 'and', 1000, 99999)opening_circle (SelectedRegions, RegionOpening, 4.5)connection (RegionOpening, ConnectedRegions)select_shape (ConnectedRegions, SelectedRegions, 'area', 'and', 1000, 99999)shape_trans (SelectedRegions, Pills, 'convex')* * classify segmentation results and display statisticscount_obj (Chambers, Number)gen_empty_obj (WrongPill)gen_empty_obj (MissingPill)for I := 1 to Number by 1select_obj (Chambers, Chamber, I)intersection (Chamber, Pills, Pill)area_center (Pill, Area, Row1, Column1)if (Area > 0)min_max_gray (Pill, ImageB, 0, Min, Max, Range)if (Area<3800 or Min < 60)concat_obj (WrongPill, Pill, WrongPill)endifelseconcat_obj (MissingPill, Chamber, MissingPill)endifendfor* dev_clear_window ()dev_display (ImageAffinTrans)dev_set_color ('forest green')count_obj (Pills, NumberP)count_obj (WrongPill, NumberWP)count_obj (MissingPill, NumberMP)dev_display (Pills)if (NumberMP > 0 or NumberWP > 0)disp_message (WindowHandle, 'Not OK', 'window', 10, 10+600, 'red', 'true')elsedisp_message (WindowHandle, 'OK', 'window', 10, 10+600, 'forest green', 'true')endifdisp_message (WindowHandle, '# correct pills: ' + (NumberP - NumberWP), 'window', 10, 10, 'black', 'true')disp_message (WindowHandle, '# wrong pills  :  ' + NumberWP, 'window', 10+25, 10, 'black', 'true')if (NumberWP>0)disp_message (WindowHandle, NumberWP, 'window', 10+25, 10+180, 'red', 'true')endifdisp_message (WindowHandle, '# missing pills:  ' + NumberMP, 'window', 10+50, 10, 'black', 'true')if (NumberMP > 0)disp_message (WindowHandle, NumberMP, 'window', 10+50, 10+180, 'red', 'true')endifdev_set_color ('red')dev_display (WrongPill)dev_display (MissingPill)if (Index < Count)disp_continue_message (WindowHandle, 'black', 'true')endifstop ()

 

这篇关于Halcon 几何变换之仿射变换的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1142068

相关文章

python图像处理的图像几何变换

一.图像几何变换 图像几何变换不改变图像的像素值,在图像平面上进行像素变换。适当的几何变换可以最大程度地消除由于成像角度、透视关系乃至镜头自身原因所造成的几何失真所产生的负面影响。几何变换常常作为图像处理应用的预处理步骤,是图像归一化的核心工作之一[1]。 一个几何变换需要两部分运算: 空间变换:包括平移、缩放、旋转和正平行投影等,需要用它来表示输出图像与输入图像之间的像素映射关系。灰度插值

将DIB/bitmap读入内存并转为 halcon hobject

问题由来:在mfc halcon混合编程中,发现halcon::readimage() 函数读取图片(8位8M/bmp)至少200ms,当然24位 32位bmp 倍数所消耗的时间倍数上涨。那么有没有什么方法加快读取速度?目前发现一个亲测可行的方式:  1、通过 DIBAPI 读取图片,下载可转到点击打开链接,赚点积分 2、获取所读读片的图像数据的首地址,注意非结构头地址 3、通过halcon

Halcon选择一堆region中面积第N大的region的算法实现

以下图为例: 比如我想把面积第2小的那个“小正方形”选择出来,算法代码如下: 1 read_image (Yuan, 'C:/Users/happy xia/Desktop/yuan.png')2 binary_threshold (Yuan, Region, 'max_separability', 'dark', UsedThreshold)3 connection (Regio

Halcon编程-基于形状特征的模板匹配

halcon软件最高效的一个方面在于模板匹配,号称可以快速进行柔性模板匹配,能够非常方便的用于缺陷检测、目标定位。下面以一个简单的例子说明基于形状特征的模板匹配。      为了在右图中,定位图中的三个带旋转箭头的圆圈。注意存在,位置、旋转和尺度变化。 上halcon程序 1 * This example program shows how to find scaled and

halcon 仿射变换功能函数,

1.仿射变换有:平移、旋转、缩放、斜切。 2.要进行仿射变换,必须先获取变换矩阵。要获取变换矩阵,必须先获取特征点坐标、角度等信息,几何匹配和bolb是获取特征点的高效方法,除此之外还有其它方法,只要能稳定的求出特征点即可。 3.仿射变换流程    (1.)获取特征点坐标、角度    (2.)计算仿射变换矩阵    (3.)对图像、区域、轮廓进行仿射变换 4.根据特征点、角度计算仿射变

halcon 的图像坐标转到实际的机械坐标的标定

所谓手眼系统,就是人眼睛看到一个东西的时候要让手去抓取,就需要大脑知道眼睛和手的坐标关系。如果把大脑比作B,把眼睛比作A,把手比作C,如果A和B的关系知道,B和C的关系知道,那么C和A的关系就知道了,也就是手和眼的坐标关系也就知道了。 相机知道的是像素坐标,机械手是空间坐标系,所以手眼标定就是得到像素坐标系和空间机械手坐标系的坐标转化关系。 在实际控制中,相机检测到目标在图像中的像

C#版Halcon:HalconDotNet最详细最全面教程(万字详细总结)

文章目录 第一部分:Halcon基础1. Halcon简介Halcon的安装和配置 2. Halcon界面和工具图像显示窗口的使用 3. 图像处理基础图像的表示和存储图像的基本操作 4. 图像预处理图像增强技术图像去噪方法图像二值化 第二部分:Halcon进阶5. 形态学操作腐蚀和膨胀开运算和闭运算形态学梯度 6. 特征提取边缘检测角点检测区域特征 第三部分:Halcon高级应用7. 模

学习Halcon深度学习可以分为以下几个步骤

‌基础准备‌:‌了解深度学习基本概念,‌掌握Halcon软件的基本操作。‌ ‌理论学习‌:‌通过官方文档、‌教程和社区资源,‌学习Halcon中深度学习的原理、‌模型架构和训练方法。‌ ‌实践项目‌:‌参与实际项目,‌通过动手实践来加深理解和提升技能。‌可以从简单的图像分类任务开始,‌逐步扩展到目标检测、‌语义分割等复杂任务。‌ ‌持续学习‌:‌关注Halcon的更新和深度学习领域的新进展,‌不断

Halcon基于组件的模板匹配

Halcon基于组件的模板匹配 基于组件的模板匹配可以说是基于形状的模板匹配的加强版,加强的地方在于,这种方法允许模板中包含多个目标,并且允许目标之间存在相对运动(位移和旋转)。这决定了这种方式不适用于尺寸缩放的情况。由于有多个ROI,且需要检测多个ROI之间的相对运动关系,因此这种方法与基于形状的模板匹配相比要稍微复杂一点,且不适用于失焦图像和轻微形变的目标。图中是一个基于组件的模板匹配的例子

图像处理之仿射变换

仿射变换 什么是仿射变换仿射变换有什么用 什么是仿射变换 仿射变换(原图和一个矩阵进行运算)是指在几何中,图像从一个向量空间经过一次线性变换和一次平移,映射到另一个向量空间的过程。 这种变换可以保持图像的“平直性”和“平行性”,即直线经过仿射变换后仍然是直线,平行线经过变换后仍然保持平行。 仿射变换有什么用 图像校正: 当图像由于相机角度、镜头畸变或其他因素产生透视变形时,