二值图像中封闭孔洞的高效填充算法(附源码)。

     鉴于心情不好,这篇文章只是简单的说说这个算法的过程。

     在对图像二值化后,不管用的是什么二值算法,总会存在一些瑕疵,这个时候我们就需要进行一些列的处理,去除那些我们不想要的糟粕,这类方法其实有很多,比如去除孤点、去除孤枝等等,这里介绍下去除封闭孔洞的一种算法。

     首先,注意我们这里是去除封闭孔洞,何谓封闭孔洞?我们认为如果一个特征的边缘完全被另外一个特征包围,则认为其为一个封闭的特征,比如在下图中:

     1所标注处就是封闭的孔洞,2所标注极为开式孔洞。

     对于识别来说,很多情况下,我们希望能够把这些封闭孔洞用周边的特征来填充,从而减少特征的数量。

     一种直觉的想法就是,用FloodFill,不过如果直接用FloodFill,我们无法直接定位那些未知需要进行种子填充的, 但是Gabriel Landini, G.Landini 在2008年5月给我们写了个非常简单的代码实现了这一过程(原始代码是JAVA的,话说JAVA的算法代码改为C#基本就不要做什么改动啊):

    public static void FillHole(FastBitmap Bmp)
    {
        int X, Y;
        int Width,Height,Stride;
        byte * Pointer;
        Width = Bmp.Width; Height = Bmp.Height; Pointer = Bmp.Pointer; Stride = Bmp.Stride;
        for (Y=0;Y<Height;Y++)
        {
            Pointer=Bmp.Pointer + Y*Stride;
            if (Pointer[0]==0) FloodFill(Bmp,0,Y);
            if (Pointer[Width-1]==0) FloodFill(Bmp,Width-1,Y);
        }
        for (X=0;X<Width;X++)
        {
            Pointer=Bmp.Pointer + X;
            if (Pointer[0]==0) FloodFill(Bmp,X,0);
            if (Pointer[(Height-1)*Stride]==0) FloodFill(Bmp,X,Height-1);
        }
            for (Y = 0; Y < Height; Y++)
            {
                Pointer = Bmp.Pointer + Y * Stride;
                for (X = 0; X < Width; X++)
                {
                    if (Pointer[X] == 127)
                        Pointer[X] = 0;
                    else
                        Pointer[X] = 255;
                }
            }
      }

     算法的过程很简单,先水平方向取起点和终点为种子点,进行种子填充,然后再垂直方向进行。不要以为需要有那么多次种子填充的过程,算法速度就很慢,由于在每次种子填充前,都有个判断条件,而该判断条件,随着前面种子填充的过程的进行,将越来越难以满足。      算法具体的原理留给有兴趣的人思考,直接使用的人就完全不用去管他,知道他有这个功能就OK了。

     关于FloodFill算法的实现,多少年来也不知道有多少个版本的代码,能从网上找到的99%的都是些垃圾代码,真正的优秀代码作者一般都会留着,我这也是从网上找了一段代码,敷衍了事把,虽然我这里有非常好的这个函数。愿意学习的自然会去改进的。

     下面我们来看一下填充的效果:

                       原图

                         二值图

                            填充后的图  

                      原图

                         二值图

                            填充后的图    

     至于是要填充掉前景的孔洞还是背景的孔洞这可能需要作者自己判断了。

     如果我们要去掉指定面积小于指定值得孔洞,而保留大于的,你知道该怎么办吗?

     关于FloodFill函数,我在稍微展开一下吧,一般情况下这个函数都是用的四领域或者八领域的区域生长法实现的,如果能充分掌握该函数的编写,可以实现很多功能,比如PS的连续的魔术棒功能、比如二值图像的去除噪点、漫画分割、一些识别上等等,举例如下:

    一、连续的魔术棒

    二、清除二值图像的孤点

  是不是感觉和这里的填充孔洞类似,不过两者还是有所区别的。

    三、PCB板的某个元器件的定位                       

  好了,不扩展了,对填充孔洞有兴趣的朋友可以从这里下载源码:http://files.cnblogs.com/Imageshop/FillHole.rar

  希望看过认为好的朋友多多支持。 

*********************************作者: laviewpbt   时间: 2013.9.8       联系QQ:  33184777  转载请保留本行信息************************

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏思影科技

NATURE NEUROSCIENCE:大脑动态隐性状态是行为导向的工作记忆的基础

来自牛津大学的学者Michael J Wolff等人在Nature Neuroscience期刊上发文,提出了一种功能扰动的方法来探测大脑的隐性状态,...

2656
来自专栏PPV课数据科学社区

一文读懂遗传算法工作原理(附Python实现)

几天前,我着手解决一个实际问题——大型超市销售问题。在使用了几个简单模型做了一些特征工程之后,我在排行榜上名列第 219 名。

1184
来自专栏AI研习社

如何用 TensorFlow 生成令人惊艳的分形图案

今天来介绍一个小项目:在 TensorFlow 中生成分形图案。分形本身只是一个数学概念,与机器学习并无太大关系,但是通过分形的生成,我们可以了解怎么在 Ten...

2353
来自专栏人工智能LeadAI

文本数据处理的终极指南-[NLP入门]

简介 实现任何程度或者级别的人工智能所必需的最大突破之一就是拥有可以处理文本数据的机器。值得庆幸的是,全世界文本数据的数量在最近几年已经实现指数级增长。这也迫切...

3716
来自专栏ATYUN订阅号

消灭假新闻:使用Scikit-Learn检测虚假新闻

检测所谓的假新闻不是一项容易的任务,首先,要定义是什么是假新闻。如果你能找到或同意一个关于虚假新闻的定义,那么你必须收集并正确地对真实和虚假的新闻进行标签(希望...

5255
来自专栏一心无二用,本人只专注于基础图像算法的实现与优化。

图像偏色检测算法,速度快,效果好,共享给大家。      式中 ,M、 N分别为图像的宽和高,以像素为单位。在 a - b色度平面上,等效圆的中心坐标为 ( da , db ) ,半径为 M 。等效

     本文的算法并不是我自己提出的,而是一些论文中提出的,详见 :      1、基于图像分析的偏色检测及颜色校正方法 徐晓昭 , 蔡轶珩 , 刘长江 , ...

2278
来自专栏Jack-Cui

Python3《机器学习实战》学习笔记(四):朴素贝叶斯基础篇之言论过滤器

运行平台: Windows Python版本: Python3.x IDE: Sublime text3 一 前言     朴素贝叶斯算法是有监督的学...

2797
来自专栏小小挖掘机

推荐系统遇上深度学习(十二)--推荐系统中的EE问题及基本Bandit算法

Exploration and Exploitation(EE问题,探索与开发)是计算广告和推荐系统里常见的一个问题,为什么会有EE问题?简单来说,是为了平衡推...

1124
来自专栏大数据文摘

【干货】用朴素贝叶斯进行文本分类

2049
来自专栏iOSDevLog

100天写机器学习代码100天写机器学习代码

今天进入#100DaysOfMLCode我深入研究了实际Logistic回归的深度,以及它背后的数学运算是什么。了解如何计算成本函数,以及如何将梯度下降算法应用...

591

扫码关注云+社区