学习一下region的官方示例,看看有啥未知的知识点(二)

勇哥大致看了一下halcon中有关region相关的官方例程,还是有一些很趣的东西。

因此有个想法是把它全部滤一遍,在这里记录一下以备查。


  • area_center求面积中心

  • 灰度区域和重心计算的精度分析   

  • 计算region的孔的面积

  • 定位网格图形中的不规则部分(缺陷部分)

  • auto_threshold 自动阈值图像分割



(1) area_center求面积中心

area_center.hdev

image.png

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相乘才能得到亚像素坐标。


image.png

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


这个例程有几点看头:

  1.  area_center_gray和area_center的区别

    area_center_gray在计算面积和重心时会考虑图像的灰度值,area_center将中心计算为所有像素的线或列坐标的平均值。

    请注意在程序中area_center返回行、列坐标的结果,是不带小数点后面有效位数的。这表明它求的结果最小单位是像素。

    而area_center_gray求到的重点的行列坐标是带小数点后面数值的,这表明它的精度是在亚像素精度。

    image.png

  2. 程序中使用gen_ellipse_contour_xld通过计算画出一个亚像素精度的椭圆,验证了area_center_gray求出重心的准确度。


(3)计算region的孔的面积

area_holes.hdev

image.png

* 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,感谢政府,居然找到一个例子用到了几何矩属性,这真得很难得!


原图

image.png

找到的缺陷部分

image.png


* 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的值是多少。

红:image.png

绿:image.png

蓝:image.png

代码中设置的两组阈值是: 0到1.5e8,  9.5e8到1e10

image.png

再看几个正常的region的几何矩moments_i1,大约是这些值:

8.65874e8

6.50356e8

5.14910e8


勇哥放大了图片,3个ng的见箭头所示的,其它的网格region的moments_i1都在ok范围内。

image.png


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


下图是分割的结果。

image.png

(图1)

image.png

(图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)


其它看点:

  1.  create_funct_1d_array, smooth_funct_1d_gauss 

    直方图数据是可以用函数方式来处理,create_funct_1d_array就是创建函数的数据集。

     smooth_funct_1d_gauss则是用高斯模糊的方式对数据集进行处理。

  2. gen_region_histo 

    生成一个region类型的直方图,然后可以显示出来。


--------------------- 

作者:hackpig

来源:www.skcircle.com

版权声明:本文为博主原创文章,转载请附上博文链接!



本文出自勇哥的网站《少有人走的路》wwww.skcircle.com,转载请注明出处!讨论可扫码加群:

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

会员中心
搜索
«    2024年3月    »
123
45678910
11121314151617
18192021222324
25262728293031
网站分类
标签列表
最新留言
    热门文章 | 热评文章 | 随机文章
文章归档
友情链接
  • 订阅本站的 RSS 2.0 新闻聚合
  • 扫描加本站机器视觉QQ群,验证答案为:halcon勇哥的机器视觉
  • 点击查阅微信群二维码
  • 扫描加勇哥的非标自动化群,验证答案:C#/C++/VB勇哥的非标自动化群
  • 扫描加站长微信:站长微信:abc496103864
  • 扫描加站长QQ:
  • 扫描赞赏本站:
  • 留言板:

Powered By Z-BlogPHP 1.7.2

Copyright Your skcircle.com Rights Reserved.

鄂ICP备18008319号


站长QQ:496103864 微信:abc496103864