区域生长算法是一种图像分割方法,能够将图像中具有相同特征的连通区域分割出来,同时保证较好的边缘信息。

  区域生长算法的优点是简单,容易实现;但空间和时间复杂度较高,对分割图像要求较高,否则容易形成孔洞和过分割。

  区域生长算法的基本思想是首先获取分割区域的一个种子点,然后在种子点的周围搜索与该种子点有相似性质的像素点,合并到种子区域中。然后将合并的像素作为新的种子点继续搜索,直到种子区域中所有像素周围没有相似的像素点,算法结束。

  如果要实现区域生长算法,基本算法流程是:

  1. 选取种子点p(x0,y0),用堆栈表示种子区域,将种子点push到种子堆栈中

  2. 将种子堆栈中第一个种子点pop出堆栈,并以该点为中心,遍历该中心8邻域像素

  3. 判断遍历像素点是否已经在种子区域中,如果否,判断遍历像素点是否满足相邻种子点相似性,如果像素点(x,y)满足相似性,将(x,y)push到堆栈中

  4. 重复步骤 2-3,直至种子堆栈为空。

  从基本思想可以知道,影响区域生长算法的要素有三个:种子点的选取搜索路径的选择像素相似性的判断

  种子点的选取:一般情况下,区域生长算法是半交互式的分割算法,需要用户选取种子点。也可以是通过其他算法计算出来的种子点。

  搜索路径的选择:搜索路径一般选择相邻的像素,以二维图像为例,一般为8邻域搜索,或者4邻域搜索;以三维图像为例,一般为26邻域搜索或者6邻域搜索。

  像素相似性的判断:相似性一般以像素值的相近程度为判断标准,例如,可以设置一定灰度范围做为相似的标准。也可以通过计算满足某种形状或者性质作为判断标准。

  接着根据上文中提到的算法,作者提出一种C++的实现方法,该实现不基于任何类库,以二维图像为例,假设图像的数据类型为char型。

首先,为了便于操作,需要定义种子点的类:

 class Point2D
{
public:
Point2D(){}
Point2D(int ix, int iy)
{
this->x = ix;
this->y = iy;
} ~Point2D(){} Point2D operator+(const Point2D& a) const
{
return Point2D(x + a.x, y + a.y);
} Point2D operator-(const Point2D& a) const
{
return Point2D(x - a.x, y - a.y);
} bool operator=(const Point2D & a)
{
return (x == a.x && y == a.y);
} int x;
int y;
};

然后,定义种子点的邻域信息:

const Point2D PointShift2D[] =
{
Point2D(, ),
Point2D(, -),
Point2D(, -),
Point2D(-, -),
Point2D(-, ),
Point2D(-, ),
Point2D(, ),
Point2D(, )
};

然后,定义区域生长算法类的头文件:

class RegionGrowing
{
public:
RegionGrowing();
~RegionGrowing(); void SetInputData(char *pData, int width, int height); void SetSeedPoint(Point2D &p); void SetThreshold(int low, int hight); bool RegionGrow2D(); char* GetOutput(); private:
int LowThreshold;
int HighThreshold; int Width;
int Height; char *InputData;
char *OutputData; Point2D SeedPoint;
};

然后,是区域生长算法类的实现:

 #include "RegionGrowing.h"
#include <stack> RegionGrowing::RegionGrowing()
{
this->InputData = nullptr;
this->OutputData = nullptr;
} RegionGrowing::~RegionGrowing()
{ } void RegionGrowing::SetInputData(char *pData, int width, int height)
{
this->InputData = pData;
this->Width = width;
this->Height = height;
} void RegionGrowing::SetSeedPoint(Point2D &p)
{
this->SeedPoint = p;
} void RegionGrowing::SetThreshold(int low, int high)
{
this->LowThreshold = low;
this->HighThreshold = high;
} bool RegionGrowing::RegionGrow2D()
{
if (this->InputData == nullptr || this->OutputData == nullptr)
{
return false;
} int index = this->SeedPoint.y * this->Width + this->SeedPoint.x;
int seedValue = this->InputData[index]; std::stack<Point2D> pointStack;
pointStack.push(this->SeedPoint); memset(this->OutputData, , sizeof(char)*this->Width*this->Height); while (!pointStack.empty())
{
Point2D topPoint = pointStack.top();
pointStack.pop(); for (int i = ; i < ; i++)
{
Point2D p = topPoint + PointShift2D[i]; index = p.y * this->Width + p.x; if (this->InputData[index] > this->LowThreshold &&
        this->InputData[index] < this->HighThreshold &&
this->OutputData[index] == )
{
this->OutputData[index] = ;
pointStack.push(p);
}
}
} return true;
} char* RegionGrowing::GetOutput()
{
return this->OutputData;
}

声明本博客文章未特殊注明均为原创,转载请注明作者和原地址

