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

請問哪種的方法對於edge detection較好呢?

尚未結案
paf
初階會員


發表:36
回覆:70
積分:41
註冊:2002-12-27

發送簡訊給我
#1 引用回覆 回覆 發表時間:2004-08-01 03:41:44 IP:218.164.xxx.xxx 未訂閱
看了很多文章 好像較常用的是sobel 而梯形法中也有其他的方法 或是Laplacian 為什麼不用呢??是因為不好實作. 還是效率不佳呢? 因為小弟想找一個比sobel效果還好的 初接觸影像處理(有關人臉邊緣偵測) 不知道前輩們可否指教一下..謝謝!!!
adonis
高階會員


發表:140
回覆:258
積分:159
註冊:2002-04-15

發送簡訊給我
#2 引用回覆 回覆 發表時間:2004-08-02 10:02:34 IP:210.201.xxx.xxx 未訂閱
paf, 您好 我想並沒有什麼方法比較好或不好,只不過都是從不同或相似的理論基礎而來。 再針對不同的作法及其所表現出來的效果來選取自己所需應用的層面而已。當然,很多時候其執行效率或實作上的難易也會成為程式設計者的重要考量之一,但我個人覺得在邊緣偵測這部份被提出來的理論和作法著實不少,你可以將相關所得知的理論實作後去交叉比對,最後綜合你所要的結果,我想對你而言,當下的實作至少已是不差的選擇。 提供參考一下個人的想法。 我也正在努力學習中 ^^
------
我也在努力學習中,若有錯謬請見諒。
paf
初階會員


發表:36
回覆:70
積分:41
註冊:2002-12-27

發送簡訊給我
#3 引用回覆 回覆 發表時間:2004-08-03 13:14:22 IP:218.164.xxx.xxx 未訂閱
引言: 看了很多文章 好像較常用的是sobel 而梯形法中也有其他的方法 或是Laplacian 為什麼不用呢??是因為不好實作. 還是效率不佳呢? 因為小弟想找一個比sobel效果還好的 初接觸影像處理(有關人臉邊緣偵測) 不知道前輩們可否指教一下..謝謝!!!
最後小弟選擇了用LoG (Laplacian of Gaussian)來做edge detection 現在有個問題!就是如果用一個9*9kernel跟原始圖做遮罩之後 算出來的那個值大於255,或是小於0 請問該如何處理呢??? 謝謝
adonis
高階會員


發表:140
回覆:258
積分:159
註冊:2002-04-15

發送簡訊給我
#4 引用回覆 回覆 發表時間:2004-08-04 09:16:38 IP:210.201.xxx.xxx 未訂閱
paf, 您好 這很簡單,在程式中多個判斷即可。 大於255的值讓其等於255;小於0的值讓其等於0即可。 我也正努力學習中 ^ ^
------
我也在努力學習中,若有錯謬請見諒。
paf
初階會員


發表:36
回覆:70
積分:41
註冊:2002-12-27

發送簡訊給我
#5 引用回覆 回覆 發表時間:2004-08-07 14:03:59 IP:220.143.xxx.xxx 未訂閱
引言: paf, 您好 這很簡單,在程式中多個判斷即可。 大於255的值讓其等於255;小於0的值讓其等於0即可。
void __fastcall TForm1::Button1Click(TObject *Sender)
{
   Graphics::TBitmap *Bmp1 = new Graphics::TBitmap();
   Graphics::TBitmap *Bmp2 = new Graphics::TBitmap();       //sigma = 1.4
   int kernel[] ={0, 1, 1,  2,  2,  2, 1, 1, 0,
                1, 2, 4,  5,  5,  5, 4, 2, 1,
                1, 4, 5,  3,  0,  3, 5, 4, 1,
                2, 5, 3,-12,-24,-12, 3, 5, 2,
                2, 5, 0,-24,-40,-24, 0, 5, 2,
                2, 5, 3,-12,-24,-12, 3, 5, 2,
                1, 4, 5,  3,  0,  3, 5, 4, 1,
                1, 2, 4,  5,  5,  5, 4, 2, 1,
                0, 1, 1,  2,  2,  2, 1, 1, 0};       if(OpenDialog1->Execute())
   {
      Image1->Picture->LoadFromFile(OpenDialog1->FileName);
      Bmp1->LoadFromFile(OpenDialog1->FileName);
   }       int Width = Bmp1->Width;
   int Height = Bmp1->Height;       Bmp2->Width = Width;
   Bmp2->Height = Height;
   Bmp2->PixelFormat = pf24bit;       int *buffer = new int [Height * Width];
   int *result = new int [Height * Width];
   Byte *ptr1, *ptr2;       for(int row = 0; row < Height; row++)
   {
      ptr1 = (Byte *)Bmp1->ScanLine[row];
      //ptr2 = (Byte *)Bmp2->ScanLine[row];          for(int col = 0, k = 0; col < Width * 3; col += 3, k++)
      {
         //因為是Gray 所以RGB三個值都一樣
         buffer[row*Width+k] = ptr1[col];
         //result[row*Width+k] = 500;
      }
   }       //***************Convolution***************
   double value;       for(int row = 4; row < Height - 4; row++)
   {
      for(int col = 4; col < Width - 4; col++)
      {
         // Convolution計算
         value = 0;
         for(int r = -4; r <= 4; r++)
         {
            for(int c = -4; c <= 4; c++)
            {
               value += buffer[(row+r)*Width+col+c] * kernel[(r+4)*9+c+4];
            }
         }
         if(value > 255)
            value = value - 255;
         else if(value < 0)
            value = -value + 255;             result[row*Width+col] = value/40;          } // end of for(col)
   } // end of for(row)       for(int j = 0; j < Height; j++)
   {
      for(int i = 0; i < Width; i++)
         Bmp2->Canvas->Pixels[i][j] = (TColor)RGB(result[j*Width+i], result[j*Width+i], result[j*Width+i]);
   }
   Image2->Canvas->Draw(0, 0, Bmp2);
}
執行結果 如果在程式碼紅色的部分 改為前輩您說的大於255即assign 255..小於0則assign 0
if(value > 255)
   value = 255;
