Halcon斑点分析官方示例讲解

Posted morganma

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Halcon斑点分析官方示例讲解相关的知识,希望对你有一定的参考价值。

官方示例中有许多很好的例子可以帮助大家理解和学习Halcon,下面举几个经典的斑点分析例子讲解一下

Crystals

技术图片

图中显示了在高层大气中采集到的晶体样本的图像。任务是分析对象以确定特定形状的频率。重要的对象之一是六角形。

首先,使用read_image从文件中读取图像。由于晶体的对比度相对较低且结合了不均匀的背景,因此使用局部阈值执行对象的分割。该轮次由平均过滤器mean_image确定。选择滤光罩的尺寸,使其具有暗区宽度的大约三倍。 dyn_threshold现在将平滑的和原始的灰色进行比较,选择那些通过8个灰度值的对比而变暗的像素。connection将对象分为连接的组件。下图显示了此初始分割的结果。

read_image (Image, ‘crystal‘)
mean_image (Image, ImageMean, 21, 21)
dyn_threshold (Image, ImageMean, RegionDynThresh, 8, ‘dark‘)
connection (RegionDynThresh, ConnectedRegions)

技术图片

现在的任务是仅选择六边形的晶体。为此,首先变成他们的凸包,这就像在每个区域周围都使用橡皮筋。在这些区域中,选择那些具有较大的(select_shape)并具有给定灰度值分布(select_gray)的对象。确定选择的参数,以便仅保留相关的晶体如下图。

shape_trans (ConnectedRegions, ConvexRegions, ‘convex‘)
select_shape (ConvexRegions, LargeRegions, ‘area‘, ‘and‘, 600, 2000)
select_gray (LargeRegions, Image, Crystals, ‘entropy‘, ‘and‘, 1, 5.6)

技术图片

源程序

* crystal.hdev: extraction of hexagonally shaped crystals via local thresholding and region post-processing
* 
dev_close_window ()
dev_update_window (‘off‘)
* ****
* step: acquire image获取图像
* ****
read_image (Image, ‘crystal‘)
get_image_size (Image, Width, Height)
dev_open_window_fit_image (Image, 0, 0, Width, Height, WindowID)
set_display_font (WindowID, 12, ‘mono‘, ‘true‘, ‘false‘)
dev_set_draw (‘margin‘)
dev_set_line_width (2)
dev_display (Image)
disp_continue_message (WindowID, ‘black‘, ‘true‘)
stop ()
* ****
* step: segment image分割图像
* ****
* -> using a local threshold
mean_image (Image, ImageMean, 21, 21)
dyn_threshold (Image, ImageMean, RegionDynThresh, 8, ‘dark‘)
* -> extract connected components
connection (RegionDynThresh, ConnectedRegions)
dev_display (ConnectedRegions)
disp_continue_message (WindowID, ‘black‘, ‘true‘)
stop ()
* ****
* step: process regions处理区域
* ****
shape_trans (ConnectedRegions, ConvexRegions, ‘convex‘)
select_shape (ConvexRegions, LargeRegions, ‘area‘, ‘and‘, 600, 2000)
select_gray (LargeRegions, Image, Crystals, ‘entropy‘, ‘and‘, 1, 5.6)
dev_display (Image)
dev_display (Crystals)
Atoms

技术图片

专业显微镜能够确定单个原子的大致位置,这对于例如分析PN结晶体的晶格变化很有用,使用分水岭方法在这类图片上细分效果很好。在这里,每个暗区作为单个区域返回。因为在图像的外部原子仅部分可见,第一个任务是仅提取那些不靠近图像边界的原子。最后提取不规则,这是通过寻找形状(被挤压)的异常原子实现的。

gauss_filter (Image, ImageGauss, 5)
watersheds (ImageGauss, Basins, Watersheds)

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])

分水岭方法划分图像
技术图片

结果图
技术图片

源程序

