區域生長算法的一種C++實現


  區域生長算法是一種圖像分割方法,能夠將圖像中具有相同特征的連通區域分割出來,同時保證較好的邊緣信息。

  區域生長算法的優點是簡單,容易實現;但空間和時間復雜度較高,對分割圖像要求較高,否則容易形成孔洞和過分割。

  區域生長算法的基本思想是首先獲取分割區域的一個種子點,然后在種子點的周圍搜索與該種子點有相似性質的像素點,合並到種子區域中。然后將合並的像素作為新的種子點繼續搜索,直到種子區域中所有像素周圍沒有相似的像素點,算法結束。

  如果要實現區域生長算法,基本算法流程是:

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

然后,定義種子點的鄰域信息:

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)
};
View Code

然后,定義區域生長算法類的頭文件:

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

然后,是區域生長算法類的實現:

 1 #include "RegionGrowing.h"
 2 #include <stack>
 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<Point2D> 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 }
View Code

 

 聲明本博客文章未特殊注明均為原創,轉載請注明作者和原地址


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM