區域生長算法的基本思想是將有相似性質的像素點合併到一起。對每一個區域要先指定一個種子點作爲生長的起點,然後將種子點周圍領域的像素點和種子點進行對比,將具有相似性質的點合併起來繼續向外生長,直到沒有滿足條件的像素爲止。
區域生長算法的設計主要由以下三點:生長種子點的確定,區域生長的條件,區域生長停止的條件。算法的實現步驟:
- 選取種子點:種子點可以輸入,也可以通過輸入的數據自動選取;
- 區域生長的條件:相鄰象元(四通道或八通道)滿足相應的閾值要求即可劃分在一個圖斑之中;
- 區域生長停止的條件:當所有的象元都已經劃分在相應的圖斑中時,算法結束。
參考代碼如下:
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;
}
示例圖像及結果:
歡迎大家批評指正。