線上訂房服務-台灣趴趴狗聯合訂房中心
發文 回覆 瀏覽次數:4503
推到 Plurk!
推到 Facebook!

Connected Component Labeling 轉non-cursive

尚未結案
revenger
一般會員


發表:1
回覆:3
積分:0
註冊:2005-05-08

發送簡訊給我
#1 引用回覆 回覆 發表時間:2005-05-10 13:41:02 IP:163.28.xxx.xxx 未訂閱
hi: 以下是我Connected Component Labeling  一張640*480的圖
int Origin[480][640];        //原始的圖轉成 int 存放此
int Temp[480][640];                //temp buffer
TARGET target1[256],object[256];
typedef struct 
{
    int id;                //TARGET 的計算編號
    int cx,cy;  //中心點
    int area;   //面積
         
        
}TARGET;
void mani()
{
//count 是傳回計算所得 components 數量
count = mark_components( object, &object_count );
}    void mark_components_fill( TARGET *p, int x, int y, int c, int mark )
{
    //x,y, 要在 screen 內
    if( (x)>=0 && (x)< W && y>=0 && ycx  = x;                //累加 x,y (稍後會求中心點)
            p->cy  = y;
            p->area  ;                //累加填入 pixel 數量
            Temp[y][x] = mark;        //填入 新值(mark)
        }        }        //以下是用 recursive 方式 填滿 底色為 c 的所用周邊
    if( (x-1)>=0 && (x-1)< W && y>=0 && y=0 && (x 1)< W && y>=0 && y=0 && x< W && (y-1)>=0 && (y-1)=0 && x< W && (y 1)>=0 && (y 1)id = total;        //[標記值]                    mark_components_fill(p, x, y, c, total);  //傳入 要 填滿 的 x,y,  底色值c, 要標記的值total                    //p-> area 將是填滿pixel 個數,求中心點
                p->cx /= p->area;
                p->cy /= p->area;                }            }        }        return total;
}
此程式在VC 驗證過沒有問題; 但重點是我目前要移植到一個stack很小的裝置上,大概只能5k bytes左右, 由於Connected Component Labeling我是以recursive撰寫,stack量會很大, 目前想轉寫成non-recursive,這方面不是很瞭解,想請教各位前輩,是否給我一些意見,如何轉成non-recursive的寫法. 請不另賜教,謝謝 發表人 - revenger 於 2005/05/10 15:00:23
 
 
 
發表人 - revenger 於 2005/05/10 17:07:20
taishyang
站務副站長


發表:377
回覆:5490
積分:4563
註冊:2002-10-08

發送簡訊給我
#2 引用回覆 回覆 發表時間:2005-05-10 16:25:34 IP:210.68.xxx.xxx 未訂閱
您好:    PO程式碼的方式請參考版規說明,煩請修改謝謝您的配合 >
justdo
高階會員


發表:2
回覆:359
積分:222
註冊:2004-08-17

發送簡訊給我
#3 引用回覆 回覆 發表時間:2005-05-10 21:04:41 IP:221.169.xxx.xxx 未訂閱
查一下Digital Image Processing的書籍應該都有,我簡單描述一下: 由左而右,由上而下一一檢查每個pixel 假若有物體存在,則給予編號,編號方式:
  • 若周圍有物體,則沿用該物體的編號(檢查的順序依序為左上、上、右上、左)
  • 若周圍物體有數個不同的編號,則記錄這些編號為等價的
  • 若周圍沒有物體,則給予新的編號
全部標記好了之後,開始整理等價的編號,建立一張table記錄等價編號中最小的值 重設影像的編號,以上一行的"最小編號值"取代等價編號 發表人 - justdo 於 2005/05/10 21:08:34
revenger
一般會員


發表:1
回覆:3
積分:0
註冊:2005-05-08

