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\')
灵感来源于官方文档