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

指定區塊填滿

尚未結案
bala0514
一般會員


發表:42
回覆:37
積分:15
註冊:2004-07-26

發送簡訊給我
#1 引用回覆 回覆 發表時間:2005-04-18 17:52:51 IP:163.28.xxx.xxx 未訂閱
我有一個二直化圖形,如下圖一,有不規則區塊,我想將白色區塊填滿成紅色,但是我有參考幾位高手所PO的程式碼,最主要是對整張影像做白色區塊填滿,但是我現在問題是: 1.將較小區塊填滿成紅色例如像素為32Pixels,只保留較大的白色區塊,例如像素為100pixels。 圖一 圖二
void TForm1::scan2D(TImage *image, TColor fillColor)
{
  Byte **ptr;
  int r, g, b, index;      image->Picture->Bitmap->PixelFormat = pf24bit;
  // 視覺上維持白色感覺
  image->Picture->Bitmap->Canvas->Brush->Color = (TColor)RGB(252,253,254);
  image->Picture->Bitmap->Canvas->FloodFill(0,0,clBlack,fsBorder);      ptr = new Byte*[image->Picture->Height];
  for (int k=0; kPicture->Height; k++)
     ptr[k] = (Byte*) image->Picture->Bitmap->ScanLine[k];      for (int row=0; rowPicture->Height; row++)
     {
     index = 0;
       for (int col=0; colPicture->Width; col++)
          {
            b = ptr[row][index  ];
            g = ptr[row][index+1];
            r = ptr[row][index+2];                if ( r==255 && g==255 && b==255 ) // come into the internal of closed regions
              {
                image->Picture->Bitmap->Canvas->Brush->Color = fillColor;
                image->Picture->Bitmap->Canvas->FloodFill(col,row,clBlack,fsBorder);
              }
            index += 3;
          }
     }      // 還原封閉區域外部回白色
  image->Picture->Bitmap->Canvas->Brush->Color = clWhite;
  image->Picture->Bitmap->Canvas->FloodFill(0,0,clBlack,fsBorder);      delete [] ptr; // 釋放記憶體
}
//-------------------------------------------------------------------    void __fastcall TForm1::Button2Click(TObject *Sender)
{
scan2D(Image1, RGB(0,0,0));
}
//---------------------------------------------
謝謝各位 ***程式語言真是一門高深的學問***
------
***程式語言真是一門高深的學問***
1666362
初階會員


發表:66
回覆:124
積分:43
註冊:2004-07-07

發送簡訊給我
#2 引用回覆 回覆 發表時間:2005-04-18 18:48:30 IP:163.25.xxx.xxx 未訂閱
請參考下面這篇 http://delphi.ktop.com.tw/topic.php?TOPIC_ID=57709 這程式碼 可以統計出圖上總共有多少區塊,每個區塊pixel大小 所以您只要自己加入條件修改(限定區塊pixel範圍) 在這範圍內圖上顏色 就可以了
bala0514
一般會員


發表:42
回覆:37
積分:15
註冊:2004-07-26

發送簡訊給我
#3 引用回覆 回覆 發表時間:2005-04-19 09:47:05 IP:163.28.xxx.xxx 未訂閱
引言: 請參考下面這篇 http://delphi.ktop.com.tw/topic.php?TOPIC_ID=57709 這程式碼 可以統計出圖上總共有多少區塊,每個區塊pixel大小 所以您只要自己加入條件修改(限定區塊pixel範圍) 在這範圍內圖上顏色 就可以了
1666362你好,我照你的連結,觀看了一下,看了程式碼部分,我有利用他的程式碼Run過,但是有些問題,
map=new unsigned int*[height];
這部分有問題,Compiler後他說 謝謝你!! ***程式語言真是一門高深的學問*** 不好意思,我少看了一個條件,unsigned int **map;< > < > 發表人 - bala0514 於 2005/04/19 10:19:05
------
***程式語言真是一門高深的學問***
bala0514
一般會員


發表:42
回覆:37
積分:15
註冊:2004-07-26