* atoms.hdev: Locates irregularities in an atomic grid structure
* 
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 ()
* ****
* Segment image分割图像
* ****
* -> 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 ()
* ****
* Process regions处理区域
* ****
* -> Skip regions at the border of the image
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 irregularly shaped atoms
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‘)
Analyzing Particles

技术图片

本示例的任务是分析液体中的颗粒。此应用程序的主要困难是存在两种类型的物体:大的明亮物体和对比度低的小物体。此外,还存在噪音干扰。

该程序使用两种不同的方法分别对两类对象进行分段:全局阈值和局部阈值。通过附加的后处理,可以以可靠的方式提取小颗粒。

threshold (Image, Large, 110, 255)
dilation_circle (Large, LargeDilation, 7.5)

complement (LargeDilation, NotLarge)
reduce_domain (Image, NotLarge, ParticlesRed)
mean_image (ParticlesRed, Mean, 31, 31)
dyn_threshold (ParticlesRed, Mean, SmallRaw, 3, ‘light‘)
opening_circle (SmallRaw, Small, 2.5)
connection (Small, SmallConnection)

技术图片
技术图片

源程序

* particle.hdev: Measurement of small particles
* 
dev_update_off ()
dev_close_window ()
dev_open_window (0, 0, 512, 512, ‘black‘, WindowID)
set_display_font (WindowID, 14, ‘mono‘, ‘true‘, ‘false‘)
read_image (Image, ‘particle‘)
dev_display (Image)
dev_disp_text (‘Original image‘, ‘window‘, 12, 12, ‘black‘, [], [])
dev_disp_text (‘Press Run (F5) to continue‘, ‘window‘, ‘bottom‘, ‘right‘, ‘black‘, [], [])
stop ()
threshold (Image, Large, 110, 255)
* Dilate regions with a circular structuring element
dilation_circle (Large, LargeDilation, 7.5)
dev_display (Image)
dev_set_draw (‘margin‘)
dev_set_line_width (3)
dev_set_color (‘red‘)
dev_display (LargeDilation)
dev_set_draw (‘fill‘)
dev_disp_text (‘Exclude large areas from processing‘, ‘window‘, 12, 12, ‘black‘, [], [])
dev_disp_text (‘Press Run (F5) to continue‘, ‘window‘, ‘bottom‘, ‘right‘, ‘black‘, [], [])
stop ()
* Continue to calculate small regions
* Return the complement of a region
complement (LargeDilation, NotLarge)
reduce_domain (Image, NotLarge, ParticlesRed)
mean_image (ParticlesRed, Mean, 31, 31)
* Segment the image using a local threshold
dyn_threshold (ParticlesRed, Mean, SmallRaw, 3, ‘light‘)
opening_circle (SmallRaw, Small, 2.5)
connection (Small, SmallConnection)
dev_display (Image)
dev_set_colored (12)
dev_display (SmallConnection)
dev_disp_text (‘Extracted small particles‘, ‘window‘, 12, 12, ‘black‘, [], [])
dev_disp_text (‘Press Run (F5) to continue‘, ‘window‘, ‘bottom‘, ‘right‘, ‘black‘, [], [])
stop ()
* Continue to select several regions and to get information
dev_set_color (‘green‘)
dev_display (Image)
dev_set_draw (‘margin‘)
dev_display (SmallConnection)
Button := 1
* Define limits for the displayed message at the end of the while-loop.
MaxRow := 450
MaxColumn := 440
MinRow := 40
MinColumn := 100
while (Button == 1)
    dev_disp_text ([‘Select object with left mouse button‘,‘Right button to quit‘], ‘window‘, 12, 12, ‘black‘, ‘box_color‘, ‘#fce9d4dd‘)
    dev_set_color (‘green‘)
    get_mbutton (WindowID, Row, Column, Button)
    dev_display (Image)
    dev_display (SmallConnection)
    dev_set_color (‘red‘)
    select_region_point (SmallConnection, SmallSingle, Row, Column)
    dev_display (SmallSingle)
    count_obj (SmallSingle, NumSingle)
    if (NumSingle == 1)
        intensity (SmallSingle, Image, MeanGray, DeviationGray)
        area_center (SmallSingle, Area, Row, Column)
        * Limit the message so that it is displayed entirely inside the graphics window.
        if (Row > MaxRow)
            Row := MaxRow
        endif
        if (Column > MaxColumn)
            Column := MaxColumn
        endif
        if (Row < MinRow)
            Row := MinRow
        endif
        if (Column < MinColumn)
            Column := MinColumn
        endif
        dev_disp_text ([‘Area = ‘ + Area,‘Intensity = ‘ + MeanGray$‘.3‘], ‘image‘, Row + 10, Column - 90, ‘black‘, ‘box_color‘, ‘#fce9d4dd‘)
    endif
endwhile
dev_set_line_width (1)
dev_update_on ()
Extracting Forest Features from Color Infrared Image

技术图片

本示例的任务是在图中所示的彩色红外图像中检测不同的对象类别:树(针叶和落叶),草地和道路

图像数据是彩色红外图像,由于其特定的颜色,可以非常轻松地提取道路。需要做到那样的话,要将多通道图像拆分为单通道。

read_image (Forest, ‘forest_air1‘)
decompose3 (Forest, Red, Green, Blue)
threshold (Blue, BlueBright, 80, 255)
connection (BlueBright, BlueBrightConnection)
select_shape (BlueBrightConnection, Path, ‘area‘, ‘and‘, 100, 100000000)

山毛榉树根据其在红色通道中的强度和最小大小进行分割

threshold (Red, RedBright, 120, 255)
connection (RedBright, RedBrightConnection)
select_shape (RedBrightConnection, RedBrightBig, ‘area‘, ‘and‘, 1500, 10000000)
closing_circle (RedBrightBig, RedBrightClosing, 7.5)
opening_circle (RedBrightClosing, RedBrightOpening, 9.5)
connection (RedBrightOpening, RedBrightOpeningConnection)
select_shape (RedBrightOpeningConnection, BeechBig, ‘area‘, ‘and‘, 1000, 100000000)
select_gray (BeechBig, Blue, Beech, ‘mean‘, ‘and‘, 0, 59)

技术图片

草地具有相似的光谱特性,但亮度略高

union1 (Beech, BeechUnion)
complement (BeechUnion, NotBeech)
difference (NotBeech, Path, NotBeechNotPath)
reduce_domain (Red, NotBeechNotPath, NotBeechNotPathRed)
threshold (NotBeechNotPathRed, BrightRest, 150, 255)
connection (BrightRest, BrightRestConnection)
select_shape (BrightRestConnection, Meadow, ‘area‘, ‘and‘, 500, 1000000)

技术图片

使用分水岭方法提取针叶树,并在盆地内部增加阈值

union2 (Path, RedBrightClosing, BeechPath)
smooth_image (Red, RedGauss, ‘gauss‘, 4.0)
invert_image (RedGauss, Invert)
watersheds (Invert, SpruceRed, Watersheds)
select_shape (SpruceRed, SpruceRedLarge, ‘area‘, ‘and‘, 100, 5000)
select_gray (SpruceRedLarge, Red, SpruceRedInitial, ‘max‘, ‘and‘, 100, 200)
gen_empty_obj (LocalThresh)
count_obj (SpruceRedInitial, NumSpruce)
dev_update_var (‘off‘)
dev_update_pc (‘off‘)
for i := 1 to NumSpruce by 1
    select_obj (SpruceRedInitial, SingleSpruce, i)
    min_max_gray (SingleSpruce, Red, 50, Min, Max, Range)
    reduce_domain (Red, SingleSpruce, SingleSpruceRed)
    threshold (SingleSpruceRed, SingleSpruceBright, Min, 255)
    connection (SingleSpruceBright, SingleSpruceBrightCon)
    select_shape_std (SingleSpruceBrightCon, MaxAreaSpruce, ‘max_area‘, 70)
    concat_obj (MaxAreaSpruce, LocalThresh, LocalThresh)
endfor
opening_circle (LocalThresh, FinalSpruce, 1.5)

技术图片

源程序

dev_close_window ()
dev_update_window (‘off‘)
read_image (Forest, ‘forest_air1‘)
get_image_size (Forest, Width, Height)
dev_open_window (0, 0, Width, Height, ‘black‘, WindowHandle)
decompose3 (Forest, Red, Green, Blue)
dev_display (Red)
threshold (Blue, BlueBright, 80, 255)
connection (BlueBright, BlueBrightConnection)
select_shape (BlueBrightConnection, Path, ‘area‘, ‘and‘, 100, 100000000)
dev_set_color (‘red‘)
dev_set_draw (‘margin‘)
dev_display (Path)
disp_continue_message (WindowHandle, ‘black‘, ‘true‘)
stop ()
threshold (Red, RedBright, 120, 255)
connection (RedBright, RedBrightConnection)
select_shape (RedBrightConnection, RedBrightBig, ‘area‘, ‘and‘, 1500, 10000000)
closing_circle (RedBrightBig, RedBrightClosing, 7.5)
opening_circle (RedBrightClosing, RedBrightOpening, 9.5)
connection (RedBrightOpening, RedBrightOpeningConnection)
select_shape (RedBrightOpeningConnection, BeechBig, ‘area‘, ‘and‘, 1000, 100000000)
select_gray (BeechBig, Blue, Beech, ‘mean‘, ‘and‘, 0, 59)
dev_display (Red)
dev_display (Beech)
disp_continue_message (WindowHandle, ‘black‘, ‘true‘)
stop ()
union1 (Beech, BeechUnion)
complement (BeechUnion, NotBeech)
difference (NotBeech, Path, NotBeechNotPath)
reduce_domain (Red, NotBeechNotPath, NotBeechNotPathRed)
threshold (NotBeechNotPathRed, BrightRest, 150, 255)
connection (BrightRest, BrightRestConnection)
select_shape (BrightRestConnection, Meadow, ‘area‘, ‘and‘, 500, 1000000)
dev_display (Red)
dev_display (Meadow)
disp_continue_message (WindowHandle, ‘black‘, ‘true‘)
stop ()
union2 (Path, RedBrightClosing, BeechPath)
smooth_image (Red, RedGauss, ‘gauss‘, 4.0)
invert_image (RedGauss, Invert)
watersheds (Invert, SpruceRed, Watersheds)
select_shape (SpruceRed, SpruceRedLarge, ‘area‘, ‘and‘, 100, 5000)
select_gray (SpruceRedLarge, Red, SpruceRedInitial, ‘max‘, ‘and‘, 100, 200)
gen_empty_obj (LocalThresh)
count_obj (SpruceRedInitial, NumSpruce)
dev_update_var (‘off‘)
dev_update_pc (‘off‘)
for i := 1 to NumSpruce by 1
    select_obj (SpruceRedInitial, SingleSpruce, i)
    min_max_gray (SingleSpruce, Red, 50, Min, Max, Range)
    reduce_domain (Red, SingleSpruce, SingleSpruceRed)
    threshold (SingleSpruceRed, SingleSpruceBright, Min, 255)
    connection (SingleSpruceBright, SingleSpruceBrightCon)
    select_shape_std (SingleSpruceBrightCon, MaxAreaSpruce, ‘max_area‘, 70)
    concat_obj (MaxAreaSpruce, LocalThresh, LocalThresh)
endfor
opening_circle (LocalThresh, FinalSpruce, 1.5)
dev_set_line_width (2)
dev_set_color (‘red‘)
dev_display (Red)
dev_display (FinalSpruce)
dev_set_color (‘green‘)
dev_display (Beech)
dev_set_color (‘yellow‘)
dev_display (Meadow)
Checking a Boundary for Fins

技术图片

本示例的任务是检查塑料零件的外边界。在这种情况下,某些对象会显示鳍

程序首先提取背景区域(鳍显示为压痕)

binary_threshold (Fin, Background, ‘max_separability‘, ‘light‘, UsedThreshold)

技术图片

然后使用形态学运算符关闭背景区域中的压痕

 closing_circle (Background, ClosedBackground, 250)

技术图片

封闭区域与原始区域之间的显著差异是鳍

 difference (ClosedBackground, Background, RegionDifference)
 opening_rectangle1 (RegionDifference, FinRegion, 5, 5)

技术图片

源程序

* fin.hdev: Detection of a fin
* 
dev_update_window (‘off‘)
read_image (Fins, ‘fin‘ + [1:3])
get_image_size (Fins, Width, Height)
dev_close_window ()
dev_open_window (0, 0, Width[0], Height[0], ‘black‘, WindowID)
set_display_font (WindowID, 14, ‘mono‘, ‘true‘, ‘false‘)
for I := 1 to 3 by 1
    select_obj (Fins, Fin, I)
    dev_display (Fin)
    binary_threshold (Fin, Background, ‘max_separability‘, ‘light‘, UsedThreshold)
    dev_set_color (‘blue‘)
    dev_set_draw (‘margin‘)
    dev_set_line_width (4)
    dev_display (Background)
    disp_continue_message (WindowID, ‘black‘, ‘true‘)
    stop ()
    closing_circle (Background, ClosedBackground, 250)
    dev_set_color (‘green‘)
    dev_display (ClosedBackground)
    disp_continue_message (WindowID, ‘black‘, ‘true‘)
    stop ()
    difference (ClosedBackground, Background, RegionDifference)
    opening_rectangle1 (RegionDifference, FinRegion, 5, 5)
    dev_display (Fin)
    dev_set_color (‘red‘)
    dev_display (FinRegion)
    area_center (FinRegion, FinArea, Row, Column)
    if (I < 3)
        disp_continue_message (WindowID, ‘black‘, ‘true‘)
        stop ()
    endif
endfor
Bonding Balls

技术图片

本示例的任务是检查图中PCB板所示的球形键合直径

球形键的提取有两个步骤:首先,通过分割亮区来定位裸片,然后将它们转换为最小的矩形

threshold (Bond, Bright, 100, 255)
shape_trans (Bright, Die, ‘rectangle2‘)

技术图片

现在,使用reduce_domain处理模具内部的区域。在此ROI中,程序检查与线材相对应的深色区域

reduce_domain (Bond, Die, DieGrey)
threshold (DieGrey, Wires, 0, 50)
fill_up_shape (Wires, WiresFilled, ‘area‘, 1, 100)

技术图片

删除不相关的结构,并按预定顺序排列键提取所需的特征

opening_circle (WiresFilled, Balls, 15.5)
connection (Balls, SingleBalls)
select_shape (SingleBalls, IntermediateBalls, ‘circularity‘, ‘and‘, 0.85, 1.0)
sort_region (IntermediateBalls, FinalBalls, ‘first_point‘, ‘true‘, ‘column‘)
smallest_circle (FinalBalls, Row, Column, Radius)

源代码

* ball.hdev: Inspection of Ball Bonding
* 
dev_update_window (‘off‘)
dev_close_window ()
dev_open_window (0, 0, 728, 512, ‘black‘, WindowID)
read_image (Bond, ‘die/die_03‘)
dev_display (Bond)
set_display_font (WindowID, 14, ‘mono‘, ‘true‘, ‘false‘)
disp_continue_message (WindowID, ‘black‘, ‘true‘)
stop ()
threshold (Bond, Bright, 100, 255)
shape_trans (Bright, Die, ‘rectangle2‘)
dev_set_color (‘green‘)
dev_set_line_width (3)
dev_set_draw (‘margin‘)
dev_display (Die)
disp_continue_message (WindowID, ‘black‘, ‘true‘)
stop ()
reduce_domain (Bond, Die, DieGrey)
threshold (DieGrey, Wires, 0, 50)
fill_up_shape (Wires, WiresFilled, ‘area‘, 1, 100)
dev_display (Bond)
dev_set_draw (‘fill‘)
dev_set_color (‘red‘)
dev_display (WiresFilled)
disp_continue_message (WindowID, ‘black‘, ‘true‘)
stop ()
opening_circle (WiresFilled, Balls, 15.5)
dev_set_color (‘green‘)
dev_display (Balls)
disp_continue_message (WindowID, ‘black‘, ‘true‘)
stop ()
connection (Balls, SingleBalls)
select_shape (SingleBalls, IntermediateBalls, ‘circularity‘, ‘and‘, 0.85, 1.0)
sort_region (IntermediateBalls, FinalBalls, ‘first_point‘, ‘true‘, ‘column‘)
dev_display (Bond)
dev_set_colored (12)
dev_display (FinalBalls)
disp_continue_message (WindowID, ‘black‘, ‘true‘)
stop ()
smallest_circle (FinalBalls, Row, Column, Radius)
NumBalls := |Radius|
Diameter := 2 * Radius
meanDiameter := mean(Diameter)
minDiameter := min(Diameter)
dev_display (Bond)
disp_circle (WindowID, Row, Column, Radius)
dev_set_color (‘white‘)
disp_message (WindowID, ‘D: ‘ + Diameter$‘.4‘, ‘image‘, Row - 2 * Radius, Column, ‘white‘, ‘false‘)
dev_update_window (‘on‘)
Surface Scratches

技术图片

本示例检测金属表面上的划痕
分割的主要困难是背景不均匀以及划痕是薄的结构。可以使用局部阈值解决这两个问题。即算子mean_image和dyn_threshold,在connection后,将小对象(主要是噪声)移除

mean_image (Image, ImageMean, 7, 7)
dyn_threshold (Image, ImageMean, DarkPixels, 5, ‘dark‘)
connection (DarkPixels, ConnectedRegions)
select_shape (ConnectedRegions, SelectedRegions, ‘area‘, ‘and‘, 10, 1000)

技术图片

选择的一部分是划痕,但是如果我们仔细观察,就会发现它们被部分分割了。为了解决这个问题,我们将所有分割部分再次合并到一个大区域中。通过应用dilation_circle将具有给定最大距离的物体组合在一起。最终获得正确形状的划痕。由于膨胀的缘故,使用skeleton将形状变薄到一个像素的宽度

union1 (SelectedRegions, RegionUnion)
dilation_circle (RegionUnion, RegionDilation, 3.5)
skeleton (RegionDilation, Skeleton)
connection (Skeleton, Errors)

技术图片

技术图片

最后一步是区分表面上的小点和划痕。这是通过使用大小作为特征的select_shape实现的。

select_shape (Errors, Scratches, ‘area‘, ‘and‘, 50, 10000)
select_shape (Errors, Dots, ‘area‘, ‘and‘, 1, 50)

技术图片

源代码

* This programm shows the extraction of surface scratches via
* local thresholding and morphological post-processing
* 
dev_update_off ()
dev_close_window ()
* 
* Step 1: Acquire image
* 
read_image (Image, ‘surface_scratch‘)
get_image_size (Image, Width, Height)
dev_open_window_fit_image (Image, 0, 0, Width, Width, WindowID)
set_display_font (WindowID, 16, ‘mono‘, ‘true‘, ‘false‘)
dev_set_draw (‘margin‘)
dev_set_line_width (4)
dev_display (Image)
Message := ‘This program shows the extraction of‘
Message[1] := ‘surface scratches via local thresholding‘
Message[2] := ‘and morphological post-processing‘
disp_message (WindowID, Message, ‘window‘, 12, 12, ‘black‘, ‘true‘)
disp_continue_message (WindowID, ‘black‘, ‘true‘)
stop ()
* 
* Step 2: Segment image
* 
* Using a local threshold
mean_image (Image, ImageMean, 7, 7)
dyn_threshold (Image, ImageMean, DarkPixels, 5, ‘dark‘)
* 
* Extract connected components
connection (DarkPixels, ConnectedRegions)
dev_set_colored (12)
dev_display (Image)
dev_display (ConnectedRegions)
Message := ‘Connected components after image segmentation‘
Message[1] := ‘using a local threshold.‘
disp_message (WindowID, Message, ‘window‘, 12, 12, ‘black‘, ‘true‘)
disp_continue_message (WindowID, ‘black‘, ‘true‘)
stop ()
* 
* Step 3: Process regions
* 
* Select large regions
select_shape (ConnectedRegions, SelectedRegions, ‘area‘, ‘and‘, 10, 1000)
dev_display (Image)
dev_display (SelectedRegions)
disp_message (WindowID, ‘Large Regions‘, ‘window‘, 12, 12, ‘black‘, ‘true‘)
disp_continue_message (WindowID, ‘black‘, ‘true‘)
stop ()
* 
* Visualize fractioned scratch
open_zoom_window (0, round(Width / 2), 2, 303, 137, 496, 3, WindowHandleZoom)
dev_set_color (‘blue‘)
dev_display (Image)
dev_display (SelectedRegions)
set_display_font (WindowHandleZoom, 16, ‘mono‘, ‘true‘, ‘false‘)
disp_message (WindowHandleZoom, ‘Fractioned scratches‘, ‘window‘, 12, 12, ‘black‘, ‘true‘)
disp_continue_message (WindowHandleZoom, ‘black‘, ‘true‘)
stop ()
* 
* Merge fractioned scratches via morphology
union1 (SelectedRegions, RegionUnion)
dilation_circle (RegionUnion, RegionDilation, 3.5)
dev_display (Image)
dev_display (RegionDilation)
Message := ‘Region of the scratches after dilation‘
disp_message (WindowHandleZoom, Message, ‘window‘, 12, 12, ‘black‘, ‘true‘)
disp_continue_message (WindowHandleZoom, ‘black‘, ‘true‘)
stop ()
skeleton (RegionDilation, Skeleton)
connection (Skeleton, Errors)
dev_set_colored (12)
dev_display (Image)
dev_display (Errors)
Message := ‘Fractioned scratches merged via morphology‘
disp_message (WindowHandleZoom, Message, ‘window‘, 12, 12, ‘black‘, ‘true‘)
disp_continue_message (WindowHandleZoom, ‘black‘, ‘true‘)
stop ()
* 
* Distinguish small and large scratches
close_zoom_window (WindowHandleZoom, Width, Height)
select_shape (Errors, Scratches, ‘area‘, ‘and‘, 50, 10000)
select_shape (Errors, Dots, ‘area‘, ‘and‘, 1, 50)
dev_display (Image)
dev_set_color (‘red‘)
dev_display (Scratches)
dev_set_color (‘blue‘)
dev_display (Dots)
Message := ‘Extracted surface scratches‘
Message[1] := ‘Not categorized as scratches‘
disp_message (WindowID, Message, ‘window‘, 440, 310, [‘red‘,‘blue‘], ‘true‘)

灵感来源于官方文档





以上是关于Halcon斑点分析官方示例讲解的主要内容,如果未能解决你的问题,请参考以下文章

初学者系列:halcon(二) 图像算子Image

谁知道哪里可以看halcon软件的视频教程啊,或者有哪位会用halcon的人,可以教教我

halcon开发的软件 如何让客户不安装halcin也能用

halcon 手眼标定的坐标转换原理讲解

HALCON - 如何在 halcon 中读取低分辨率 ECC200 数据代码?

halcon blob分析demo