区域生长算法的一种C++实现

您所在的位置:网站首页 区域生长法的基本流程 区域生长算法的一种C++实现

区域生长算法的一种C++实现

2023-07-26 18:04| 来源: 网络整理| 查看: 265

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

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

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

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

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

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

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

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

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

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

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

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

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

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

复制代码 1 class Point2D 2 { 3 public: 4 Point2D(){} 5 Point2D(int ix, int iy) 6 { 7 this->x = ix; 8 this->y = iy; 9 } 10 11 ~Point2D(){} 12 13 Point2D operator+(const Point2D& a) const 14 { 15 return Point2D(x + a.x, y + a.y); 16 } 17 18 Point2D operator-(const Point2D& a) const 19 { 20 return Point2D(x - a.x, y - a.y); 21 } 22 23 bool operator=(const Point2D & a) 24 { 25 return (x == a.x && y == a.y); 26 } 27 28 int x; 29 int y; 30 }; 复制代码

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

复制代码 const Point2D PointShift2D[8] = { Point2D(1, 0), Point2D(1, -1), Point2D(0, -1), Point2D(-1, -1), Point2D(-1, 0), Point2D(-1, 1), Point2D(0, 1), Point2D(1, 1) }; 复制代码

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

复制代码 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; }; 复制代码

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

复制代码 1 #include "RegionGrowing.h" 2 #include 3 4 RegionGrowing::RegionGrowing() 5 { 6 this->InputData = nullptr; 7 this->OutputData = nullptr; 8 } 9 10 RegionGrowing::~RegionGrowing() 11 { 12 13 } 14 15 void RegionGrowing::SetInputData(char *pData, int width, int height) 16 { 17 this->InputData = pData; 18 this->Width = width; 19 this->Height = height; 20 } 21 22 void RegionGrowing::SetSeedPoint(Point2D &p) 23 { 24 this->SeedPoint = p; 25 } 26 27 void RegionGrowing::SetThreshold(int low, int high) 28 { 29 this->LowThreshold = low; 30 this->HighThreshold = high; 31 } 32 33 bool RegionGrowing::RegionGrow2D() 34 { 35 if (this->InputData == nullptr || this->OutputData == nullptr) 36 { 37 return false; 38 } 39 40 int index = this->SeedPoint.y * this->Width + this->SeedPoint.x; 41 int seedValue = this->InputData[index]; 42 43 std::stack pointStack; 44 pointStack.push(this->SeedPoint); 45 46 memset(this->OutputData, 0, sizeof(char)*this->Width*this->Height); 47 48 while (!pointStack.empty()) 49 { 50 Point2D topPoint = pointStack.top(); 51 pointStack.pop(); 52 53 for (int i = 0; i < 8; i++) 54 { 55 Point2D p = topPoint + PointShift2D[i]; 56 57 index = p.y * this->Width + p.x; 58 59 if (this->InputData[index] > this->LowThreshold && 60         this->InputData[index] < this->HighThreshold && 61 this->OutputData[index] == 0) 62 { 63 this->OutputData[index] = 126; 64 pointStack.push(p); 65 } 66 } 67 } 68 69 return true; 70 } 71 72 char* RegionGrowing::GetOutput() 73 { 74 return this->OutputData; 75 } 复制代码


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3