2012-11-13 131 views
2

我遇到了使用Sobel算子的邊緣檢測問題:它產生太多假邊緣,效果顯示在下面的圖片上。 我正在使用3x3 sobel算子 - 首先提取垂直和水平,最終輸出是每個濾波器輸​​出的幅度。 合成圖像上的邊緣被正確提取,但即使通過應用模糊或中值濾波器預處理圖像,自然圖像也會產生太多假邊緣或「噪點」。 這可能是什麼原因造成的?它是實現問題(那麼:爲什麼合成圖像很好?)或者我需要做更多的預處理?sobel算子 - 假邊緣自然圖像

原文:
orig

輸出:
out

代碼:

void imageOp::filter(image8* image, int maskSize, int16_t *mask) 
{ 
    if((image == NULL) || (maskSize/2 == 0) || maskSize < 1) 
    { 
     if(image == NULL) 
     { 
      printf("filter: image pointer == NULL \n"); 
     } 
     else if(maskSize < 1) 
     { 
      printf("filter: maskSize must be greater than 1\n"); 
     } 
     else 
     { 
      printf("filter: maskSize must be odd number\n"); 
     } 
     return; 
    } 

    image8* fImage = new image8(image->getHeight(), image->getWidth()); 
    uint16_t sum = 0; 
    int d = maskSize/2; 
    int ty, tx; 

    for(int x = 0; x < image->getHeight(); x++)   // 
    {             // loop over image 
     for(int y = 0; y < image->getWidth(); y++)  // 
     { 
      for(int xm = -d; xm <= d; xm++) 
      { 
       for(int ym = -d; ym <= d; ym++) 
       { 
        ty = y + ym; 
        if(ty < 0) // edge conditions 
        { 
         ty = (-1)*ym - 1; 
        } 
        else if(ty >= image->getWidth()) 
        { 
         ty = image->getWidth() - ym; 
        } 

        tx = x + xm; 
        if(tx < 0) // edge conditions 
        { 
         tx = (-1)*xm - 1; 
        } 
        else if(tx >= image->getHeight()) 
        { 
         tx = image->getHeight() - xm; 
        } 

        sum += image->img[tx][ty] * mask[((xm+d)*maskSize) + ym + d]; 
       } 
      } 

      if(sum > 255) 
      { 
       fImage->img[x][y] = 255; 
      } 
      else if(sum < 0) 
      { 
       fImage->img[x][y] = 0; 
      } 
      else 
      { 
       fImage->img[x][y] = (uint8_t)sum; 
      } 
      sum = 0; 
     } 
    } 


    for(int x = 0; x < image->getHeight(); x++) 
    { 
     for(int y = 0; y < image->getWidth(); y++) 
     { 
      image->img[x][y] = fImage->img[x][y]; 
     } 
    } 

    delete fImage; 
} 
+0

究竟是什麼問題? – Junuxx

+0

您使用的是標準的3x3 sobel操作符,據推測? – Rook

+0

這可能是什麼原因?它是實現問題(那麼:爲什麼合成圖像很好?)或者我需要做更多的預處理? – user1821186

回答

4

這似乎是由於某處代碼中的數學錯誤。按照我的意見,這是我所得到的,當我通過Sobel算子運行你的形象在這裏(邊緣強度是由輸出圖像的亮度指示):

Image after Sobel operator

我用了一個GLSL片段着色器產生此:

precision mediump float; 

varying vec2 textureCoordinate; 
varying vec2 leftTextureCoordinate; 
varying vec2 rightTextureCoordinate; 

varying vec2 topTextureCoordinate; 
varying vec2 topLeftTextureCoordinate; 
varying vec2 topRightTextureCoordinate; 

varying vec2 bottomTextureCoordinate; 
varying vec2 bottomLeftTextureCoordinate; 
varying vec2 bottomRightTextureCoordinate; 

uniform sampler2D inputImageTexture; 

void main() 
{ 
    float bottomLeftIntensity = texture2D(inputImageTexture, bottomLeftTextureCoordinate).r; 
    float topRightIntensity = texture2D(inputImageTexture, topRightTextureCoordinate).r; 
    float topLeftIntensity = texture2D(inputImageTexture, topLeftTextureCoordinate).r; 
    float bottomRightIntensity = texture2D(inputImageTexture, bottomRightTextureCoordinate).r; 
    float leftIntensity = texture2D(inputImageTexture, leftTextureCoordinate).r; 
    float rightIntensity = texture2D(inputImageTexture, rightTextureCoordinate).r; 
    float bottomIntensity = texture2D(inputImageTexture, bottomTextureCoordinate).r; 
    float topIntensity = texture2D(inputImageTexture, topTextureCoordinate).r; 
    float h = -topLeftIntensity - 2.0 * topIntensity - topRightIntensity + bottomLeftIntensity + 2.0 * bottomIntensity + bottomRightIntensity; 
    float v = -bottomLeftIntensity - 2.0 * leftIntensity - topLeftIntensity + bottomRightIntensity + 2.0 * rightIntensity + topRightIntensity; 

    float mag = length(vec2(h, v)); 

    gl_FragColor = vec4(vec3(mag), 1.0); 

您不顯示您的掩碼值,我假設它包含Sobel內核。在上面的代碼中,我對在3x3 Sobel內核中每個像素的紅色通道執行的計算進行了硬編碼。這純粹是爲了在我的平臺上的性能。

我沒有注意到你的代碼中的一件事(同樣,我可能會忽略它,就像我的總和被設置回0一樣)是確定Sobel算子兩部分的向量幅度。如果存在的話,我希望在某處看到平方根操作。

+0

找到我的問題的原因:在計算動態範圍內變化和超過我的變量的寬度用於存儲它,因爲噪聲和其他文物出現。完成一些返工:兩個垂直和水平濾波同時使用int而不是uint8或uint16來存儲像素值。 – user1821186

+0

http:// pastebin。com/VeNxRijd繼承人感興趣的代碼:) – user1821186