勇哥大致看了一下halcon中有关region相关的官方例程,还是有一些很趣的东西。
因此有个想法是把它全部滤一遍,在这里记录一下以备查。
area_center求面积中心
灰度区域和重心计算的精度分析
计算region的孔的面积
定位网格图形中的不规则部分(缺陷部分)
auto_threshold 自动阈值图像分割
(1) area_center求面积中心
area_center.hdev
read_image (Image, 'fabrik') dev_close_window () dev_open_window (0, 0, 512, 512, 'black', WindowID) set_display_font (WindowID, 14, 'mono', 'true', 'false') dev_set_colored (6) regiongrowing (Image, Regions, 1, 1, 3, 200) dev_set_draw ('margin') dev_display (Regions) area_center (Regions, Area, Row, Column) get_string_extents (WindowID, 12345, Ascent, Descent, TxtWidth, TxtHeight) disp_message (WindowID, Area, 'image', Row - TxtHeight / 2, Column - TxtWidth / 2, 'white', 'false')
例子中的算子get_string_extents 有点意思,是求字符串“12345”的像素点的总宽度与高度(TxtWidth, TxtHeight)
不过,这应该是默认字体大小下的结果吧?会不会设置字本大小后,这个计算也会跟着更新呢?
没试过,不过勇哥赌“会”。
(2)灰度区域和重心计算的精度分析
area_center_gray.hdev
此程序检查算子area_center_gray返回的灰度值特征的准确性。
这是通过将相应区域特征操作符area_center的输出结果与area_center_gray在等效灰度值图像上给出的结果进行比较来实现的,所述等效灰度值图像是在其中使用恒定灰度值绘制区域的图像和相同图像的缩小版本。
在第一种情况下,结果当然应该是相同的。
在第二种情况下,差异给出了在理想情况下可以实现的亚像素精度的指示。变量ScaleFactor可用于缩小图像,使对象具有所需的大小。
因此,通过改变该参数,可以确定对象在图像中必须有多大才能达到所需的亚像素精度。
重心的差异以原始图像的单位表示。
它们必须与ScaleFactor相乘才能得到亚像素坐标。
dev_update_off () Size := 512 Radius := 32 * 3 ScaleFactor := 1. / 32. Foreground := 200 gen_image_const (Image, 'byte', Size, Size) dev_close_window () dev_open_window (0, 0, Size, Size, 'black', WindowHandle) set_display_font (WindowHandle, 16, 'mono', 'true', 'false') dev_set_line_width (3) dev_set_draw ('margin') AreasRegion := [] AreasImage := [] AreasZoomed := [] RowsRegion := [] RowsImage := [] RowsZoomed := [] ColsRegion := [] ColsImage := [] ColsZoomed := [] for R := 0 to Radius * 2 by 1 * Create test image gen_circle (Circle, Size / 2 - Radius + R, Size / 2, Radius + 0.5) area_center (Circle, AreaRegion, RowRegion, ColumnRegion) paint_region (Circle, Image, ImageCircle, Foreground, 'fill') threshold (ImageCircle, Region, 1, 255) area_center_gray (Region, ImageCircle, AreaImage, RowImage, ColumnImage) zoom_image_factor (ImageCircle, ImageZoomed, ScaleFactor, ScaleFactor, 'constant') s1:=Size*ScaleFactor get_image_pointer1(ImageZoomed, Pointer, Type, Width, Height) threshold (ImageZoomed, RegionZoomed, 1, 255) area_center_gray (RegionZoomed, ImageZoomed, AreaZoomed, RowZoomed, ColumnZoomed) * Store area and position of reference region and results from zoomed image AreasRegion := [AreasRegion,AreaRegion] AreasImage := [AreasImage,AreaImage / Foreground] AreasZoomed := [AreasZoomed,AreaZoomed / (Foreground * ScaleFactor * ScaleFactor)] RowsRegion := [RowsRegion,RowRegion] RowsImage := [RowsImage,RowImage] RowsZoomed := [RowsZoomed,(RowZoomed + 0.5) / ScaleFactor - 0.5] ColsRegion := [ColsRegion,ColumnRegion] ColsImage := [ColsImage,ColumnImage] ColsZoomed := [ColsZoomed,(ColumnZoomed + 0.5) / ScaleFactor - 0.5] dev_display (ImageZoomed) * Visualize extraction results gen_ellipse_contour_xld (ContEllipse, RowZoomed, ColumnZoomed, 0, sqrt(AreaZoomed / (rad(180) * Foreground)), sqrt(AreaZoomed / (rad(180) * Foreground)), 0, rad(360), 'positive', 1) dev_display (ImageZoomed) disp_message (WindowHandle, ['Gray values > 0','Corresponding circle'], 'window', 12, 12, ['red','green'], 'false') dev_set_color ('green') dev_display (ContEllipse) dev_set_color ('red') dev_display (RegionZoomed) wait_seconds (0.01) endfor DiffAreaRegionImage := AreasRegion - AreasImage DiffAreaRegionZoomed := AreasRegion - AreasZoomed DiffRowRegionImage := RowsRegion - RowsImage DiffRowRegionZoomed := RowsRegion - RowsZoomed DiffColRegionImage := ColsRegion - ColsImage DiffColRegionZoomed := ColsRegion - ColsZoomed
这个例程有几点看头:
area_center_gray和area_center的区别
area_center_gray在计算面积和重心时会考虑图像的灰度值,area_center将中心计算为所有像素的线或列坐标的平均值。
请注意在程序中area_center返回行、列坐标的结果,是不带小数点后面有效位数的。这表明它求的结果最小单位是像素。
而area_center_gray求到的重点的行列坐标是带小数点后面数值的,这表明它的精度是在亚像素精度。
程序中使用gen_ellipse_contour_xld通过计算画出一个亚像素精度的椭圆,验证了area_center_gray求出重心的准确度。
(3)计算region的孔的面积
area_holes.hdev
* This example demonstrates the use of the operator area_holes. * * Setup display window dev_close_window () read_image (Image, 'rings_and_nuts') dev_open_window_fit_image (Image, 0, 0, -1, -1, WindowHandle) dev_set_color ('goldenrod') set_display_font (WindowHandle, 16, 'mono', 'true', 'false') dev_display (Image) * * Create a region threshold (Image, Region, 128, 255) * * Compute the area of the holes of the region area_holes (Region, Area) disp_message (WindowHandle, 'Size of enclosed area (holes): ' + Area + ' pixel', 'window', 12, 12, 'black', 'true') *
halcon为这个简单算子浪费一张例图,好浪费。
(4)定位网格图形中的不规则部分(缺陷部分)
atoms.hdev
感谢cctv,感谢政府,居然找到一个例子用到了几何矩属性,这真得很难得!
原图
找到的缺陷部分
* atoms.hdev: 定位网格图形中的不规则部分 * dev_close_window () dev_update_window ('off') * **** * Acquire image * **** read_image (Image, 'atoms') get_image_size (Image, Width, Height) crop_rectangle1 (Image, Image, Height / 2, 0, Height - 1, Width - 1) get_image_size (Image, Width, Height) dev_open_window_fit_image (Image, 0, 0, -1, -1, WindowID) set_display_font (WindowID, 14, 'mono', 'true', 'false') dev_set_draw ('margin') dev_set_line_width (2) dev_display (Image) disp_message (WindowID, 'Original image', 'window', 12, 12, 'black', 'true') disp_continue_message (WindowID, 'black', 'true') stop () * **** * 图像分割 * **** * -> Using watershed gauss_filter (Image, ImageGauss, 5) watersheds (ImageGauss, Basins, Watersheds) dev_display (Image) dev_set_colored (12) dev_display (Watersheds) disp_message (WindowID, 'Watersheds', 'window', 12, 12, 'black', 'true') disp_continue_message (WindowID, 'black', 'true') stop () * **** * 处理region * **** * -> 跳过图像边界的区域 smallest_rectangle1 (Basins, Row1, Column1, Row2, Column2) select_shape (Basins, SelectedRegions1, 'column1', 'and', 2, Width - 1) select_shape (SelectedRegions1, SelectedRegions2, 'row1', 'and', 2, Height - 1) select_shape (SelectedRegions2, SelectedRegions3, 'column2', 'and', 1, Width - 3) select_shape (SelectedRegions3, Inner, 'row2', 'and', 1, Height - 3) * -> 选择不规则形状部分(缺陷部分) select_shape (Inner, Irregular, ['moments_i1','moments_i1'], 'or', [0,9.5e8], [1.5e8,1e10]) dev_display (Image) dev_set_line_width (1) dev_set_color ('white') dev_display (Inner) dev_set_line_width (3) dev_set_color ('red') dev_display (Irregular) disp_message (WindowID, 'Defects', 'window', 12, 12, 'black', 'true')
我们直接看看这三个region的几何矩moments_i1的值是多少。
红:
绿:
蓝:
代码中设置的两组阈值是: 0到1.5e8, 9.5e8到1e10
再看几个正常的region的几何矩moments_i1,大约是这些值:
8.65874e8
6.50356e8
5.14910e8
勇哥放大了图片,3个ng的见箭头所示的,其它的网格region的moments_i1都在ok范围内。
moments_i1究竟是啥? 翻译是:
'moments_i1' 计算中心矩_二阶矩【 对应算子是: moments_region_central】
中心矩又是什么鬼呢?
这是计算机图形学一个概念,详细见: http://www.skcircle.com/?id=1654
(5)auto_threshold 自动阈值图像分割
auto_threshold.hdev
auto_threshold使用多个阈值分割单个通道图像。首先,确定灰度值的绝对直方图。然后,从直方图中提取相关的最小值,这些最小值被连续用作阈值运算的参数。用于字节图像的阈值为0、255,并且从直方图中提取的所有最小值(在直方图已使用具有标准偏差Sigma的高斯滤波器平滑后)。对于每个灰度值间隔, 生成一个区域。因此,区域的数量是最小值的数量+1。
选择的Sigma值越大,将提取的区域越少。
图2把图片的灰度直方图画出来了,它是一个双峰图像。这种种双峰图像是非常适合基于直方图的阈值算子来处理的,
例如本文讲的auto_threshold
下图是分割的结果。
(图1)
(图2)
dev_close_window () read_image (Aegypt1, 'egypt1') get_image_size (Aegypt1, Width, Height) dev_open_window (0, 0, Width, Height, 'black', WindowID) set_display_font (WindowID, 14, 'mono', 'true', 'false') dev_set_colored (6) dev_clear_window () Sigma :=2 auto_threshold (Aegypt1, Regions, Sigma) gray_histo (Aegypt1, Aegypt1, AbsoluteHisto, RelativeHisto) disp_continue_message (WindowID, 'black', 'true') stop () dev_clear_window () create_funct_1d_array (AbsoluteHisto, Function) smooth_funct_1d_gauss (Function, Sigma, SmoothedFunction) dev_set_color ('red') funct_1d_to_pairs (SmoothedFunction, XValues, YValues) gen_region_histo (Histo1, YValues, 255, 255, 1) dev_display (Aegypt1) dev_set_color ('white') gen_region_histo (Histo2, RelativeHisto, 255, 255, 1) dev_display (Regions)
其它看点:
create_funct_1d_array, smooth_funct_1d_gauss
直方图数据是可以用函数方式来处理,create_funct_1d_array就是创建函数的数据集。
smooth_funct_1d_gauss则是用高斯模糊的方式对数据集进行处理。
gen_region_histo
生成一个region类型的直方图,然后可以显示出来。
---------------------
作者:hackpig
来源:www.skcircle.com
版权声明:本文为博主原创文章,转载请附上博文链接!

