之前的【halcon】系列文章中,有介绍全局,阈值的方法,threshold。但是当我们的图片的背景光线不均匀时,我们就需要动态阈值的方式,及不同的明度区域使用不同的阈值。
如:
这张图就是明暗不均,我们没有办法使用全局的阈值挑选出全部的“棋子”
动态阈值时根据周围的环境进行对比的,使用我们先需要做一个均值滤波:
mean_image (Image, ImageMean, 59, 59)
做了这个均值滤波之后得到了一个“明暗的背景”,它并不是最终的结果,而是一个动态阈值的参考对象。
dyn_threshold (Image, ImageMean, RegionDynThresh, 15, 'light')
使用 light,表示和平均值相比offset=15,更亮的部分。
dyn_threshold (Image, ImageMean, RegionDynThresh, 15, 'dark')
使用 dark,表示和平均值相比offset=15,更暗的部分。
但是,此时我们这两个部分都想要,就是明暗的并集,那么就选择:not_equal
dyn_threshold (Image, ImageMean, RegionDynThresh, 15, 'not_equal')
单此时棋子被割裂了,我们需要进行“缝合/闭合”,此时运用“闭运算”,及先膨胀再收缩!
closing_circle (RegionDynThresh, RegionClosing, 8.5)
接着再来一个开运算:往当前的区域放圆,放得下的区域保留,放不下的去除。
opening_circle (RegionClosing, RegionOpening, 6.5)
最后再将这些区域进行打散,然后给每个打散的区域画一个外接圆,这样就将每个棋子都选出来了。
这个是halcon的实例代码,位置位于:
* This example shows the use of the operator dyn_threshold for
* the segmentation of the raised dots of braille chharacters.
* The operator dyn_threshold is especially usefull if the
* background is inhomogeneously illuminated. In this example,
* the segmentation with a simple threshold is not possible
* because the brightness of the background increases from
* left to right.
*
dev_update_off ()
*
* Preparation
read_image (Image, 'photometric_stereo/embossed_01')
get_image_size (Image, Width, Height)
dev_get_window (WindowHandle)
if (WindowHandle >= 0)
dev_resize_window_fit_image (Image, 0, 0, -1, -1)
else
dev_open_window_fit_image (Image, 0, 0, -1, -1, WindowHandle)
endif
set_display_font (WindowHandle, 16, 'mono', 'true', 'false')
dev_set_line_width (2)
*
dev_display (Image)
Message := 'Original image'
disp_message (WindowHandle, Message, 'window', 12, 12, 'black', 'true')
disp_continue_message (WindowHandle, 'black', 'true')
stop ()
*
* Use a strong mean filter on the image to blur out the braille points
mean_image (Image, ImageMean, 59, 59)
*
dev_display (ImageMean)
Message := 'Mean filtered image'
disp_message (WindowHandle, Message, 'window', 12, 12, 'black', 'true')
disp_continue_message (WindowHandle, 'black', 'true')
stop ()
*
* Compare the original image with the blurred one and determine the
* region where the gray values of the two images differ by more than 15
dyn_threshold (Image, ImageMean, RegionDynThresh, 15, 'not_equal')
*
dev_display (Image)
dev_display (RegionDynThresh)
Message := 'Regions segmented with dyn_threshold'
disp_message (WindowHandle, Message, 'window', 12, 12, 'black', 'true')
disp_continue_message (WindowHandle, 'black', 'true')
stop ()
*
* Post-process the found regions
*闭运算
closing_circle (RegionDynThresh, RegionClosing, 8.5)
*开运算
opening_circle (RegionClosing, RegionOpening, 6.5)
*将Region进行打散以便选择过滤
connection (RegionOpening, ConnectedRegions)
smallest_circle (ConnectedRegions, Row, Column, Radius)
gen_circle_contour_xld (ContCircle, Row, Column, Radius, 0, 6.28318, 'positive', 1)
*
* Show the results
dev_display (Image)
dev_set_color ('green')
dev_display (ContCircle)
Message := 'Results of braille segmentation after morphology'
disp_message (WindowHandle, Message, 'window', 12, 12, 'black', 'true')
*
dev_update_on ()