發送簡訊給我
#4 引用回覆 回覆 發表時間:2005-05-10 21:50:15 IP:163.28.xxx.xxx 未訂閱
謝謝justdo的回應: 我的作法跟您說的一樣,而我的影像是經過而二值化的,所以背景是黑的,物體為亮點,但重點是,我本來的方法是recursive,使得stack很大 那麼我改成以while迴圈來作,可以不增加stack嗎? 一個簡單的例子,偵測右邊的CCL 增測到亮點,juge=1.
while(juge)
{
        temp[x][y]=mark;
        if(temp[x][y 1]==pixel_on;
        {
                y=y 1:
                continue;
        }
} 
這樣做,是不是可以避免stack增加,請不吝賜教,謝謝. 發表人 - revenger 於 2005/05/10 21:50:51
 
發表人 - revenger 於 2005/05/10 21:51:40
justdo
高階會員


發表:2
回覆:359
積分:222
註冊:2004-08-17

發送簡訊給我
#5 引用回覆 回覆 發表時間:2005-05-11 19:38:29 IP:221.169.xxx.xxx 未訂閱
你的方法是不足的.. 麻煩再看一次我前面貼的文章,那個是非遞迴的!!
revenger
一般會員


發表:1
回覆:3
積分:0
註冊:2005-05-08

發送簡訊給我
#6 引用回覆 回覆 發表時間:2005-05-11 21:41:32 IP:163.28.xxx.xxx 未訂閱
hi: 我看過您之前的文章,裡面有這一段
int __fastcall TForm1::Connect(Graphics::TBitmap * BMP, int x, int y)
{
int count=0;      count  ;
  BMP->Canvas->Pixels[x][y] = clBlack;
  map[y][x]=id;
  // 判斷 (x 1,y)
  if(BMP->Canvas->Pixels[x   1][y] == clWhite)
  {
    count =Connect(BMP, x   1, y);
  }
  // 判斷 (x 1, y-1)
  if(BMP->Canvas->Pixels[x   1][y - 1] == clWhite)
  {
    count =Connect(BMP, x   1, y - 1);
  }
  // 判斷 (x,y-1)
  if(BMP->Canvas->Pixels[x][y - 1] == clWhite)
  {
    count =Connect(BMP, x , y - 1);
  }
  // 判斷 (x-1,y-1)
  if(BMP->Canvas->Pixels[x-1][y - 1] == clWhite)
  {
    count =Connect(BMP, x-1, y - 1);
  }
  // 判斷 (x-1,y)
   if(BMP->Canvas->Pixels[x-1][y] == clWhite)
  {
    count =Connect(BMP, x-1, y);
  }
  // 判斷 (x-1,y 1)
  if(BMP->Canvas->Pixels[x-1][y 1] == clWhite)
  {
    count =Connect(BMP, x-1, y 1);
  }
  // 判斷 (x,y 1)
  if(BMP->Canvas->Pixels[x][y 1] == clWhite)
  {
    count =Connect(BMP, x, y 1);
  }
  // 判斷 (x 1,y 1)
  if(BMP->Canvas->Pixels[x   1][y 1] == clWhite)
  {
    count =Connect(BMP, x   1, y 1);
  }
  return count;
}
在判斷式成立後,呼叫程式本身,這算是遞迴嗎?若我觀念有錯,請指教. 另外您說我的方法是不足的,是指我本來的程式還是指後來提的簡單方法呢? 請不吝賜教,謝謝
 
 
發表人 - revenger 於 2005/05/11 21:43:44
justdo
高階會員


發表:2
回覆:359
積分:222
註冊:2004-08-17

發送簡訊給我
#7 引用回覆 回覆 發表時間:2005-05-12 20:15:31 IP:221.169.xxx.xxx 未訂閱
你貼的這段code的確是遞迴的 但是在本主題第三篇文章則是非遞迴的演算法 兩者並無任何關係!! 不足的是指後來提的簡易方法 發表人 - justdo 於 2005/05/12 20:28:13
revenger
一般會員


發表:1
回覆:3
積分:0
註冊:2005-05-08

發送簡訊給我
#8 引用回覆 回覆 發表時間:2005-05-13 20:23:02 IP:163.28.xxx.xxx 未訂閱
hi: 我目前嘗試以這樣的方法來解決,如下: 只修改 mark_components_fill
void mark_components_fill( TARGET *p, int x, int y, int c, int mark )
{
        while(1)
        {
                if( (x)>=0 && (x)< W && y>=0 && ycx  = x;                        //累加 x,y (稍後會求中心點)
                                p->cy  = y;
                                p->area  ;                        //累加填入 pixel 數量
                                Temp[y][x] = mark;        //填入 新值(mark)
                                printf("%d",mark);
                                printf("\n");
                        }
                }
                if( (x-1)>=0 && (x-1)< W && y>=0 && y=0 && (x 1)< W && y>=0 && y=0 && x< W && (y-1)>=0 && (y-1)=0 && x< W && (y 1)>=0 && (y 1)    但是結果還是有一些問題,自己還在debug
如有前輩看出哪裡出錯,請不吝賜教     
        
justdo
高階會員


發表:2
回覆:359
積分:222
註冊:2004-08-17

發送簡訊給我
#9 引用回覆 回覆 發表時間:2005-05-15 20:15:16 IP:221.169.xxx.xxx 未訂閱
你的方法只能適用在遞迴... 不用成遞迴的話,當往某個方向去找相同編號的物體之後,就再也沒機會往另一個方向,你可以把找點的次序印出來就可以看到這種情況... 非遞迴的方式就只能如我在此系列文章的第三篇所說的來做
系統時間:2024-05-13 15:21:40
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!