这个步骤应该放在图像处理四部曲的前面,为什么呢?
举例说明: 你用相机每次拍照的图像,这个图像在相机里面视野中位置每次都有变化的。
根据不同机械设计能力,不同的方案,这个位置变化也是不一样的。
通常来说如果用分割器搬运物体这个位置变化应该在0.3MM-1MM之间。
有些极端的例子 比如检测运转中的物体,那么这种偏差就更大了。
图像在视野中的位置不确定,那么你后面的很多图像操作就不能用了,比如尺寸测量之类的。
××××××××××××××××××××××××××××××××××
为此我们提出仿射变化,根据图像中最明显的特征,生成一个变换矩阵,最后呢将图像变化到同一位置。
简而言之放射变化的流程是:
获得图像中最明显的特征元素说白了一眼就看出了,比如颜色反差很大的地方。
之后生成一个变换矩阵。
最后根据这个矩阵调整原始图像的位置, 这种调整可以平移 ,旋转,缩放,还有很多。
据我所知,基恩士 康耐士,欧姆龙都有位置自动调整的功能,所以众位做基于PC的视觉的老大,我们也要跟上。 不能被那帮做智能机的打败了。
×××××××××××××××××××××××××××××××××
后记:以上介绍放射变化的背景,并且说明了放射变化在整个图像处理过程中位置。
下面将详细说明仿射变化的操作流程。
仿射操作第一步:找特征 我们要找特征,那么特征要明显才好。 比如下面这张图, 最明显的是什么? 是秋叶 篮子 ,狗。。。。 记住灰度反差大的地方。 这里我们可以选择狗的眼睛 或是鼻子作为特征。 又比如下图 这张图的特征有很多,比如中间带有缺口圆就很不错。 ×××××××××××××××××××××××××××× 虽然仿射变化是排在图像处理四部曲之前的,但是对一些有噪声或模糊的图片 我们也可以进行一些 除噪声和边缘提取的工作,目的只是让获取的特征更加明显。 特别需要注意的是 不论是去噪声还是边缘提取都不可以让图过于失真,不然提取到的特征就是失真的。 仿射变换有两种策略(策略 呵呵 一听就是专业装13人士),找特征 一种是模板搜索 一种是边缘提取和形态学分析。 关于模板匹配搜索请见我的帖子:http://www.ihalcon.com/read-2749-1.html#18254 关于边缘提取和形态学分析。 请见我的影像处理四部曲。(由于我们选择的特征都是很明显的,所以使用到边缘提取和形态学分析会很简单) ××××××××××××××××××××××××××××××××××××××××××××××××××××××××××
仿射操作第二步: 生成变换矩阵(这名太恶心了,其实就是模板了 或是说MASK)
根据需要的特征数量,我们将生成仿射变化模板(这名是我自己取的)的函数分成三类。
一:根据一个特征 角度 生成仿射变化模板
甲:hom_mat2d_identity(生成一个空模板) hom_mat2d_rotate (向模板里添加旋转参数)
hom_mat2d_scale(向模板里添加缩放参数) hom_mat2d_translate(向模板里添加平移参数)
乙:vector_angle_to_rigid(直接生成一个参数齐全的模板)
参数依次是:原始点X Y 角度 最终点 X Y 角度 最后生成一个模板
二:根据两个以上特征生成仿射变化模板
甲:vector_to_rigid 生成一个可以进行旋转 平移 但不能缩放的模板
乙:vector_to_simlarity 生成一个可以 旋转 平移 缩放的 模板
三:根据三个以上特征生成仿射变化模板
甲:vector_to_hom_mat2d ???
乙:vector_to_hom_mat2d
这两个函数非常强大,强大到无法领悟。先将其供奉在这里 ,以后拆解。
××××××××××××××××××××××××××××××××××××××××××××××××××××××××××
仿射变化第三步: 使用仿射变换模板()
经过前面两步骤咱们生成了模板,说实话不容易。如果不容易得到的东西当然要好好使用。
贴心的HALCON 开发人员为我们送来了好多函数 用于使用这些模板。
他们是:
affine_trans_contout_xld
affine_trans_image
affine_trans_pixel
affine_trans_point_2d
affine_trans_polygon_xld
affine_trans_region
其实呢 还有很多。
××××××××××××
此处我们有两种个方向可以选择:
方向一:让图进行仿射变换,这样后面的图像处理工具或是函数的坐标参数就不用改了。
方向二:让图像处理工具或是函数的坐标进行仿射变换,图像的位置可以每张图都不同。
×××××××××××××××××××××××××××××××××××××××××××××× 首先从宏观上对例子进行分类。(宏观! 一股浩然之气油然而生) 啥叫宏观呢? 请看下图。 一: 有哪些特征提取方式呢? 前面说了 模板匹配搜索 和 边缘提取&形态学分析处理 二:有那些变换函数 这不是嘛 affine_trans_contout_xld affine_trans_image affine_trans_pixel affine_trans_point_2d affine_trans_polygon_xld affine_trans_region 一堆啊 HALCOIN这帮研发人员还是比较可人,封装了好多函数。(封装:专业计算术语,高能装B词汇。通杀计算编程低中高所以语言,你值得了解) 三:最后这条就不解释了。虽然我是幼儿园绘画水平 但是这几个你老人家想必是认识的。 ×××××××××××××××××××××××××××××××××××××××8 古人云 先易后难,做啥事都讲究个次第(佛教专业术语,此处不敢亵渎 。 其实就是顺序的意思)。 好了第一个例子是 使用全局阈值分割获取特征点, 然后使用 vector_angle_to_rigid 生成仿射变换矩阵(就是模板了) 最后让图像位置不调整,调整 ROI位置。 ×××××××××××××××××
前言:手上没有素材 就借用halcon学习网的素材,请不要介意。 ××××××××××××××××××××××××××××××××××××××××××××××××× 目标图标是: 看到这幅图像 , 估计大家一下就看出来了,我们选择中间白色圆的中心点做为特征点是相当合适的。 好处仿射变换处理第一步:特征点提取。 ***下面程序的目的是找出变换的原点 **************************************************************************** dev_set_color ('red') ** 读取第一个图像 ,用于提取特征点。 read_image(Image,'E:/HALCON 函数库/测试最简单的仿射变换/图片/1.bmp') **这么清楚的图像 整个全局阈值吧 threshold(Image, Region, 210, 255) connection(Region, ConnectedRegions) ** 可以用outer_radius (最小外接圆的半径的)来提取 **不过此处我用宽度'width'来提取 select_shape ( ConnectedRegions, SelectedRegions,\ [ 'circularity','width'], 'and', [0.8,120],[1,500]) fill_up (SelectedRegions, RegionFillUp) *获得ROI的质心((就是重心了) area_center(RegionFillUp, Area0, Row0, Column0) **将重心标记出来 dev_set_color ('green') **辛辛苦苦把特征点都逮着了 标记一下吧 不能让这货跑了。 gen_cross_contour_xld (Cross, Row0, Column0, 30, 0.785398) *******************************************************************************8 中间插一句: 我们先把我们变换的ROI给确定以后,当然了 你在后面 也是说不可以了。 这个ROI只是一个范例,正式操作的时候 可能有很多ROI了。 不过呢。。操作流程都是一样的。 **下面程序的目的创建一个矩形 这个矩形将在后面的被变换 **画出一个测定区域 dev_set_draw ('margin') * draw_rectangle1(3600,Row1, Column1, Row2, Column2) **使用上面的画出来的矩形坐标 gen_rectangle1 (Rectangle, 448, 940, 630, 1125) *****************
好了 特征点有了,要变换的ROI也有了。 我们就把要处理的图片导入 。开始计算变换矩阵。 使用变换矩阵去处理ROI了。 **正式开始对每一个图片变换 **使用助手创建一些可以自动读取图片的代码 * Image Acquisition 01: Code generated by Image Acquisition 01 list_files ('E:/HALCON 函数库/测试最简单的仿射变换/图片', ['files','follow_links'], ImageFiles) tuple_regexp_select (ImageFiles, ['\\.(tif|tiff|gif|bmp|jpg|jpeg|jp2|png|pcx|pgm|ppm|pbm|xwd|ima|hobj)$',\ 'ignore_case'], ImageFiles) for Index := 0 to |ImageFiles| - 1 by 1 dev_set_color ('red') read_image (Image, ImageFiles[Index]) **重复上面找特征点的过程 对每一个读取的图像进行处理。 threshold(Image, Region, 210, 255) connection(Region, ConnectedRegions) select_shape ( ConnectedRegions, SelectedRegions,\ [ 'circularity','width'], 'and', [0.8,120],[1,500]) fill_up (SelectedRegions, RegionFillUp) area_center(RegionFillUp, Area10, Row10, Column10) dev_set_color ('green') gen_cross_contour_xld (Cross10, Row10, Column10, 30, 0.785398) ******************************************** 最后开始变换就可以了。
**如果找到了 特征点 那么小伙伴们 就可以愉快的玩耍了
if(|Row10|>0)
**生成变化矩阵
vector_angle_to_rigid (Row0, Column0, 0, Row10, Column10, 0, HomMat2D)
**使用变换矩阵对前面话的ROI变换 位置 角度 开始位置补正《==》仿射变换《==》跟随 被变换的是那个矩形
affine_trans_region (Rectangle, RegionAffineTrans, HomMat2D, 'nearest_neighbor')
endif
stop()
dev_clear_window ()
endfor
后记:图片库最后一张图片 无法找到特征点。 所以需要改善 特征点寻找算法。
但是这不难。 随意留给的自己摸索和提升的地方。。
大家有答案了 可以在回帖中写出来。