Halcon中的坐标系特点及XLD的镜像转换

Posted xh6300

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Halcon中的坐标系特点及XLD的镜像转换相关的知识,希望对你有一定的参考价值。

 

我们知道,Halcon中的坐标系的原点在左上角,而一般二维平面坐标系的原点在左下角。那么Halcon中坐标系和一般的二维坐标系有什么区别呢?我通过下面这个例子来分析。

 

 1 gen_image_const (Image, \'byte\', 512, 512)
 2 dev_set_draw (\'margin\')
 3 
 4 *点1
 5 gen_circle (Circle1, 10, 10, 3)
 6 disp_message (3600, \'(10 ,10)\', \'image\', 2, 18, \'white\', \'false\')
 7 *点2
 8 gen_circle (Circle2, 100, 200, 3)
 9 disp_message (3600, \'(100 ,200)\', \'image\', 92, 208, \'white\', \'false\')
10 *点3
11 gen_circle (Circle3, 400, 100, 3)
12 disp_message (3600, \'(400 ,100)\', \'image\', 392, 108, \'white\', \'false\')
13 
14 union2 (Circle1,Circle2, RegionUnion)
15 union2 (RegionUnion,Circle2, RegionUnion)
16 union2 (RegionUnion,Circle3, RegionUnion)
17 gen_contour_region_xld (RegionUnion, Contours, \'border\')
18 write_contour_xld_dxf (Contours,\'C:/Users/happy xia/Desktop/XLD的镜像变换/threePoint.dxf\')

这三个点在Halcon中的位置如下图:

 

上面的程序最终生成了一个名为threePoint.dxf的文件。我用文本查看器(notepad++、记事本等)打开查看它的数据:

红框中“10”下面的数据代表点的x值,“20”下面的数据代表点的y值,即截图里有两个点(98.5, 396.5)、(99.5, 396.5),这两个点都是XLD圆上的点,很明显这两个点所在圆的圆心坐标是(100, 400)。但是我们看最开始的那张图,发现只有点(400, 100),并没有点(100, 400)!

 

根据上面的事实现象,我们不难发现Halcon中的坐标系实际是这样的:

 

根据导出的dxf文件中的坐标点反推,之前的那张图的点的坐标实际上是这样的:

 

这两个坐标系的区别如下图。不难看出,它们是上下镜像的关系(只需要用CAD看图软件打开threePoint.dxf文件一看便知)。

 

上文详细分析了Halcon坐标系的特点,由于有这样的特点,Halcon中的XLD和导出的dxf文件轮廓就存在上下镜像(上下颠倒)的关系,那么我们需要解决的一个问题就是:如何进行XLD的镜像转换?

 

镜像,对应的单词是“mirror”,我们在Halcon的帮助中搜索与之相关的算子,仅有mirror_imagemirror_region

 

根据我前面的博客文章,我们知道,如果XLD是闭合的,那么可将XLD转为Region,然后再转回XLD,因此可将Region作为中介,来镜像变换XLD。

 

方法一:以Region为中介,通过mirror_region算子间接对闭合XLD进行镜像转换。

 

原XLD如下图所示。

 

1 gen_image_const (Image, \'byte\', 7000, 5000)
2 read_contour_xld_dxf (Contours,\'unionContour.dxf\', [], [], DxfStatus)
3 
4 *方法1:先转换为Region,再镜像Region,最后转回到XLD
5 gen_region_contour_xld (Contours, Region, \'margin\')
6 mirror_region (Region, RegionMirror, \'row\', 6000)
7 gen_contour_region_xld (RegionMirror, ContoursMirror, \'border\')

效果如下:

 

方法二:由于XLD都是由点组成的,因此可以点对点镜像重绘

 1 gen_image_const (Image, \'byte\', 7000, 5000)
 2 read_contour_xld_dxf (Contours,\'unionContour.dxf\', [], [], DxfStatus)
 3 
 4 *方法2:点对点镜像重绘
 5 count_obj (Contours, Num)
 6 Step := 5
 7 axisValue := 6000
 8 
 9 gen_empty_obj (Contour2)
10 for i := 1 to Num by 1
11     select_obj (Contours, Contour, i)
12     get_contour_xld (Contour, Row, Col)
13     Row1 := []
14     Col1 := []
15     for j := 0 to |Row|-1 by Step
16         
17         Row1:=[Row1,axisValue - Row[j]]
18         Col1:=[Col1,Col[j]]
19         
20     endfor
21     
22     test_closed_xld (Contour, IsClosed)
23     if (IsClosed = 1)
24         Row1:=[Row1,axisValue - Row[0]]
25         Col1:=[Col1,Col[0]]
26     
27     endif
28     
29     gen_contour_polygon_xld (Contour1, Row1, Col1)
30     smooth_contours_xld (Contour1, SmoothedContours, 3)
31     concat_obj (Contour2, SmoothedContours, Contour2)
32 endfor

效果如下:

对于方法二程序有疑问的,可以参考我之前写的文章:http://www.cnblogs.com/xh6300/p/7414256.html

 

上面两种方法有一些小问题,不够完美。方法一主要的局限是只适用于闭合的XLD,方法二对点进行处理的时候,为提高运算速度进行了间隔采样,导致最终得到的XLD轮廓和初始XLD有细微差异。

 

其实Halcon还提供了一种最佳解决方案,即仿射变换:hom_mat2d_reflect —— 变换后的对象与初始对象相对于两点确定的一条直线彼此对称,其实就是镜像。

 

方法三:使用hom_mat2d_reflect 直接进行镜像的仿射变换

1 gen_image_const (Image, \'byte\', 7000, 5000)
2 read_contour_xld_dxf (Contours,\'unionContour.dxf\', [], [], DxfStatus)
3 
4 *方法3:使用仿射变换镜像
5 hom_mat2d_identity (HomMat2DIdentity)
6 hom_mat2d_reflect (HomMat2DIdentity, 3000, 0, 3000, 100, HomMat2DReflect)
7 affine_trans_contour_xld (Contours, ContoursAffinTrans, HomMat2DReflect)

效果如下:

 

以上是关于Halcon中的坐标系特点及XLD的镜像转换的主要内容,如果未能解决你的问题,请参考以下文章

Halcon中缩放Region或XLD的方法研究

Halcon数据类型转换系列图像image区域region和轮廓xld的相互转换(★firecat推荐★)

halcon怎样取得xld上最高的y方向最高点

图像处理halcon根据轮廓亚像素点坐标绘图并分割为直线圆弧椭圆段

图像处理halcon根据轮廓亚像素点坐标绘图并分割为直线圆弧椭圆段

halcon xld轮廓点到底指啥?具体啥意思?