勇哥大致看了一下halcon中有关region相关的官方例程,还是有一些很趣的东西。
因此有个想法是把它全部滤一遍,在这里记录一下以备查。
region的仿射变换
分割背景
识别圆盘上的条码
region裁剪
将区域相对于其大小剪裁为矩形
(1)region的仿射变换
dev_close_window () dev_open_window (0, 0, 512, 512, 'white', WindowID) dev_set_color ('black') * Draw with the mouse an arbitrary region into the window draw_region (Region, WindowID) hom_mat2d_identity (HomMat2DIdentity) hom_mat2d_rotate (HomMat2DIdentity, -0.3, 256, 256, HomMat2DRotate) hom_mat2d_scale (HomMat2DRotate, 1.5, 1.5, 256, 256, HomMat2DScale) affine_trans_region (Region, RegionAffineTrans, HomMat2DScale, 'nearest_neighbor') dev_clear_window () dev_set_draw ('margin') dev_set_color ('red') dev_display (Region) dev_set_color ('green') dev_display (RegionAffineTrans)
这个比较简单,没啥子好说的。
(2)分割背景
请结合代码看图片及注释。
sobel_amp的边缘分析结果
threshold的结果
background_seg背景分离算子的结果,这个算子是个新东西,看起来可以用来方便实现region相减的样子。
背景分离后有干扰,然后算子fill_up_shape在这里按特征"area"进行填洞。
fill_up_shape和fill_up的区别就在于多这个“特征”,支持以下的特征:
'anisometry', 'area', 'compactness', 'convexity', 'inner_circle', 'outer_circle', 'phi', 'ra', 'rb'
* 确定给定区域背景的连通分量 * read_image (Image, 'fabrik') * 找边 sobel_amp (Image, EdgeAmplitude, 'thin_sum_abs', 3) threshold (EdgeAmplitude, Edges, 5, 255) background_seg (Edges, BackgroundRegions) * 基于形状特征“area(区域)”填充区域中的孔 fill_up_shape (BackgroundRegions, RegionFillUp, 'area', 1, 40) dev_clear_window () dev_set_colored (6) dev_display (RegionFillUp)
这是一个好例子,赞美一下!
(三)识别圆盘上的条码
这个例子是极坐标算子polar_trans_image_ext的应用,详细请看勇哥的一篇文章:
这里我就不想再分析了,不想做重复工作。
* Read circularly printed bar codes. * dev_update_off () get_system ('clip_region', Information) set_system ('clip_region', 'true') read_image (Image, 'circular_barcode') get_image_size (Image, Width, Height) dev_close_window () dev_open_window (0, 0, Width / 2, Height / 2, 'black', WindowHandle) dev_set_colored (12) dev_display (Image) set_display_font (WindowHandle, 14, 'mono', 'true', 'false') stop () * * Segment the ring on the CD that contains the bar code. threshold (Image, Region, 0, 100) closing_circle (Region, Region, 3.5) connection (Region, ConnectedRegions) select_shape (ConnectedRegions, Ring, ['width','height'], 'and', [550,550], [750,750]) shape_trans (Ring, OuterCircle, 'outer_circle') complement (Ring, RegionComplement) connection (RegionComplement, ConnectedRegions) select_shape (ConnectedRegions, InnerCircle, ['width','height'], 'and', [450,450], [650,650]) * * Determine the parameters of the ring that contains the bar code. smallest_circle (Ring, Row, Column, OuterRadius) smallest_circle (InnerCircle, InnerRow, InnerColumn, InnerRadius) dev_set_color ('green') dev_set_draw ('margin') dev_set_line_width (3) dev_display (Image) dev_display (OuterCircle) dev_display (InnerCircle) stop () * * Now read the bar code. This is done by computing the polar transformation * of the ring in the image that contains the bar code. WidthPolar := 1440 HeightPolar := round(OuterRadius - InnerRadius - 10) polar_trans_image_ext (Image, PolarTransImage, Row, Column, rad(360), 0, OuterRadius - 5, InnerRadius + 5, WidthPolar, HeightPolar, 'bilinear') invert_image (PolarTransImage, ImageInvert) * * Since the bar code region is quite flat the image height is doubled. zoom_image_factor (ImageInvert, ImageZoomed, 1, 2, 'weighted') create_bar_code_model ([], [], BarCodeHandle) * * Bars are small and the contrast is low; therefore the threshold is raised from 0.05 to 0.1. set_bar_code_param (BarCodeHandle, 'element_size_min', 1.5) set_bar_code_param (BarCodeHandle, 'meas_thresh', 0.3) find_bar_code (ImageZoomed, SymbolRegions, BarCodeHandle, 'Code 128', DecodedDataStrings) dev_set_window_extents (-1, -1, WidthPolar / 2, HeightPolar) dev_display (ImageZoomed) dev_display (SymbolRegions) set_system ('clip_region', Information) disp_message (WindowHandle, DecodedDataStrings, 'image', 10, 180, 'black', 'true') stop () * * Transform the code region back to the original image and display it. zoom_region (SymbolRegions, SymbolRegions, 1, 0.5) polar_trans_region_inv (SymbolRegions, CodeRegionCircular, Row, Column, rad(360), 0, OuterRadius - 5, InnerRadius + 5, WidthPolar, HeightPolar, Width, Height, 'nearest_neighbor') dev_set_window_extents (-1, -1, Width / 2, Height / 2) dev_display (Image) dev_display (CodeRegionCircular) disp_message (WindowHandle, DecodedDataStrings, 'window', 12, 12, 'black', 'true')
(4)region裁剪
regiongrowing算子用来分割图片。
clip_region (Regions, RegionClippedWithEmptyRegions, 100, 100, 455, 455)
region分割的结果如下:
set_system ('store_empty_region', 'true')
*剪切之后,现在空的区域仍然被存储
set_system ('store_empty_region', 'false')
*剪裁后,将拒绝现在为空的区域
其差别体现在 count_obj结果上, 前者region数量不变,后者数量会变。
于是对于前者来讲,会出现为空的region,但是还是算数量。
所以单靠count_obj来判断是否有region是不可靠的,必须还要判断area是否为0。
* Init dev_update_off () read_image (Image, 'fabrik') regiongrowing (Image, Regions, 1, 1, 3, 100) count_obj (Regions, NumberOfOriginalRegions) * * Clip region in two ways get_system ('store_empty_region', Information) set_system ('store_empty_region', 'true') *剪切之后,现在空的区域仍然被存储 clip_region (Regions, RegionClippedWithEmptyRegions, 100, 100, 455, 455) count_obj (RegionClippedWithEmptyRegions, NumberOfClippedRegionsWithEmptyRegions) set_system ('store_empty_region', 'false') * 剪裁后,将拒绝现在为空的区域 clip_region (Regions, RegionClipped, 100, 100, 455, 455) count_obj (RegionClipped, NumberOfClippedRegionsWithoutEmptyRegions) * * Display results dev_close_window () get_image_size (Image, Width, Height) dev_open_window (0, 0, Width, Height, 'black', WindowHandle) set_display_font (WindowHandle, 16, 'mono', 'true', 'false') dev_display (Image) dev_set_colored (12) dev_display (Regions) disp_message (WindowHandle, NumberOfOriginalRegions + ' original regions', 'window', 12, 12, 'black', 'true') disp_continue_message (WindowHandle, 'black', 'true') stop () dev_display (Image) * dev_set_color ('white') * dev_display (Regions) dev_set_colored (12) dev_display (RegionClipped) disp_message (WindowHandle, NumberOfClippedRegionsWithoutEmptyRegions + ' clipped regions', 'image', 110, 110, 'blue', 'true') set_system ('store_empty_region', Information) dev_update_on ()
这个例子好歹也是说明了一个容易被乎视的知识点。
另外,regiongrowing算子还是很有用的。
(5)将区域相对于其大小剪裁为矩形
程序运行结果如下:
勇哥放大了一个局部。
算子clip_region_rel也就是按向内生长的矩形来裁剪region,下面是勇哥的示意图。
read_image (Alpha2, 'alpha2') dev_set_color ('red') threshold (Alpha2, Region, 0, 100) connection (Region, ConnectedRegions) dev_set_color ('green') clip_region (ConnectedRegions, RegionClipped, 100, 100, 400, 400) stop () dev_display (Alpha2) dev_set_color ('red') dev_display (Region) dev_set_color ('green') clip_region_rel (ConnectedRegions, RegionClipped1, 2, 2, 2, 2)
clip_region_rel这个算子,暂时想不出来有啥子用处。
---------------------
作者:hackpig
来源:www.skcircle.com
版权声明:本文为博主原创文章,转载请附上博文链接!

