例程功能
检测液体中的颗粒物。难度在于图像中大亮斑区域、低对比度小物体和噪声影响。
代码如下
csharp
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 ()
要点
- 代码中采用两种方法---
threshold
和dyn_threshold
,以分别分割不同的物体。再使用额外的后处理稳定地提取小颗粒物。
csharp
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) # 将不相连的区域打散
膨胀运算(dilation): 将kernel
区域中的最大值赋给中心位置,所以kernel_size
一般为奇数。这样操作的结果会将图像外围的突出点连接并向外延伸;
腐蚀运算(erosion): 将kernel
区域中的最小值赋给中心位置。这样操作的结果是会将图像外围的突出点加以腐蚀;
开运算(opening): 先腐蚀后膨胀,用来消除小物体、在纤细点处分离物体、平滑较大物体的边界的同时并不明显改变其面积,消除物体表面的突起;
闭运算(closing): 闭操作就是对图像先膨胀,再腐蚀。闭操作的结果一般是可以将许多靠近的图块相连称为一个无突起的连通域。原图首先经过膨胀操作将两个分开的图块结合起来,接着通过腐蚀操作将连通域的边缘和突起进行削平,最后得到的是一个无突起的连通域;
- 通过鼠标互动显示颗粒物的面积和灰度信息(再熟悉一遍)
csharp
while (Button == 1) # 右击结束循环
get_mbutton (WindowID, Row, Column, Button) # 获取在WindowID中鼠标的状态
select_region_point (SmallConnection, SmallSingle, Row, Column) # 选取区域中所有包含点(Row, Column)的region
...... # do sth.
endwhile