發送簡訊給我
#4 引用回覆 回覆 發表時間:2005-04-19 10:47:19 IP:163.28.xxx.xxx 未訂閱
引言: 請參考下面這篇 http://delphi.ktop.com.tw/topic.php?TOPIC_ID=57709 這程式碼 可以統計出圖上總共有多少區塊,每個區塊pixel大小 所以您只要自己加入條件修改(限定區塊pixel範圍) 在這範圍內圖上顏色 就可以了
1666362你好,程式已經可以Run了,但是我利用上面我所Po的測試圖來做測試,程式Run出來後,最大區塊是第三塊,Pixels數為3453,但是要將其他白色區塊填成藍色,只保留最大塊是白色,程式碼是要撰寫成:Image1->Picture->Canvas->Pixels[x][y]=clBlue; 還是要怎樣撰寫,並且加在哪一行呢?謝謝你的指教 ***程式語言真是一門高深的學問***
------
***程式語言真是一門高深的學問***
justdo
高階會員


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

發送簡訊給我
#5 引用回覆 回覆 發表時間:2005-04-19 19:46:38 IP:221.169.xxx.xxx 未訂閱
map變數有紀錄每一個piexl的編號 只要判斷該pixel的編號不是最大區塊的編號、也不是0,就可以把該位置填藍色進去了    
for (int y=0; yPicture->Canvas->Pixels[x][y]=clBlue;    
bala0514
一般會員


發表:42
回覆:37
積分:15
註冊:2004-07-26

發送簡訊給我
#6 引用回覆 回覆 發表時間:2005-04-19 22:12:47 IP:163.28.xxx.xxx 未訂閱
引言: map變數有紀錄每一個piexl的編號 只要判斷該pixel的編號不是最大區塊的編號、也不是0,就可以把該位置填藍色進去了
for (int y=0; yPicture->Canvas->Pixels[x][y]=clBlue;
justdo謝謝你的提出,但是我將程式Run過,結果卻變成這樣,如圖一,我希望最大塊的橢圓形能保留白色,其餘都填滿呈藍色,謝謝。 圖一 程式碼如下:
void __fastcall TForm1::Button1Click(TObject *Sender)
{
   unsigned int a=StrToInt(Edit1->Text);
   unsigned int b=StrToInt(Edit2->Text);
   int c = 0;   
   int id=1;
   unsigned int counts=0;
   unsigned int maxcounts=0;
   unsigned int maxid=0;       Graphics::TBitmap *BMP = new Graphics::TBitmap();
   BMP->Assign(Image1->Picture->Bitmap );
   Byte *ptr=NULL;
   BMP->PixelFormat = pf8bit;
   int width=BMP->Width;
   int height=BMP->Height;
   map=new  unsigned int*[height];
   for (int i=0; iScanLine[y];
      for(int x = 0; x < width; x++)
      {
         if(ptr[x] == 255)
         {
            counts= Connect(BMP, x, y);
             Memo1->Lines->Add("面積"+FloatToStr(counts));
            if (counts > maxcounts)
            {
                maxcounts=counts;
                maxid=id;
            }
            id++;
                          
            if (counts>=a && counts<=b)
            {
             c+=1;    //計算物件各數 (可用像素數cx來限制是否累計)
            //break;
            }             }
      }
   }       delete BMP;
   ShowMessage(c);    ShowMessage(AnsiString("最大面積為區塊:") + maxid + ", 大小=" + maxcounts+" Pixels");       for (int y=0; yPicture->Bitmap->Canvas->Pixels[x][y]=clBlue;
      }
   }       for (int i=0; iCanvas->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;
}    //--
謝謝大家的指教 ***程式語言真是一門高深的學問*** 發表人 - bala0514 於 2005/04/19 22:15:16 發表人 - bala0514 於 2005/04/19 22:16:19
------
***程式語言真是一門高深的學問***
1666362
初階會員


發表:66
回覆:124
積分:43
註冊:2004-07-07

發送簡訊給我
#7 引用回覆 回覆 發表時間:2005-04-20 00:39:39 IP:210.192.xxx.xxx 未訂閱
下面這兩種方式 您試試看 if....要執行什麼動作 Image1->Picture->Bitmap->Canvas->Pixels[x][y]=clBlue;<---你沒有誇號 把誇號加上去試試看{ } 或者改成 if (map[y][x] != maxid) {Image1->Picture->Bitmap->Canvas->Pixels[x][y]=clBlue;} 發表人 - 1666362 於 2005/04/20 00:50:23
bala0514
一般會員


發表:42
回覆:37
積分:15
註冊:2004-07-26

發送簡訊給我
#8 引用回覆 回覆 發表時間:2005-04-20 09:24:13 IP:163.28.xxx.xxx 未訂閱
引言: 下面這兩種方式 您試試看 if....要執行什麼動作 Image1->Picture->Bitmap->Canvas->Pixels[x][y]=clBlue;<---你沒有誇號 把誇號加上去試試看{ } 或者改成 if (map[y][x] != maxid) {Image1->Picture->Bitmap->Canvas->Pixels[x][y]=clBlue;} 發表人 - 1666362 於 2005/04/20 00:50:23
1666362你好,我依妳提供的意見做測試,測試如下: (1)加上括號後跟上述的一樣,全部圖形依然皆變成藍色 (2)若改成map[y][x] != maxid,是整張圖都變成藍色,如下圖一 是哪出了問題ㄋ?? 圖一 謝謝大家在提供意見!! ***程式語言真是一門高深的學問***
------
***程式語言真是一門高深的學問***
justdo
高階會員


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

發送簡訊給我
#9 引用回覆 回覆 發表時間:2005-04-20 18:12:03 IP:221.169.xxx.xxx 未訂閱
真是糟糕,這裡有一個bug.. 請把
memset(map[i], 0, width);
改成
memset(map[i], 0, width*sizeof(unsigned int));
另外我測了一下你的影像,發現這張影像並不是二元影像 裡面還含有除了0,255以外的值 而這隻程式只針對white和black來處理,所以結果不如預期 你用一般影像處理的軟體把白色物體的邊邊一直放大就會看到有灰色的點存在... 不知道你這張影像是不是經過jpg壓過? 請使用真正的二元影像
bala0514
一般會員


發表:42
回覆:37
積分:15
註冊:2004-07-26

發送簡訊給我
#10 引用回覆 回覆 發表時間:2005-04-20 19:20:34 IP:163.28.xxx.xxx 未訂閱
引言: 真是糟糕,這裡有一個bug.. 請把
memset(map[i], 0, width);
改成
memset(map[i], , width*sizeof(unsigned int));
另外我測了一下你的影像,發現這張影像並不是二元影像 裡面還含有除了0,255以外的值 而這隻程式只針對white和black來處理,所以結果不如預期 你用一般影像處理的軟體把白色物體的邊邊一直放大就會看到有灰色的點存在... 不知道你這張影像是不是經過jpg壓過? 請使用真正的二元影像
justdo你好,我將測試影像換過,換成二值化影像,如下圖一,並且再加以測試,更改過妳提供的程式部分再做測試,程式碼如下,結果全部白色區塊皆塗成藍色,如下圖二,我是想要中間那大塊白色區塊保留,其餘皆圖上藍色,問題出在???不好意思麻煩你嚕!!我在測試看看~~謝謝指教~~!! 圖一 圖二 程式碼如下:
   unsigned int a=StrToInt(Edit1->Text);
   unsigned int b=StrToInt(Edit2->Text);
   int c = 0;   
   int id=1;
   unsigned int counts=0;
   unsigned int maxcounts=0;
   unsigned int maxid=0;
   Graphics::TBitmap *BMP = new Graphics::TBitmap();
   BMP->Assign(Image1->Picture->Bitmap );
   Byte *ptr=NULL;
   BMP->PixelFormat = pf8bit;
   int width=BMP->Width;
   int height=BMP->Height;
   map=new  unsigned int*[height];
   for (int i=0; iwidth*sizeof(unsigned int) );
   }
   for(int y = 0; yScanLine[y];
      for(int x = 0; x < width; x++)
      {
         if(ptr[x] == 255)
         {
            counts= Connect(BMP, x, y);
             Memo1->Lines->Add("面積"+FloatToStr(counts));
            if (counts > maxcounts)
            {
                maxcounts=counts;
                maxid=id;
            }
            id++;
                          
            if (counts>=a && counts<=b)
            {
             c+=1;    //計算物件各數 (可用像素數cx來限制是否累計)
            //break;
            }
         }
      }
   }
   delete BMP;
   ShowMessage(c);
   ShowMessage(AnsiString("最大面積為區塊:") + maxid + ", 大小=" + maxcounts+" Pixels");
  for (int y=0; yPicture->Bitmap->Canvas->Pixels[x][y]=clBlue;
        }
      }
   }
   for (int i=0; i
謝謝大家指教! ***程式語言真是一門高深的學問***
------
***程式語言真是一門高深的學問***
justdo
高階會員


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

發送簡訊給我
#11 引用回覆 回覆 發表時間:2005-04-20 21:27:14 IP:221.169.xxx.xxx 未訂閱
   unsigned int a=StrToInt(Edit1->Text);
   unsigned int b=StrToInt(Edit2->Text);
   int c = 0;   
   int id=1;  //這行拿掉
Button1Click跟Connect兩個函式的id是共用的全域id變數 當你在Button1Click函式內宣告一個local的id變數時 兩者便已經脫勾
bala0514
一般會員


發表:42
回覆:37
積分:15
註冊:2004-07-26

發送簡訊給我
#12 引用回覆 回覆 發表時間:2005-04-20 21:47:23 IP:163.28.xxx.xxx 未訂閱
引言:
   unsigned int a=StrToInt(Edit1->Text);
   unsigned int b=StrToInt(Edit2->Text);
   int c = 0;   
   int id=1;  //這行拿掉
Button1Click跟Connect兩個函式的id是共用的全域id變數 當你在Button1Click函式內宣告一個local的id變數時 兩者便已經脫勾
謝謝你~~~問題已經解決~結果真的是id的問題,共用一個全域變數!!謝謝你的指教~ 若我的像素範圍限制在a與b之間,我想留住a與b之間的白色區塊,將其他a與b之外的像素用藍色表示,那要將此條件寫在哪段來比較,這樣就可以依自己所需的像素範圍來上色! 謝謝你~~ ~感激不盡! ***程式語言真是一門高深的學問***
------
***程式語言真是一門高深的學問***
justdo
高階會員


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

發送簡訊給我
#13 引用回覆 回覆 發表時間:2005-04-21 07:21:50 IP:221.169.xxx.xxx 未訂閱
請自己先想想看、動手做做看,有問題再問,這樣才會進步 給個提示: 用個陣列將符合你條件的編號記錄下來 找出所有的白色物體之後,再檢查每個pixel在map變數的編號, 沒有出現在前述陣列內的話,就塗掉
bala0514
一般會員


發表:42
回覆:37
積分:15
註冊:2004-07-26

發送簡訊給我
#14 引用回覆 回覆 發表時間:2005-04-21 17:30:34 IP:163.28.xxx.xxx 未訂閱
引言: 請自己先想想看、動手做做看,有問題再問,這樣才會進步 給個提示: 用個陣列將符合你條件的編號記錄下來 找出所有的白色物體之後,再檢查每個pixel在map變數的編號, 沒有出現在前述陣列內的話,就塗掉
justdo大大!!你好 我大概寫了一下:
新增:
unsigned int a=StrToInt(Edit1->Text);
unsigned int b=StrToInt(Edit2->Text);
unsigned int test=0;    if((counts>=a) && (counts<=b))
{a=counts;b=counts;test=id;}id  ;
還有
if(map[y][x]!=test && map[y][x]!=0)
{Image1->Picture->Bitmap->Canvas->Pixels[x][y]=clBlack;}
是加入這幾行??出來的結果他會將一些濾除!但是有點怪~,不好意思我不太瞭解~且程式不知要如何表示@@真是一個頭兩個大!希望你能幫我解答~~謝謝 ***程式語言真是一門高深的學問*** 發表人 - bala0514 於 2005/04/21 17:53:55
------
***程式語言真是一門高深的學問***
justdo
高階會員


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

發送簡訊給我
#15 引用回覆 回覆 發表時間:2005-04-21 20:59:16 IP:221.169.xxx.xxx 未訂閱
引言: justdo大大!!你好 我大概寫了一下:
新增:
unsigned int a=StrToInt(Edit1->Text);
unsigned int b=StrToInt(Edit2->Text);
unsigned int test=0;
這裡應該宣告成陣列,陣列才能記錄多筆的資料,還是你確定只有一個白色物體會符合使用者設定的條件?    if((counts>=a) && (counts<=b))
{a=counts;b=counts;test=id;}id  ;
把counts指定給a跟b?why??為何你要改變上限跟下限?還且還設定成一樣的值?
還有
if(map[y][x]!=test && map[y][x]!=0)
{Image1->Picture->Bitmap->Canvas->Pixels[x][y]=clBlack;}
是加入這幾行??出來的結果他會將一些濾除!但是有點怪~,不好意思我不太瞭解~且程式不知要如何表示@@真是一個頭兩個大!希望你能幫我解答~~謝謝 ***程式語言真是一門高深的學問*** 發表人 - bala0514 於 2005/04/21 17:53:55
bala0514
一般會員


發表:42
回覆:37
積分:15
註冊:2004-07-26

發送簡訊給我
#16 引用回覆 回覆 發表時間:2005-04-21 23:53:40 IP:220.139.xxx.xxx 未訂閱
justdo大大!!你好 是這樣嗎??unsigned int test[50]; 小弟我試了好久~還是不知道要如何下手!不知可否幫我解決呢? 有些程式部分並不是很上手!請多多指教!不好意思~ 謝謝指導! ***程式語言真是一門高深的學問*** 發表人 -
------
***程式語言真是一門高深的學問***
1666362
初階會員


發表:66
回覆:124
積分:43
註冊:2004-07-07

發送簡訊給我
#17 引用回覆 回覆 發表時間:2005-04-22 01:08:13 IP:210.192.xxx.xxx 未訂閱
to bala0514 不知道您的問題出在哪邊  小弟我用justdo大的程式碼 下去作稍微的修改而已  就得到您要的功能 做出來的效果如下
bala0514
一般會員


發表:42
回覆:37
積分:15
註冊:2004-07-26

發送簡訊給我
#18 引用回覆 回覆 發表時間:2005-04-22 01:20:45 IP:220.139.xxx.xxx 未訂閱
引言: to bala0514 不知道您的問題出在哪邊 小弟我用justdo大的程式碼 下去作稍微的修改而已 就得到您要的功能 做出來的效果如下 >< face="Verdana, Arial, Helvetica"> 1666362妳好,妳的意思我懂!我最主要的目的是,利用兩個Edit1與Edit,內輸入像素的範圍區間,若假使算出來各區塊的像素各為: 27,59,68,115,47,234,56,959,而我想將Pixel 100與Pixel 500間的區塊填為藍色,就如115與234 pixel這兩塊,其餘的就塗成紅色,就如剩餘的27,59.68,47,56,959,等六個區塊,就是大概這樣!< > 謝謝你提供意見!呼!我還要再加油嚕~~< > ***程式語言真是一門高深的學問***
------
***程式語言真是一門高深的學問***
bala0514
一般會員


發表:42
回覆:37
積分:15
註冊:2004-07-26

發送簡訊給我
#19 引用回覆 回覆 發表時間:2005-04-22 12:25:08 IP:163.28.xxx.xxx 未訂閱
引言: 請自己先想想看、動手做做看,有問題再問,這樣才會進步 給個提示: 用個陣列將符合你條件的編號記錄下來 找出所有的白色物體之後,再檢查每個pixel在map變數的編號, 沒有出現在前述陣列內的話,就塗掉
justdo你好!我試了一下~我輸入的像素範圍為100-800之間,照道理來說,有兩個區塊符合這個範圍,會被塗成紅色,其餘區塊會被塗成藍色,但是程式撰寫過後,僅有找到一塊在範圍間的,另一塊沒找到,如下圖一箭頭那一區塊。是程式中id的判斷問題?還是其他問題呢?謝謝你幫我解答 < class="code"> unsigned int otherid=0; //unsigned int othercounts=0; int label[50]; if((counts>=a) && (counts<=b)) {label[x]=counts;otherid=id;Memo2->Lines->Add("id: "+FloatToStr(otherid)+" 面積: "+FloatToStrcounts));} for (int y=0; yPicture->Bitmap->Canvas->Pixels[x][y]=clRed;} if((map[y][x] != otherid) && (map[y][x] != 0)) {Image1->Picture->Bitmap->Canvas->Pixels[x][y]=clBlue;} } } 圖一 謝謝你! ***程式語言真是一門高深的學問*** 發表人 -
------
***程式語言真是一門高深的學問***
justdo
高階會員


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

發送簡訊給我
#20 引用回覆 回覆 發表時間:2005-04-23 00:56:22 IP:221.169.xxx.xxx 未訂閱
引言:
if((counts>=a) && (counts<=b))
{label[x]=counts;otherid=id;Memo2->Lines->Add("id: " FloatToStr(otherid) " 面積: " FloatToStrcounts));}
上面這一段跑完,otherid只會得到一個值:最後一個符合條件的編號!!請用陣列把符合條件的id都記下來
for (int y=0; yPicture->Bitmap->Canvas->Pixels[x][y]=clRed;}          if((map[y][x] != otherid) && (map[y][x] != 0))
       {Image1->Picture->Bitmap->Canvas->Pixels[x][y]=clBlue;}
      }
   }
