【halcon】例子分析之动态阈值

背景

之前的【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 ()