2014-11-05 90 views
0

我已經在C++和C#中看到了許多Sobel邊緣檢測操作,但是我很難將代碼轉換爲在16位圖形上操作。我見過的大部分代碼都被編程爲在R.G.B風格的位圖上運行。我得到的圖形是一個ushort []數組,每列中都有亮度值,即col像素。16bit灰度圖像的Sobel邊緣檢測輸出

以下是我提出的代碼:(問題在於,它不是很有效......)有了一個巧妙的因素,它可能找到邊緣,但它也發現了很多的噪音。

但是,如果我將原始文件保存爲JPG格式,並將其運行到另一個接受Bitmap的替代Sobel-Edge-Detector C#代碼中,那麼它會好得多......幾乎沒有噪音!我的16bit灰度版本不應該更好嗎?!但它一定是我的代碼不符合規定。我不理解邏輯。

public void sobel() 
    { 

     ushort[] pixels = new ushort[9]; 
     ushort[,] imageData = image_array[0].GetArray(); 
     ushort[,] imageOut = (ushort[,])imageData.Clone(); 
     uint xDim = (ushort)(imageData.GetLength(1) - imageData.GetLength(1) % regions); 
     uint yDim = (ushort)(imageData.GetLength(0) - imageData.GetLength(0) % regions); 

     double intensityX = 0.0; 
     double intensityY = 0.0; 
     double intensityTotal = 0.0; 
     int limit = 1000000; //Just arbitrary junk number 

     int filterOffset = 1; 

     for (int offsetY = filterOffset; offsetY < 
      yDim - (filterOffset+1); offsetY++) 
     { 

      for (int offsetX = filterOffset; offsetX < 
       xDim - (filterOffset+1); offsetX++) 
      { 
       //intensityX = intensityY = 0; 
       //intensityTotal = 0; 

       pixels[0] = imageData[offsetY - 1, offsetX - 1]; 
       pixels[1] = imageData[offsetY - 1, offsetX]; 
       pixels[2] = imageData[offsetY - 1, offsetX + 1]; 
       pixels[3] = imageData[offsetY, offsetX - 1]; 
       pixels[4] = imageData[offsetY, offsetX]; 
       pixels[5] = imageData[offsetY, offsetX + 1]; 
       pixels[6] = imageData[offsetY + 1, offsetX - 1]; 
       pixels[7] = imageData[offsetY + 1, offsetX]; 
       pixels[8] = imageData[offsetY + 1, offsetX + 1]; 

       intensityX = pixels[8] + 2 * pixels[5] + pixels[2] - pixels[0] - 2 * pixels[3] - pixels[6]; 
       intensityY = pixels[8] + 2 * pixels[7] + pixels[6] - pixels[2] - 2 * pixels[1] - pixels[0]; 

       //intensityTotal = Math.Sqrt((intensityX * intensityX) + (intensityY * intensityY)); 
       //intensityTotal = Math.Abs(intensityX) + Math.Abs(intensityY); 
       intensityTotal = intensityX * intensityX + intensityY * intensityY; 
       //int sobel = (int)Math.Sqrt((xSobel * xSobel) + (ySobel * ySobel)); 

       //if (intensityTotal > MaximumValue) 
        // intensityTotal = MaximumValue; //Presumably Black 

       //if (intensityTotal < -1000) //1000 fudgefactor ...still not working correctly 
        // intensityTotal = MinimumValue; //Presumably White 
       //if (intensityTotal < (MinimumValue - 1000)) 
        // intensityTotal = MaximumValue; 

       if (intensityTotal > limit) 
        imageOut[offsetY, offsetX] = MinimumValue; 
       else 
        imageOut[offsetY, offsetX] = MaximumValue; 

       //imageOut[offsetY, offsetX] = (ushort)intensityTotal; 
      } 

     } 

     SetImageArrayItem(ImageDataIndex.RAWData, new DiskBackedArray(imageOut)); 

    } 

假設'image_array',xDim,yDim是條件。你會注意到一些其他的嘗試。

回答

0

Sobel(以及其他基於梯度的濾波器)受到噪音干擾。您可以用高斯平滑法預先篩選圖片並比較結果。請注意,對於平方差,limit = 1000000對應於大約1000的差值 - 對於16位(MAX = 65535)圖片,這個值相當小。
以JPG格式保存會使圖片更加模糊 - 尖銳的邊緣被弄髒,高頻噪音降低。所以請稍微平滑一點,限制一下。

+0

我一直在擺弄這一段時間。但後來,我發現了另一個我說過的軟件,讓它看起來很容易,它將圖像的大小改變爲我所看到的畫布大小 - 杜德。因此,不是處理5700 * 3700圖像,而是處理550 * 780,當然我是四捨五入的,但是您會看到圖片。所以是的,這是平穩的...我還沒有完成這個,但最終,我正在接受我的教育。 – 2014-11-08 12:58:43

+0

上面的代碼完全不是我正在使用的,但我正在做你的話:使用高斯平滑,比實際應用Kirsh邊緣檢測... Thankx – 2014-11-26 20:00:00