bala0514
一般會員


發表:42
回覆:37
積分:15
註冊:2004-07-26

發送簡訊給我
#21 引用回覆 回覆 發表時間:2005-04-23 11:17:43 IP:163.28.xxx.xxx 未訂閱
引言:
if((counts>=a) && (counts<=b))
{label[x]=counts;otherid=id;Memo2->Lines->Add("id: " FloatToStr(otherid) " 面積: " FloatToStrcounts));}
上面這一段跑完,otherid只會得到一個值:最後一個符合條件的編號!!請用陣列把符合條件的id都記下來
for (int y=0; yPicture->Bitmap->Canvas->Pixels[x][y]=clRed;}          if((map[y][x] != otherid) && (map[y][x] != 0))
       {Image1->Picture->Bitmap->Canvas->Pixels[x][y]=clBlue;}
      }
   }
justdo大大!!你好 小弟我試了好久~還是不知道要如何下手!
unsigned int otherid[50];
if((counts>=a) && (counts<=b))
{label[x]=counts;otherid[x]=id;}    for (int y=0; yPicture->Bitmap->Canvas->Pixels[x][y]=clRed;}
     if((map[y][x] !=otherid[d]) && (map[y][x] != 0))
     {Image1->Picture->Bitmap->Canvas->Pixels[x][y]=clBlue;}
      }}}
