Halcon斑点分析官方示例讲解

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

Crystals

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

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

复制代码
  • 1
  • 2
  • 3
  • 4
read_image (Image, 'crystal') mean_image (Image, ImageMean, 21, 21) dyn_threshold (Image, ImageMean, RegionDynThresh, 8, 'dark') connection (RegionDynThresh, ConnectedRegions)

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

复制代码
  • 1
  • 2
  • 3
shape_trans (ConnectedRegions, ConvexRegions, 'convex') select_shape (ConvexRegions, LargeRegions, 'area', 'and', 600, 2000) select_gray (LargeRegions, Image, Crystals, 'entropy', 'and', 1, 5.6)

源程序

复制代码
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
* 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结晶体的晶格变化很有用,使用分水岭方法在这类图片上细分效果很好。在这里,每个暗区作为单个区域返回。因为在图像的外部原子仅部分可见,第一个任务是仅提取那些不靠近图像边界的原子。最后提取不规则,这是通过寻找形状(被挤压)的异常原子实现的。

复制代码
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
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])

分水岭方法划分图像

结果图

源程序

复制代码
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
* 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

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

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

复制代码
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
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)


源程序

复制代码
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
* 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

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

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

复制代码
  • 1
  • 2
  • 3
  • 4
  • 5
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)

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

复制代码
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
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)

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

复制代码
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
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)

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

复制代码
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
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)

源程序

复制代码
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
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

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

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

复制代码
  • 1
binary_threshold (Fin, Background, 'max_separability', 'light', UsedThreshold)

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

复制代码
  • 1
closing_circle (Background, ClosedBackground, 250)

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

复制代码
  • 1
  • 2
difference (ClosedBackground, Background, RegionDifference) opening_rectangle1 (RegionDifference, FinRegion, 5, 5)

源程序

复制代码
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
* 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板所示的球形键合直径

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

复制代码
  • 1
  • 2
threshold (Bond, Bright, 100, 255) shape_trans (Bright, Die, 'rectangle2')

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

复制代码
  • 1
  • 2
  • 3
reduce_domain (Bond, Die, DieGrey) threshold (DieGrey, Wires, 0, 50) fill_up_shape (Wires, WiresFilled, 'area', 1, 100)

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

复制代码
  • 1
  • 2
  • 3
  • 4
  • 5
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)

源代码

复制代码
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
* 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后,将小对象(主要是噪声)移除

复制代码
  • 1
  • 2
  • 3
  • 4
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将形状变薄到一个像素的宽度

复制代码
  • 1
  • 2
  • 3
  • 4
union1 (SelectedRegions, RegionUnion) dilation_circle (RegionUnion, RegionDilation, 3.5) skeleton (RegionDilation, Skeleton) connection (Skeleton, Errors)

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

复制代码
  • 1
  • 2
select_shape (Errors, Scratches, 'area', 'and', 50, 10000) select_shape (Errors, Dots, 'area', 'and', 1, 50)

源代码

复制代码
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
* 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')

灵感来源于官方文档

本文作者:callcall

本文链接:https://www.cnblogs.com/MorganMa/p/13186831.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   callcall  阅读(4426)  评论(1编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
展开