区域生长算法的一种C++实现的更多相关文章

  1. 区域生长算法(附MATLAB代码实现)

    一.理论概念 区域生长是按照事先定义的生长准则将一个像素或者子区域逐步聚合成一个完整独立的连通区域过程.对于图像感兴趣目标区域R,z为区域R上事先发现的种子点,按照规定的生长准则逐步将与种子点z一定邻 ...

  2. 区域生长算法 全局分类 C++ & matlab

    // 注:本内容为作者原创,禁止在其他网站复述内容以及用于商业盈利,如需引用,请标明出处:https://www.cnblogs.com/lv-anchoret/ 今天我们来介绍用C++算法如何来实现 ...

  3. xgboost算法教程(两种使用方法)

    标签: xgboost 作者:炼己者 ------ 欢迎大家访问我的简书以及我的博客 本博客所有内容以学习.研究和分享为主,如需转载,请联系本人,标明作者和出处,并且是非商业用途,谢谢! ------ ...

  4. Python数据结构与算法(几种排序)

    数据结构与算法(Python) 冒泡排序 冒泡排序(英语:Bubble Sort)是一种简单的排序算法.它重复地遍历要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来.遍历数列的工作是 ...

  5. [CC]区域生长算法——点云分割

    基于CC写的插件,利用PCL中算法实现: void qLxPluginPCL::doRegionGrowing() { assert(m_app); if (!m_app) return; const ...

  6. 求质数算法的N种境界[1] - 试除法和初级筛法

    ★引子 前天,俺在<俺的招聘经验[4]:通过笔试答题能看出啥?>一文,以"求质数"作为例子,介绍了一些考察应聘者的经验.由于本文没有政治敏感内容,顺便就转贴到俺在CSD ...

  7. 【转】求质数算法的N种境界

    原文地址:http://blog.csdn.net/program_think/article/details/7032600/ ★引子 前天,俺在<俺的招聘经验[4]:通过笔试答题能看出啥?& ...

  8. PHP 一致性哈希算法的一种简单实现

    在分布式系统中,如果某业务可以由多个相同的节点处理,很容易想到用HASH的方式将业务请求分散到这些节点处理,比如memecache缓存等分 布式集群应用,如果只是简单的使用,不涉及用户用户状态等信息, ...

  9. 【转载】阻塞队列之三:SynchronousQueue同步队列 阻塞算法的3种实现

    一.SynchronousQueue简介 Java 6的并发编程包中的SynchronousQueue是一个没有数据缓冲的BlockingQueue,生产者线程对其的插入操作put必须等待消费者的移除 ...

随机推荐

  1. java常用的包的简介

    java常用的包: java.lang:包含java语言的核心类,如String.math.system和thread类等,使用这个包下的类无需import导入,系统会自动导入这个包下的所有类.   ...

  2. Java设计模式之策略模式(一)

    今年寒假没有回家,打算利用这个假期的时间进行学习设计模式,这一个人感觉比较牛的知识,前一段时间一直在忙着搞自己的专业课,还有就是捣鼓了一下Linux系统,没有好好的学习关于Java还有Android方 ...

  3. 如何使用ZBLibrary-Android快速开发框架

    1.下载: 点击右边这个地址 https://github.com/TommyLemon/Android-ZBLibrary 点击DownloadZip即可. 2.解压 3.用ADT-Bundle(集 ...

  4. Android_Handler

    xml文件: <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:t ...

  5. ES 中的那些坑

    数组 1. 数组中的 full-text 字段将被 [analyzed] 2. 数组中[所有元素]的数据类型必须一致 3. 数组的数据类型,以其 [第一个元素]为准 映射 1. 数据类型会自动进行转化 ...

  6. Python(2.7.6) ConfigParser - 读写配置文件

    Python 标准库的 ConfigParser 模块提供一套 API 来读取和操作配置文件. 配置文件的格式 a) 配置文件中包含一个或多个 section, 每个 section 有自己的 opt ...

  7. SQL server 的约束条件【转】

    SQLServer - 约束 一.约束的分类 在SQLServer中,有3种不同类型的约束. 1.实体约束 实体约束是关于行的,比如某一行出现的值就不允许出现在其他行,例如主键. 2.域约束 域约束是 ...

  8. c++和c#之间的类型转换

    //C#调用C++的DLL搜集整理的所有数据类型转换方式,可能会有重复或者多种方案,自己多测试        //c++:HANDLE(void   *)          ----    c#:Sy ...

  9. 第十八篇、keychain保存UUID(保持唯一性,应用卸载,下载安装也不变)和获取IP地址

    .h #import <Foundation/Foundation.h> #import <Security/Security.h> /**使用**/ //-(void) se ...

  10. c# 中模拟一个模式匹配及匹配值抽取

    摘一段模式的说明, F#的: msdn是这么描述它的:“模式”是用于转换输入数据的规则.模式将在整个 F# 语言中使用,采用多种方式将数据与一个或多个逻辑结构进行比较.将数据分解为各个构成部分,或从数 ...