勇哥的一个案子里需求如下:
分割出齿轮的小齿,小齿要排列规则,图像大小固定
由于齿轮数量有40多个,因此分割要求速度快
分割后的图片形成磁盘文件
(图1 分割后的图片样例)
(图2 要分割的齿轮和极坐标转换后的效果)
这个需求如果不考虑速度的话,是很简单的。
最简单的是转动图片固定角度,然后用一个矩形ROI去切割固定位置的小齿。
但是这个办法由于耗时太长,能实现功能,却达不到速度要求。
还有一个办法是crop_domain算子切割小齿,然后再仿射变换摆正姿式。
但是它有个问题是仿射变换后图像移动旋转会越界,造成生成的图片尺寸大小不一致。
另一个办法是本文说的极坐标转换。
其实它也有缺点,就是如果计算不合理的话,图像会变形或者像素有变化。
在这个案子里面,勇哥也是不得已而为之,因为它的速度能达到要求。
在算子polar_trans_image_ext中:
RowModel, ColumnModel是极坐标中心,你可以想像一下,一个平铺的小齿,由这个中心坐标旋转成齿轮的样子。
这个位置错了,极坐标结果就会有问题。
-0.07, PI*2-0.07 这个2pi是圆的一周,好理解。
但是-0.07这个可能不好理解,它类似于控制小齿的频率,例如这个例子小齿有48个,如果不设置这个值,你会发现展平的图像上面没有48个齿,或者第48个齿被分成左右两半。
在图2上面,由于展平的图像很长,勇哥把它截成上下两段放置,它是设置为-0.07的效果。
radiusStart, radiusEnd这个相当于平铺图像的高度,对于齿轮来说,它就是两个半径之间的部分,即我们想切出来的东西的径向半径。
c1, c2这个是生成平铺图像的宽高了。
这两个值是需要严格计算出来的,如果误差大,生成的图像就会变形或者有像素损失。
c1是宽度,它就是齿轮的周长2piR。
c2是高度。
gen_circle (ROI_1, 1523.25, 2142.02, 167.687) reduce_domain(ImageAffinTrans, ROI_1, ImageReduced2) threshold(ImageReduced2, t1, 200, 255) connection(t1, ConnectedRegions) select_shape(ConnectedRegions, SelectedRegions, 'area', 'and', 56000, 99999) area_center(SelectedRegions, Area1, RowModel, ColumnModel) gen_cross_contour_xld(Cross, RowModel, ColumnModel, 556, Angle) gen_circle(Circle1, RowModel, ColumnModel, 1480) gen_circle(Circle2, RowModel, ColumnModel, 1250) difference(Circle1, Circle2, RegionDifference1) reduce_domain(ImageAffinTrans, RegionDifference1, ImageReduced1) gen_circle(Circle3, RowModel, ColumnModel, 1430) PI:=3.1415926 SmoothX :=501 radiusStart:=1250 radiusEnd:=1480 c1:=PI*1430*2 c2:=1480-1250+1 get_image_size(ImageAffinTrans, Width3, Height3) polar_trans_image_ext(ImageAffinTrans, PolarTransImage, RowModel, ColumnModel, -0.07, PI*2-0.07, radiusStart, radiusEnd,\ c1, c2, 'nearest_neighbor') for i:=0 to 47 by 1 x1:=0 y1:=c1/48*i x2:=c2 y2:=c1/48*(i+1)+2 if(i=0) y2:=c1/48 endif gen_rectangle1(Rectangle1, x1,y1,x2,y2) *move_region(Rectangle1, RegionMoved, 0, c1/48*i+2) *dev_display(PolarTransImage) *dev_display(Rectangle1) reduce_domain(PolarTransImage, Rectangle1, ImageReduced3) crop_domain(ImageReduced3, ImagePart1) write_image(ImagePart1, 'bmp', 0, 'd:/splitImage/c'+i) endfor
勇哥以图2中故意放了几个符号:1, 5, A, b, c
好让你可以了解一下极坐标变换出来的平铺图像中的小齿位置对应原图上的哪里。
至于切割,因为极坐标已经把图像展平了,所以勇哥用了一个固定大小的Rectangle1在图像上滑动切割图像就可以了。
不考虑旋转角度的情况下,做啥子都方便了。
另外,如果你看到下面这样的变形图像,请不要以为结果是错误的。
只是你要手工调整一下显示窗口的大小以适应图像的长宽罢了。
其它极坐标的参考贴子如下:
Halcon极坐标转换,图文解说,含点坐标的转换 http://47.98.154.65/?id=1386
---------------------
作者:hackpig
来源:www.skcircle.com
版权声明:本文为博主原创文章,转载请附上博文链接!

