C++實現區域生長算法(Region growing algorithm)

區域生長算法的基本思想是將有相似性質的像素點合併到一起。對每一個區域要先指定一個種子點作爲生長的起點,然後將種子點周圍領域的像素點和種子點進行對比,將具有相似性質的點合併起來繼續向外生長,直到沒有滿足條件的像素爲止。
區域生長算法的設計主要由以下三點:生長種子點的確定,區域生長的條件,區域生長停止的條件。算法的實現步驟:

  1. 選取種子點:種子點可以輸入,也可以通過輸入的數據自動選取;
  2. 區域生長的條件:相鄰象元(四通道或八通道)滿足相應的閾值要求即可劃分在一個圖斑之中;
  3. 區域生長停止的條件:當所有的象元都已經劃分在相應的圖斑中時,算法結束。

參考代碼如下:

bool regiongrow(float *input, int nImgWidth, int nImgHeight, float threshold, float *output)
{
	stack <PT> seed;
	PT tempt;
	vector <PT> tempploy;
	vector < vector <PT> > polys;
	PT* pts=new PT [nImgWidth * nImgHeight];
	
	for(int i = 0; i < nImgHeight;++i)
	{
		for (int j = 0; j < nImgWidth; ++j)
		{
			pts[i * nImgWidth + j].pix = input[i * nImgWidth + j];
			pts[i * nImgWidth + j].x = i;
			pts[i * nImgWidth + j].y = j;
			pts[i * nImgWidth + j].polynum = -1;
		}
	}

	for(int i = 0; i < nImgHeight; ++i)
	{
		for (int j = 0; j < nImgWidth; ++j)
		{
			if(pts[i * nImgWidth + j].pix <= 0)
				continue;
			if(pts[i * nImgWidth + j].polynum > -1) 
				continue;
			if(seed.empty() == true)
				seed.push(pts[i * nImgWidth + j]);
			while(!seed.empty() == true)
			{
				tempt = seed.top();			//取出棧頂元素
				seed.pop();				//刪除棧頂元素
				tempploy.push_back(tempt);	//將棧頂元素放入到臨時圖斑中
				pts[(int)(tempt.x * nImgWidth + tempt.y)].polynum = polys.size();	//此時已有歸屬

				for (int bufferX = -1; bufferX <= 1; ++bufferX)
				{
					for (int bufferY = -1; bufferY <= 1; ++bufferY)
					{
						//對該種子點的八鄰域進行遍歷
						//判斷所在是否在有效的範圍內
						if(tempt.x + bufferX < 0 || tempt.x + bufferX >= nImgHeight || tempt.y + bufferY < 0 || tempt.y + bufferY >= nImgWidth)
							continue;
						//判斷是否有歸屬
						if(pts[((int)tempt.x + bufferX) * nImgWidth + ((int)tempt.y + bufferY)].polynum > -1)
							continue;
						//判斷是否滿足閾值條件
						if(abs(pts[((int)tempt.x + bufferX) * nImgWidth + ((int)tempt.y + bufferY)].pix - tempt.pix) <= threshold)
						{
							seed.push(pts[((int)tempt.x + bufferX) * nImgWidth + ((int)tempt.y + bufferY)]);
							pts[((int)tempt.x + bufferX) * nImgWidth + ((int)tempt.y + bufferY)].polynum = polys.size();
						}
					}
				}
			}
			polys.push_back(tempploy);
			tempploy.clear();
		}
	}
	
	for (int i = 0; i < polys.size(); ++i)
	{
		for(int j = 0; j < polys[i].size(); ++j)
		{					
				output[(int)(polys[i][j].x * nImgWidth + polys[i][j].y)] = polys[i][j].pix;
			}
		}
	}
	
	delete [] pts;
	return true;
}

示例圖像及結果:

在這裏插入圖片描述

歡迎大家批評指正。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章