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

請問關於Sobel測邊,小弟的程式碼怪怪的

尚未結案
xdio2
一般會員


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

發送簡訊給我
#1 引用回覆 回覆 發表時間:2004-10-25 16:40:33 IP:61.59.xxx.xxx 未訂閱
想請問一下各位大大觀念 所謂的Sobel測邊方式 就是使用兩個遮罩對Pixels作運算吧? 這兩個遮罩分別是 x方向 -1 -2 -1  0  0  0  1  2  1 y方向 -1  0  1 -2  0  2 -1  0  1    可是小弟做出來的結果似乎很差 想請問大大我下面的程式碼是否有哪裡錯誤 還是說我觀念徹底錯誤... 請大大們耐心為我看一下 感謝~     
//p1陣列用來放24bit彩圖轉灰階後,每一個pixels的灰階值    int p1[1000][1000];    void p1Pixel(Graphics::TBitmap *pBmp)
{    Byte *ptr;
for (int i=0;iHeight;i   )
 {
  ptr=(Byte*)pBmp->ScanLine[i];
  for (int j=0;jWidth; j   )
  {
   p1[i][j]=ptr[j*3];
  }
 }    //Sobel測邊的主程式碼    void __fastcall TForm1::Sobel2Click(TObject *Sender)
{
 //先用Bmp來暫存讀入的圖像
 Graphics::TBitmap *Bmp = new Graphics::TBitmap();
 Byte *ptr;
 Bmp->Assign(Image1->Picture->Bitmap );    //使用p1Pixel函式存入每一個pixel的灰階值
 p1Pixel(Bmp);
//開始用兩個遮罩來計算
for(int i=0;iHeight;i  )
 {
  ptr=(Byte*)Bmp->ScanLine[i];
  for (int j=0;jWidth; j   )
   {
       int GX;
      int p[10]={0};
      
      p[1]=p1[i-1][j-1];
      p[2]=p1[i][j-1];
      p[3]=p1[i 1][j-1];
      p[4]=p1[i-1][j];
      p[5]=p1[i][j];
      p[6]=p1[i 1][j];
      p[7]=p1[i-1][j 1];
      p[8]=p1[i][j 1];
      p[9]=p1[i 1][j 1];          GX=(p[3] p[6]*2 p[9])-(p[1] p[4]*2 p[7]); //x方向的遮罩          if(GX<0)
      GX=-GX;
            int GY;          p[1]=p1[i-1][j-1];
      p[2]=p1[i][j-1];
      p[3]=p1[i 1][j-1];
      p[4]=p1[i-1][j];
      p[5]=p1[i][j];
      p[6]=p1[i 1][j];
      p[7]=p1[i-1][j 1];
      p[8]=p1[i][j 1];
      p[9]=p1[i 1][j 1];
      GY=p[7] p[8]*2 p[9]-(p[1] p[2]*2 p[3]); //y方向的遮罩          if(GY<0)
      GY=-GY;          for(int z=0;z<3;z  )
      ptr[j*3 z*1]=GX GY;       }
  }
  
  Image2->Picture->Assign(Bmp); //把結果存到Image2
  delete Bmp;
}
 
發表人 - xdio2 於 2004/10/25 16:44:38
TheMoon
中階會員


發表:17
回覆:95
積分:67
註冊:2002-06-05

發送簡訊給我
#2 引用回覆 回覆 發表時間:2004-10-26 17:51:19 IP:202.39.xxx.xxx 未訂閱
//p1陣列用來放24bit彩圖轉灰階後,每一個pixels的灰階值
int p1[1000][1000];    void p1Pixel(Graphics::TBitmap *pBmp)
{
 Byte *ptr;
 for (int i=0;iHeight;i   )
 {
   ptr=(Byte*)pBmp->ScanLine[i];
   for (int j=0;jWidth; j   )
   {
     p1[i][j]=ptr[j*3]; //<--(3)小細節
   }
 }
}    //Sobel測邊的主程式碼
void __fastcall TForm1::Sobel2Click(TObject *Sender)
{
 //先用Bmp來暫存讀入的圖像
 Graphics::TBitmap *Bmp = new Graphics::TBitmap();
 Byte *ptr;
 Bmp->Assign(Image1->Picture->Bitmap );     //使用p1Pixel函式存入每一個pixel的灰階值
 p1Pixel(Bmp);     //開始用兩個遮罩來計算
 for(int i=0; iHeight; i  )
 {
   ptr=(Byte*)Bmp->ScanLine[i];
   for (int j=0; jWidth; j  ) //<--(2)小細節
   {
      int p[10]={0,0,0,0,0,0,0,0,0,0};
      int GX;
      p[1]=p1[i-1][j-1];
      p[2]=p1[i][j-1];
      p[3]=p1[i 1][j-1];
      p[4]=p1[i-1][j];
      p[5]=p1[i][j];
      p[6]=p1[i 1][j];
      p[7]=p1[i-1][j 1];
      p[8]=p1[i][j 1];
      p[9]=p1[i 1][j 1];
      GX=(p[3] p[6]*2 p[9])-(p[1] p[4]*2 p[7]); //x方向的遮罩          if(GX<0) GX=-GX;          int GY;
      //(4)小細節
      p[1]=p1[i-1][j-1];
      p[2]=p1[i][j-1];
      p[3]=p1[i 1][j-1];
      p[4]=p1[i-1][j];
      p[5]=p1[i][j];
      p[6]=p1[i 1][j];
      p[7]=p1[i-1][j 1];
      p[8]=p1[i][j 1];
      p[9]=p1[i 1][j 1];
      GY=p[7] p[8]*2 p[9]-(p[1] p[2]*2 p[3]); //y方向的遮罩          if(GY<0) GY=-GY;          for(int z=0;z<3;z  )
      ptr[j*3 z*1]=GX GY; //<--(1)主要問題在此
   }
 }     Image2->Picture->Assign(Bmp); //把結果存到Image2
 delete Bmp;
}
(1)主要問題:GX GY的值要除以2,並且要判斷此值是否介於0~255之間。
(2)小細節:最好判斷i,j是否是邊界值,以避免index超出陣列存取範圍。
(3)小細節:這是只取RGB中某一色平面之值作灰階值,與一般彩色轉灰階作法不一樣,請參考
    http://delphi.ktop.com.tw/topic.php?topic_id=46261
(4)小細節:底下給值的動作似乎與上頭重複,可以省略。
發表人 - TheMoon 於 2004/10/26 17:59:26
xdio2
一般會員


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

發送簡訊給我
#3 引用回覆 回覆 發表時間:2004-10-26 18:41:01 IP:61.59.xxx.xxx 未訂閱
感謝您的回應喔! 小弟沒事先說明其實圖片都是已經作過灰階處理了 我用這功能時都是對灰階圖 算是我問問題沒問清楚 感謝這位大大的回應, 請問當我超出255的狀況時 是會發生奇怪的溢位狀況嗎? 再次感謝您的回覆~
TheMoon
中階會員


發表:17
回覆:95
積分:67
註冊:2002-06-05

發送簡訊給我
#4 引用回覆 回覆 發表時間:2004-10-27 13:29:16 IP:202.39.xxx.xxx 未訂閱
引言: 請問當我超出255的狀況時 是會發生奇怪的溢位狀況嗎? 再次感謝您的回覆~
因為在BCB中, Byte資料型態相當於8位元的unsigned integer, 所以資料範圍是在0~255之間, 若數值X超出255的話, 系統會將X表示成(X mod 256)的值。 255 → 11111111 256 →100000000 (最左邊那一位會被捨棄)
xdio2
一般會員


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

發送簡訊給我
#5 引用回覆 回覆 發表時間:2004-10-27 19:04:48 IP:61.59.xxx.xxx 未訂閱
引言:
引言: 請問當我超出255的狀況時 是會發生奇怪的溢位狀況嗎? 再次感謝您的回覆~
因為在BCB中, Byte資料型態相當於8位元的unsigned integer, 所以資料範圍是在0~255之間, 若數值X超出255的話, 系統會將X表示成(X mod 256)的值。 255 → 11111111 256 →100000000 (最左邊那一位會被捨棄) < face="Verdana, Arial, Helvetica"> 多謝您的解釋喔 那我再多請問一下您,上次的回答中您說要把(GX GY)/2 那是說(GX GY)/2要是大於255時,我必須做些檢查,好比說就直接設為255 若是(GX GY)/2沒大於255,那我就把那個像素的值放入(GX GY)/2的值囉? 請問除以二是Sobel理論中的道理嗎? 勞煩您解惑了 感謝~
TheMoon
中階會員


發表:17
回覆:95
積分:67
註冊:2002-06-05

發送簡訊給我
#6 引用回覆 回覆 發表時間:2004-10-28 10:23:01 IP:202.39.xxx.xxx 未訂閱
多謝您的解釋喔
那我再多請問一下您,上次的回答中您說要把(GX GY)/2
那是說(GX GY)/2要是大於255時,我必須做些檢查,好比說就直接設為255
A:Yes    若是(GX GY)/2沒大於255,那我就把那個像素的值放入(GX GY)/2的值囉?
A:Yes    請問除以二是Sobel理論中的道理嗎?
A:Yes

     -1 -2 -1          -1  0  1
[abs( 0  0  0 )   abs( -2  0  2 )]/2
      1  2  1          -1  0  1

發表人 - TheMoon 於 2004/10/28 10:25:52
系統時間:2024-07-01 5:45:29
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!