直接使用遞歸方法來搜尋連通區域,如果連通區域是大的整塊的值,這樣就會出現遞歸溢出的問題,是以我使用了邊界遞歸的思路,建立一個圖像大小的二值數組,儲存圖像的每個像素的值(0或者1).這樣在遞歸的時候如果一個像素的4或者8方向都是跟自己值相同,就可以跳過這點繼續搜尋,因為他不在邊界上,同時為搜尋過的每個像素儲存狀态,後面就可以跳過搜尋過的點.
下面是C#描述算法:
private bool[][] sArr;
private bool[][] vArr;
//
private void findRect()
{
recArr = newArrayList();
for (int i=0;i<bmp.Width; i++){
for(int j=0; j<bmp.Height; j++)
sArr[i][j]=false;
}
//
for (int i=1;i<bmp.Width-1; i++) {
for(int j=1; j<bmp.Height-1; j++) {
if(vArr[i][j]) {
rec= new Rectangle();
rec.Y= j;
rec.Height= j;
rec.X= i;
rec.Width= i;
//
if(findNext(i,j)) {
if(rec.Width>0 && rec.Height>0) {
rec.Height= rec.Height - rec.Y;
rec.Width= rec.Width - rec.X;
drawOneRec(rec);
recArr.Add(rec);
}
}
fnCount= 0;
}
}
}
private int fnCount=0;
private bool findNext(int i,intj)
fnCount++;
if(fnCount> 10000)
{
//fnCount= 0;
returntrue;
try
if(i<2||i>bmp.Width-2||j<2||j>bmp.Height-2)
{
//throw(newException("error"));
elseif (vArr[i][j] && !sArr[i][j])
if(j<rec.Y)
{
rec.Y=j;
if(j>rec.Height)
rec.Height=j;
if(i<rec.X)
rec.X=i;
if(i>rec.Width)
rec.Width=i;
//
sArr[i][j]= true;
//if(!vArr[i+1][j+1] || !vArr[i+1][j-1])
if(vArr[i+1][j] && !sArr[i+1][j])
findNext(i+1,j);
if(vArr[i-1][j] && !sArr[i-1][j])
findNext(i-1,j);
if(vArr[i][j+1] && !sArr[i][j+1])
findNext(i,j+1);
if(vArr[i][j-1] && !sArr[i][j-1])
findNext(i,j-1);
//findNext(i+1,j+1);
//findNext(i-1,j-1);
//findNext(i-1,j+1);
//findNext(i+1,j-1);
catch(Exception e)
//MessageBox.Show(e.Message);
//returntrue;
returntrue;
本文轉自feisky部落格園部落格,原文連結:http://www.cnblogs.com/feisky/archive/2008/04/11/1586639.html,如需轉載請自行聯系原作者