全國最多中醫師線上諮詢網站-台灣中醫網
發文 回覆 瀏覽次數:1004
推到 Plurk!
推到 Facebook!

關於環型路徑的判斷

尚未結案
xdio2
一般會員


發表:60
回覆:29
積分:17
註冊:2004-07-23

發送簡訊給我
#1 引用回覆 回覆 發表時間:2004-11-12 02:33:07 IP:61.59.xxx.xxx 未訂閱
請問各位大大,小弟想找一個取過細化的圖形 是否有環型區域 像是數字之類的圖形    下面是小弟的測試檔     不過我的程式一開始就出現錯誤, 我想可能是我想的太簡單了吧.... 雖然覺得自己挺遜的 不過還是希望各位大大能指教一下小弟的想法 告訴我不對的地方 感謝各位 謝謝~
     int charp1[300][300];
void charp1Pixel(Graphics::TBitmap *pBmp)
{    Byte *ptr;
for (int i=0;iHeight;i++ )
 {
  ptr=(Byte*)pBmp->ScanLine[i];
  for (int j=0;jWidth; j++ )
  {
   charp1[i][j]=ptr[j*3];
  }
 }    }    //一個判斷環型路徑的遞迴副程式
int  charcircle(Graphics::TBitmap *charcBmp,int x,int y)
{
  
  //把是黑色的點圖成藍的,讓路徑不會往回走
  charcBmp->Canvas->Pixels[x][y]=clBlue;
  
  //找出該點的八方向座標像素值
  int p[8]={0};
  p[0]=charp1[y-1][x-1];
  p[1]=charp1[y-1][x];
  p[2]=charp1[y-1][x+1];
  p[3]=charp1[y][x+1];
  p[4]=charp1[y+1][x+1];
  p[5]=charp1[y+1][x];
  p[6]=charp1[y+1][x-1];
  p[7]=charp1[y][x-1];      //順時鐘找黑色的點,只要找到,就去走那個點
  for(int i=0;i<8;i++)
  {
   if(p[i]==clBlack)
   {
    //用i來判斷座標,並進行遞迴
    switch(i)
    {
     case 0 :  charcircle(charcBmp,x-1,y-1);
               break;
     case 1 :  charcircle(charcBmp,x,y-1);
               break;
     case 2 :  charcircle(charcBmp,x+1,y-1);
               break;
     case 3 :  charcircle(charcBmp,x+1,y);
               break;
     case 4 :  charcircle(charcBmp,x+1,y+1);
               break;
     case 5 :  charcircle(charcBmp,x,y+1);
               break;
     case 6 :  charcircle(charcBmp,x-1,y+1);
               break;
     case 7 :  charcircle(charcBmp,x-1,y);
               break;
    }
   }
  }      //會到這邊,應該是該點的四周八個方向找不到黑色的點,若是如此,就回傳 1
  return 1;
}    //控制鈕
void __fastcall TcharDlg::Button6Click(TObject *Sender)
{
 
   Graphics::TBitmap *Bmp = new Graphics::TBitmap();
   Bmp->Assign(Image1->Picture->Bitmap);
   
   charp1Pixel(Bmp);
   int cir=0;
   
   //在Bmp中只要找到黑色點,就進入遞迴副程式
   for(int i=1;iHeight-1;i++)
   {
     for (int j=1;jWidth-1; j++ )
     if(Bmp->Canvas->Pixels[j][i]==clBlack)
     {
       cir=cir+charcircle(Bmp,j,i);
     }
   }
   
   //判別環型路徑的個數
   ShowMessage(cir);
}
發表人 - xdio2 於 2004/11/12 02:34:08 發表人 - xdio2 於 2004/11/12 02:35:34 發表人 - xdio2 於 2004/11/12 02:36:22
richtop
資深會員


發表:122
回覆:646
積分:468
註冊:2003-06-10

發送簡訊給我
#2 引用回覆 回覆 發表時間:2004-11-12 11:48:32 IP:140.129.xxx.xxx 未訂閱
xdio2 您好:    之前有篇文章,您可參考參考!    Chain-Code 邊界搜尋與字串(螞蟻) http://delphi.ktop.com.tw/topic.php?TOPIC_ID=49312 RichTop 敬上 =====***** 把數學當工具,可以解決問題;將數學變能力,能夠發現並解決問題! =====#####
xdio2
一般會員


發表:60
回覆:29
積分:17
註冊:2004-07-23