else if(value < 0)
   value = 0;    result[row*Width+col] = value;
則結果為 但我覺得用LoG的方法來抓取邊緣...似乎以第一張圖那樣子..比較像是 用LoG所抓出來的邊緣...其實小弟也不曉得. 請前輩們指教...謝謝!!! 發表人 - paf 於 2004/08/07 14:06:54 發表人 - paf 於 2004/08/07 14:08:07
adonis
高階會員


發表:140
回覆:258
積分:159
註冊:2002-04-15

發送簡訊給我
#6 引用回覆 回覆 發表時間:2004-08-08 17:27:36 IP:61.64.xxx.xxx 未訂閱
paf, 您好    很高與看到你實作的部份。 Laplacian of Gaussian 的作法想必也是從一開始的理論基礎上來推導並改良的方法,若回到一開始的Laplacina Operator簡直就像極了高通的作法去作邊緣的強調(就理論而言其實也沒錯)。 而您的 
引言:if(value > 255) value = value - 255; else if(value < 0) value = -value + 255; result[row*Width+col] = value/40;
是透過公式而來還是...? 但我要強調的還是影像處理所要的是最終的適合結果,並沒有所謂的誰好或誰不好,所以就需求上來看似乎現階段你在處理大於255或小於0的作法上遠比我所提供的作法要來的好,那當然就是最好的選擇囉。而我之所以會提出這樣的處理機制不外乎是1個bute所能表現的不就是0~255嗎?而且仔細看你的圖,你不覺得那裡怪怪的嗎?..有沒有發現邊緣其實只是亮暗所形成的交界,而你的圖卻是亮暗亮暗,這已是重複邊緣,若將該圖作二值化,臨界值取低一點則更明顯,你可以嘗試看看。 而你使用我所提供的方法所產生的圖形之所以會"長成這樣",這絕對和你的int kernel[] 有關,若只是單純的Laplacina Operator也不致如此。 我提供另一種Edge Detection的作法(裡頭對大於255和小於0的處理機制就是利用我所建議你的作法) 很高與能與你一起學習。 我也正在努力學習中 ^ ^ 發表人 - adonis 於 2004/08/08 17:38:40 發表人 - adonis 於 2004/08/08 17:44:30 發表人 - adonis 於 2004/08/08 17:47:05
------
我也在努力學習中,若有錯謬請見諒。
paf
初階會員


發表:36
回覆:70
積分:41
註冊:2002-12-27

發送簡訊給我
#7 引用回覆 回覆 發表時間:2004-08-08 22:42:29 IP:218.164.xxx.xxx 未訂閱
引言: 但我要強調的還是影像處理所要的是最終的適合結果,並沒有所謂的誰好或誰不好,所以就需求上來看似乎現階段你在處理大於255或小於0的作法上遠比我所提供的作法要來的好,那當然就是最好的選擇囉。而我之所以會提出這樣的處理機制不外乎是1個bute所能表現的不就是0~255嗎?而且仔細看你的圖,你不覺得那裡怪怪的嗎?..有沒有發現邊緣其實只是亮暗所形成的交界,而你的圖卻是亮暗亮暗,這已是重複邊緣,若將該圖作二值化,臨界值取低一點則更明顯,你可以嘗試看看。 而你使用我所提供的方法所產生的圖形之所以會"長成這樣",這絕對和你的int kernel[] 有關,若只是單純的Laplacina Operator也不致如此。 我提供另一種Edge Detection的作法(裡頭對大於255和小於0的處理機制就是利用我所建議你的作法)
adonis前輩您好 我看了你抓出來的邊緣非常地乾淨俐落 不知道前輩您是用哪種作法呢??是單純的Laplacian Operator嗎? 是否能分享一下code呢? 謝謝!!! (我不用Laplacian是因為文獻描述它對雜訊的敏感度較高 容易也把雜訊給抓了出來...故而科學家就研究一套理論 就是將Gaussian smoothing的技術整合到Laplacian operator 而產生了LoG這個改良的方法) 我也覺得我抓出來的圖..也許是kernel的不同而造成不同結果 至於如何的產生一個好的kernel..不知道有何依據呢? 剛接觸影像處理...要學的領域還很多的...還得靠前輩的指教
adonis
高階會員


發表:140
回覆:258
積分:159
註冊:2002-04-15

發送簡訊給我
#8 引用回覆 回覆 發表時間:2004-08-12 09:00:25 IP:210.201.xxx.xxx 未訂閱
paf, 您好 Laplacian Operator 本身對雜訊的反應會有點敏感,但不致那麼強烈,之所以會如此應為LOG改良後的結果。 而我所用的是 Frei-Chen 的邊緣偵測。 以上提供你參考 我也正努力學習中 ^ ^
------
我也在努力學習中,若有錯謬請見諒。
系統時間:2024-11-23 10:46:12
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!