【dyn_threshold_划痕检测】


总结:

  • 灰度低通滤波可以突出信号。
  • dyn_threshold可以对两幅孪生图的信号进行阈值分割。

一、dyn_threshold算子说明

dyn_threshold(OrigImage, ThresholdImage : RegionDynThresh : Offset, LightDark : )

  • dyn_threshold 从输入的两幅图像中选择像素满足阈值条件的区域。
  • 令 g_{o} = g_{OrigImage} 和 g_{t} = g_{ThresholdImage}。
  • 其中,g_{OrigImage}是原始图像,g_{ThresholdImage}是平滑后图像,充当阈值。

那么

1) LightDark = ‘light’ 的条件是:

在这里插入图片描述
2)对于 LightDark = ‘dark’,条件是:

在这里插入图片描述

3)对于 LightDark = ‘equal’,条件是:

在这里插入图片描述
4)对于 LightDark = ‘not_equal’,条件是:

在这里插入图片描述

通常,阈值图像是原始图像的平滑版本(例如,通过应用 mean_image、binomial_filter、gauss_filter 等)。那么 dyn_threshold 的效果类似于将阈值应用于原始图像的高通滤波版本(参见 highpass_image)。

二、针对问题:

2.1 原始图片

如下图中,将划痕部分检出来。

read_image (Image, 'surface_scratch')

在这里插入图片描述

  • 原始图的表面灰度图(看不出明显的划痕)。

2.2 平滑后的图片

mean_image (Image, ImageMean, 7, 7)

平滑图片灰度图(划痕明显):

在这里插入图片描述

2.3 观察结果

可以断定,平滑图片中,能够将被噪声湮灭的细长划痕的信号给暴露出来。

三、代码部分

* 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
dev_open_window (0, 0, Width, Height, 'black', WindowHandle)
*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 (WindowHandle, 16, 'mono', 'true', 'false')
disp_message (WindowHandle, 'Fractioned scratches', 'window', 12, 12, 'black', 'true')
disp_continue_message (WindowHandle, '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 (WindowHandle, Message, 'window', 12, 12, 'black', 'true')
disp_continue_message (WindowHandle, '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 (WindowHandle, Message, 'window', 12, 12, 'black', 'true')
disp_continue_message (WindowHandle, 'black', 'true')
stop ()
* 
* Distinguish small and large scratches
dev_close_window ()
*close_zoom_window (WindowHandle, 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')

检查结果:
在这里插入图片描述

总结:

  • 灰度低通滤波可以突出信号。
  • dyn_threshold可以对两幅孪生图的信号进行阈值分割。
``` dev_update_off() * 参数定义 GaussSize := 5 ScratchLengthMin := 30 StainAreaMin := 50 * 获取图像文件列表 ImageFolder := 'E:/毕业论文/瓶盖图/' list_files(ImageFolder, ['files','follow_links'], ImageFiles) tuple_regexp_select(ImageFiles, ['\\.(tif|tiff|gif|bmp|jpg|jpeg|jp2|png|pcx|pgm|ppm|pbm|xwd|ima|hobj)$','ignore_case'], ImageFiles) * 创建日志文件 open_file('defect_log.txt', 'output', FileHandle) * 主循环 for ImgIndex := 0 to |ImageFiles| - 1 by 1 * 窗口管理 dev_close_window() dev_open_window(0, 0, 600, 400, 'black', WindowHandle) * 文件读取(带异常捕获) try read_image(Image, ImageFiles[ImgIndex]) catch (Exception) write_string(FileHandle, 'Failed:'+ImageFiles[ImgIndex]+'\n') continue endtry get_image_size (Image, Width, Height) dev_open_window (0, 0, 600, 400, 'black', WindowHandle) set_display_font (WindowHandle, 16, 'mono', 'true', 'false') dev_set_draw ('margin') dev_set_line_width (2) * 1. 图像预处理(保留V通道信息) try decompose3 (Image, R, G, B) trans_from_rgb (R, G, B, H, S, V, 'hsv') gauss_filter (V, VFiltered, GaussSize) catch (Exception) disp_message (WindowHandle, '预处理错误', 'window', 12, 12, 'red', 'true') stop() endtry * 2. 瓶盖区域定位 binary_threshold (VFiltered, Regions, 'max_separability', 'dark', UsedThreshold) closing_circle (Regions, RegionClosing, 5.5) connection (RegionClosing, ConnectedRegions) ImageArea := Width * Height MinArea := 0.3 * ImageArea MaxArea := 0.9 * ImageArea select_shape (ConnectedRegions, SelectedRegions, 'area', 'and', MinArea, MaxArea) select_shape (SelectedRegions, CapCandidates, ['circularity','compactness'], 'and', [0.6,0.5], [1,1]) fill_up (CapCandidates, RegionFillUp) shape_trans (RegionFillUp, CapRegion, 'convex') * 3. 缺陷检测流程 * 3.1 划痕检测 reduce_domain (VFiltered, CapRegion, VReduced) equ_histo_image (VReduced, VEquHist) edges_sub_pix (VEquHist, Edges, 'canny', 0.5, 15, 25) select_shape_xld (Edges, Scratches, ['contlength','width'], 'and', [ScratchLengthMin,1], [9999,3]) gen_region_contour_xld (Scratches, ScratchesRegion, 'filled') * 3.2 污渍检测 mean_image (VReduced, ImageMean, 31, 31) dyn_threshold (VReduced, ImageMean, Stains, 15, 'dark') connection (Stains, ConnectedStains) select_shape (ConnectedStains, SelectedStains, ['area','compactness'], 'and', [StainAreaMin,0.2], [9999,1.5]) * 4. 合并缺陷区域 gen_empty_obj (AllDefects) union2 (ScratchesRegion, SelectedStains, AllDefects) * 5. 后处理 connection (AllDefects, ConnectedDefects) closing_circle(ConnectedDefects, FinalDefects, 1.5) * 6. 结果显示 count_obj (FinalDefects, NumDefects) // 此时NumDefects会被正确初始化 dev_display (Image) dev_set_color ('green') dev_display (CapRegion) if (NumDefects > 0) * 划痕显示(蓝色) dev_set_color ('blue') dev_display (ScratchesRegion) * 污渍显示(紫色) dev_set_color ('magenta') dev_display (SelectedStains) * 添加图例说明 disp_message (WindowHandle, '检测结果:', 'window', 12, 12, 'white', 'true') disp_message (WindowHandle, '蓝色:划痕缺陷', 'window', 40, 12, 'blue', 'true') disp_message (WindowHandle, '紫色:污渍缺陷', 'window', 60, 12, 'magenta', 'true') else disp_message (WindowHandle, '检测通过:无缺陷', 'window', 12, 12, 'green', 'true') endif endfor *主循环结束```结果显示无缺陷,但过程识别到了划痕污渍
最新发布
03-19
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

【网络星空】

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值