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

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

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

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

  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;
}

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

最新文章

  1. Waud.js – 使用HTML5降级处理的Web音频库
  2. C# 解析JSON的几种办法
  3. 几个常用Json组件的性能测试
  4. ARM compiler No such file or directory
  5. mingW与cygwin
  6. Ubuntu系统、开发环境配置
  7. system2之:4-LVM逻辑卷管理
  8. spring MVC之返回JSON数据(Spring3.0 MVC)
  9. 浅谈GlusterFS
  10. NLTK的安装
  11. 网络编程 多线程/socketserver模块/ threading.local
  12. Android Studio 3.1 正式版
  13. 使用LevelListDrawable实现Html.fromHtml多张图片显示
  14. java的几种对象(po,dto,dao等)
  15. 在Ubuntu中添加和删除PPA的软件源
  16. 12.nodejs事件轮询机制
  17. css基础----&gt;学习html(一)
  18. [C#]浮点数除零无法捕获异常的解决办法
  19. vue本地设置请求接口及数据
  20. 用AutoHotkey重置Excel的Ctrl+Alt+方向键选择的范围

热门文章

  1. opencv中stitching_detail的运行
  2. (转)STL
  3. 理解JavaScript闭包
  4. Error:(6, 0) No such property: outputDir for class: org.gradle.api.internal.project.DefaultProject_Decorated
  5. ZOJ 2392 The Counting Problem(模拟)
  6. error RC1205: invalid code page
  7. 队列(链式存储)C++模板实现
  8. 排序算法FOUR:堆排序HeapSort
  9. c#通过反射获取类上的自定义特性
  10. C# 制作Zip压缩包