勇哥大致看了一下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
版权声明:本文为博主原创文章,转载请附上博文链接!

