Halcon斑點分析官方示例講解

callcall發表於2020-06-25

官方示例中有許多很好的例子可以幫助大家理解和學習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')

靈感來源於官方文件

相關文章