不好意思~我真是笨阿!@@< >< > 謝謝指導! ***程式語言真是一門高深的學問*** 發表人 -
------
***程式語言真是一門高深的學問***
bala0514
一般會員


發表:42
回覆:37
積分:15
註冊:2004-07-26

發送簡訊給我
#22 引用回覆 回覆 發表時間:2005-04-24 20:22:07 IP:163.28.xxx.xxx 未訂閱
引言: 請自己先想想看、動手做做看,有問題再問,這樣才會進步 給個提示: 用個陣列將符合你條件的編號記錄下來 找出所有的白色物體之後,再檢查每個pixel在map變數的編號, 沒有出現在前述陣列內的話,就塗掉
justdo大大你好,我又試了一次,結果還是有些問題,我將完整的程式碼與show出的結果跟你討論.不好意思打擾你這麼久,Memo1上是所有的像素值,Memo2是範圍間的id與像素值,但是上色依然沒有在範圍間的像素區塊間上色,謝謝指教@@
void __fastcall TForm1::Button1Click(TObject *Sender)
{
   Memo1->Lines->Clear();Memo2->Lines->Clear();
   unsigned  int a=StrToInt(Edit1->Text);
   unsigned  int b=StrToInt(Edit2->Text);
   int c = 0,i;
   unsigned int counts=0;
   unsigned int maxcounts=0;
   unsigned int maxid=0;
   unsigned int otherid[10];
   unsigned int test[10];
   Graphics::TBitmap *BMP = new Graphics::TBitmap();
   BMP->Assign(Image1->Picture->Bitmap);
   Byte *ptr=NULL;
   BMP->PixelFormat = pf8bit;
   int width=BMP->Width;
   int height=BMP->Height;
   map=new  unsigned int*[height];
   for (int i=0; iScanLine[y];
      for(int x = 0; x < width; x++)
      {
         if(ptr[x] == 255)
         {
         counts= Connect(BMP, x, y);
          Memo1->Lines->Add("面積:"+FloatToStr(counts));
         //****測試             if((counts>=a) && (counts<=b))
         {for(i=0;i<10;i++)
           {
          test[i]=counts;
          otherid[i]=id;
           }
  Memo2->Lines->Add("id: "+IntToStr(id)+" 面積: "+IntToStr(counts));
          }
            if (counts > maxcounts)
            {maxcounts=counts;maxid=id;}            
            id++;
            if (counts>=a && counts<=b)
            {
             c+=1;    //計算物件各數
            //break;
            }}}}
    
   delete BMP;
   ShowMessage(c);
   ShowMessage(AnsiString("最大面積為區塊:") + maxid + ", 大小=" + maxcounts+" Pixels");
  for (int y=0; yPicture->Bitmap->Canvas->Pixels[x][y]=clBlue;
         }           if((map[y][x] != otherid[i]) && (map[y][x] != 0))
        {
         Image1->Picture->Bitmap->Canvas->Pixels[x][y]=clRed;
        }
      }
    //*********}}
   for (int i=0; i
圖一 謝謝 ***程式語言真是一門高深的學問***
------
***程式語言真是一門高深的學問***
justdo
高階會員


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

發送簡訊給我
#23 引用回覆 回覆 發表時間:2005-04-25 19:55:00 IP:221.169.xxx.xxx 未訂閱
引言:
if((counts>=a) && (counts<=b))
{
  for(i=0;i<10;i  )
  {
    test[i]=counts;
    otherid[i]=id;
  }
}
這種寫法,當有一個符合你條件的id出現時,會把test[0]~test[9]都填入counts、otherid[0]~otherid[9]都填入id,這並不是你要的東西,你要的應該是第一個符合者,填入test[0]和otherid[0]、第二個符合者填入test[1]和otherid[1]...,因此應該改成
if((counts>=a) && (counts<=b))
{
  test[i]=counts;
  otherid[i]=id;
    i;
}
記得在進入搜尋迴圈之前,要重設i值為0
沒有實際測測看,試試看吧 發表人 - justdo 於 2005/04/25 19:57:20
bala0514
一般會員


發表:42
回覆:37
積分:15
註冊:2004-07-26

發送簡訊給我
#24 引用回覆 回覆 發表時間:2005-04-25 20:18:04 IP:61.222.xxx.xxx 未訂閱
justdo大大你好,我剛剛試了一下~還是不行!結果還是在範圍間填色部分~那出了問題呢??不好意思又要請教你嚕~~!< >互相學習~一直打擾你真是歹事!< >
int i=0;
for(int y = 0; yScanLine[y];
      for(int x = 0; x < width; x  )
      {if(ptr[x] == 255)
         {counts= Connect(BMP, x, y);
          Memo1->Lines->Add("面積:" FloatToStr(counts));
        //****測試
         if((counts>=a) && (counts<=b))
         { for(i=0;i<10;i  )
           {test[i]=counts;
          otherid[i]=id;
            i;
           }
  Memo2->Lines->Add("id: " IntToStr(id) " 面積: " IntToStr(counts));
         }     for (int y=0; yPicture->Bitmap->Canvas->Pixels[x][y]=clBlue;}
       if((map[y][x] != otherid[i]) && (map[y][x] != 0))
        {Image1->Picture->Bitmap->Canvas->Pixels[x][y]=clRed;}}
     }
   }
***程式語言真是一門高深的學問***
------
***程式語言真是一門高深的學問***
justdo
高階會員


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

發送簡訊給我
#25 引用回覆 回覆 發表時間:2005-04-25 21:49:24 IP:221.169.xxx.xxx 未訂閱
引言:
int i=0;
for(int y = 0; yScanLine[y];
      for(int x = 0; x < width; x  )
      {if(ptr[x] == 255)
         {counts= Connect(BMP, x, y);
          Memo1->Lines->Add("面積:" FloatToStr(counts));
        //****測試
         if((counts>=a) && (counts<=b))
         { for(i=0;i<10;i  ) 這行要拿掉啦,我的文字說明都沒在看喔
           {>>>    ***程式語言真是一門高深的學問***
< face="Verdana, Arial, Helvetica">     
        
bala0514
一般會員


發表:42
回覆:37
積分:15
註冊:2004-07-26

發送簡訊給我
#26 引用回覆 回覆 發表時間:2005-04-25 23:26:51 IP:61.31.xxx.xxx 未訂閱
引言:
int i=0;
for(int y = 0; yScanLine[y];
      for(int x = 0; x < width; x++)
      {if(ptr[x] == 255)
         {counts= Connect(BMP, x, y);
          Memo1->Lines->Add("面積:"+FloatToStr(counts));
        //****測試
         if((counts>=a) && (counts<=b))
         { for(i=0;i<10;i++) 這行要拿掉啦,我的文字說明都沒在看喔
           {>>>
< face="Verdana, Arial, Helvetica">
justdo大大,不好意思一直麻煩你,我將那行移除,可是結果還是一樣!
不好意思讓妳生氣了!應該有 >
< src="http://delphi.ktop.com.tw/loadfile.php?TOPICID=21848039&CC=488621">圖一    ***程式語言真是一門高深的學問***
        
------
***程式語言真是一門高深的學問***
justdo
高階會員


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

發送簡訊給我
#27 引用回覆 回覆 發表時間:2005-04-26 20:54:01 IP:221.169.xxx.xxx 未訂閱
我...  算了,還是把完整的code貼上來... 紅色是有修改的地方    
void __fastcall TForm1::Button1Click(TObject *Sender)
{
   Memo1->Lines->Clear();Memo2->Lines->Clear();
   unsigned  int a=StrToInt(Edit1->Text);
   unsigned  int b=StrToInt(Edit2->Text);
   int c = 0,i;
   unsigned int counts=0;
   unsigned int maxcounts=0;
   unsigned int maxid=0;
   unsigned int otherid[10];
   unsigned int otherid_num=0; //otherid記錄的數量 
   unsigned int test[10];
   Graphics::TBitmap *BMP = new Graphics::TBitmap();
   BMP->Assign(Image1->Picture->Bitmap);
   Byte *ptr=NULL;
   BMP->PixelFormat = pf8bit;
   int width=BMP->Width;
   int height=BMP->Height;
   map=new  unsigned int*[height];
   for (i=0; iScanLine[y];
      for(int x = 0; x < width; x  )
      {
         if(ptr[x] == 255)
         {
         counts= Connect(BMP, x, y);
          Memo1->Lines->Add("面積:" FloatToStr(counts));
         if((counts>=a) && (counts<=b))
         {
          test[otherid_num]=counts;
          otherid[otherid_num]=id;
          otherid_num  ; 
  Memo2->Lines->Add("id: " IntToStr(id) " 面積: " IntToStr(counts));
          }
            if (counts > maxcounts)
            {maxcounts=counts;maxid=id;}
            id  ;
}}}
   delete BMP;
   ShowMessage(AnsiString("最大面積為區塊:")   maxid   ", 大小="   maxcounts " Pixels");
  for (int y=0; yPicture->Bitmap->Canvas->Pixels[x][y]=clBlue;
       else if (map[y][x] != 0)
         Image1->Picture->Bitmap->Canvas->Pixels[x][y]=clRed;
    }
    }
   for (int i=0; iPicture->Bitmap->Canvas->Pixels[x][y]=clBlue;}
       if((map[y][x] != otherid[i]) && (map[y][x] != 0))
        {Image1->Picture->Bitmap->Canvas->Pixels[x][y]=clRed;}}
     }
   }
(1)當符合條件的id數量少於10或多於10的時候,都會出問題 (2)中間的迴圈會跑10次,假設幸運的,迴圈第一次檢查map[y][x]恰巧為otherid[0],則馬上畫藍色上去,然後跑第二次迴圈檢查,此時map[y][x]必然不等於otherid[1],則馬上又被畫紅色上去...,顯然這並非我們要的。
bala0514
一般會員


發表:42
回覆:37
積分:15
註冊:2004-07-26

發送簡訊給我
#28 引用回覆 回覆 發表時間:2005-04-26 22:05:29 IP:61.30.xxx.xxx 未訂閱
justdo大大~你人真是好~ 從妳身上讓我學會了更多東西~讓我對程式的瞭解有更深的認知~! 謝謝你!替我解決了問題!謝謝< > 妳不厭其煩的回我問題~真是個好人~最後還是要跟你說聲謝謝!< > ***程式語言真是一門高深的學問***
------
***程式語言真是一門高深的學問***
系統時間:2024-11-25 14:50:18
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!