發送簡訊給我
#3 引用回覆 回覆 發表時間:2004-11-13 02:33:53 IP:61.59.xxx.xxx 未訂閱
Rich大大您好喔 冒昧的再請問您一下 小弟對於您那個程式碼有點不懂 請問    int cdX[]={ 1, 1, 0,-1,-1,-1, 0, 1, 0}; int cdY[]={ 0,-1,-1,-1, 0, 1, 1, 1, 0}; 這兩行陣列的數值...是代表什麼呢    for (dir=0; dir<8; dir =2) // to speed up the searching. { previous[dir] = next(dir, 8, prev); } 這個是說要加速搜尋...可是之前把prev便成-2 但是在next函式中skip已經預設為-1 那-1這個值有可能用到嗎? 為何要替skip預設值呢? next函式是用來幹麻的呢? 小弟只看到上面那邊就卡住了,希望您能指點一下迷津 打擾之處請多包含 感謝~ 下面是您原本的程式碼
int next(int value, int len, int skip=1) // including both direction
{ value  = skip;
  if ( skip<0 ) value  = len;
  value %= len;
  return (value);
}    int cdX[]={ 1, 1, 0,-1,-1,-1, 0, 1, 0};
int cdY[]={ 0,-1,-1,-1, 0, 1, 1, 1, 0};    int next(int value, int len, int skip=1) // including both direction
{ value  = skip;
  if ( skip<0 ) value  = len;
  value %= len;
  return (value);
}    int sftX=10, sftY=120, moveX, moveY;
int index=0;
float scale=3;
unsigned char path[1000];    void __fastcall TForm1::btn90DegreeClick(TObject *Sender)
{
  TColor color = RGB(0,0,0);
  TCanvas * canvas = Form1->Canvas;
  canvas->Pen->Color = RGB(0,0,0);      index = 0;
  //當滑鼠點下的地方並非黑色 , 做向下的滑鼠搜尋 ,若是大於視窗的height , 就結束~
  while( canvas->Pixels[px][py]!=color )
    { py  ; //px  ;
      if ( py>Form1->ClientHeight ) return;
    }      //此時的px,py一定是黑色的座標
  moveX = px;  moveY = py;
  
  int startX, startY;
  startX=px; startY=py;      int prev=-2, oriX, oriY, heading;
  int dir, previous[8];      
  for (dir=0; dir<8; dir =2)  // to speed up the searching.
     { previous[dir] = next(dir, 8, prev);
     }      for (dir=0; dir<8; dir =2)
     { if ( (canvas->Pixels[px cdX[dir]][py cdY[dir]]==color) &&
            (canvas->Pixels[px cdX[previous[dir]]][py cdY[previous[dir]]]!=color) )
         { heading = dir;
           break;
         }
     }
  if ( dir >= 8 ) return; // isolated point      oriX = sftX px*scale;
  oriY = sftY py*scale;
  canvas->MoveTo(oriX, oriY);
  int toDir;
  do { //for (dir=-2; dir<6; dir =2)
       for (dir=-3; dir<=4; dir  )
          { toDir = next(heading, 8, dir);
            if ( canvas->Pixels[px cdX[toDir]][py cdY[toDir]]==color )
              { px  = cdX[toDir];
                py  = cdY[toDir];
                //canvas->Pixels[px][py] = RGB(0,255,255);
                heading = toDir;
                break;
              }
          }           //if ( dir>=6 || px>Form1->ClientWidth  || px<0
       if ( dir>4 || px>Form1->ClientWidth  || px<0
                   || py>Form1->ClientHeight || py<0   )
         break; // isolated point
  path[index  ] = toDir;           canvas->MoveTo(oriX, oriY);
       oriX = sftX px*scale;
       oriY = sftY py*scale;
       canvas->LineTo(oriX, oriY);
     }
  while ((px!=startX) || (py!=startY) );
ShowMessage("The length of chain codes : "  IntToStr(index));
}
 
richtop
資深會員


發表:122
回覆:646
積分:468
註冊:2003-06-10

發送簡訊給我
#4 引用回覆 回覆 發表時間:2004-11-13 11:19:26 IP:211.76.xxx.xxx 未訂閱
xdio2 您好:    因為要把事情說清楚不容易,所以就把程式碼貼上來。 但是卻忘了:程式碼有時更不容易說清楚。< > 程式是我為了某些工作而做寫的一部分,所以會有一些比較不相關的部分。 不過您要的部分應該有包括在裡面。< >
引言: Rich大大您好喔 冒昧的再請問您一下 小弟對於您那個程式碼有點不懂 請問 int cdX[]={ 1, 1, 0,-1,-1,-1, 0, 1, 0}; int cdY[]={ 0,-1,-1,-1, 0, 1, 1, 1, 0}; 這兩行陣列的數值...是代表什麼呢 這是記錄八個neighbors,相對於中心點的(x,y)座標偏移量,這樣方便我使用迴圈去訪問每一個neighbor。 而我設定的方向是:首先是由三點鐘方向(或東方)開始,再依逆時針方向去找每個neighbor。 for (dir=0; dir<8; dir =2) // to speed up the searching. { previous[dir] = next(dir, 8, prev); } 這個是說要加速搜尋...可是之前把prev便成-2 但是在next函式中skip已經預設為-1 那-1這個值有可能用到嗎? 為何要替skip預設值呢? next函式是用來幹麻的呢? 小弟只看到上面那邊就卡住了,希望您能指點一下迷津 打擾之處請多包含 感謝~ 下面是您原本的程式碼
int next(int value, int len, int skip=1) // including both direction
{ value  = skip;
  if ( skip<0 ) value  = len;
  value %= len;
  return (value);
}

next(.)函式的目的是要產生能循環的數列。
例如:希望產生四個數的循環數列,0~3,
0,1,2,3,0,1,2,3,0,1,2,3,..... 或
3,2,1,0,3,2,1,0,3,2,1,0,.....
也就能產生兩種不同的方向。
至於skip的初值設定為1,是為了大部情形下,要用的是每次增或減1,所以設定初值之後就不必給該參數,讓程式碼簡化些如此而已。
另外,原先我將不同方向設定成不同的函式名稱,next(.),prev(.),目的是要使程式碼可讀性提高(其實程式碼只有我自己在看),但後來想說next(.)已能明確的表示要找下一個元素(只要方向設定正確,也不見得是連續的),所以就合併為一個。
而所謂的加速,應該是每次轉的方向角度增加(正常每次是45度),您可以設定為2(90度)等,依此類推。,
RichTop 敬上 =====***** 把數學當工具,可以解決問題;將數學變能力,能夠發現並解決問題! =====#####
xdio2
一般會員


發表:60
回覆:29
積分:17
註冊:2004-07-23

發送簡訊給我
#5 引用回覆 回覆 發表時間:2004-11-15 12:50:10 IP:61.59.xxx.xxx 未訂閱
喔喔喔! 多謝您的解說喔! 小弟因為您程式給的想法 自己也寫出了一個類似的邏輯 rich大大多謝您囉!!
系統時間:2024-05-17 13:31:55
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!