2012-11-13 2 views
2

Sobel 연산자를 사용하여 가장자리 감지에 문제가 있습니다. 잘못된 가장자리가 너무 많아서 효과가 아래 그림에 표시됩니다. 3x3 sobel 연산자를 사용하고 있습니다. 첫 번째로 수직으로 추출한 다음 수평으로 출력하고, 최종 출력은 각 필터 출력의 크기입니다. 합성 이미지의 가장자리는 올바르게 추출되지만 자연 이미지는 흐림 또는 중간 값 필터를 적용하여 이미지를 사전 처리하더라도 너무 많은 잘못된 가장자리 또는 "노이즈"가 발생합니다. 이 문제의 원인은 무엇일까요? 구현 문제 (다음 : 왜 합성 이미지가 좋습니까?) 또는 좀 더 사전 처리해야합니까? 원래sobel 연산자 - false edges 자연스러운 이미지

:
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

.

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); 

소벨 커널이 있다고 가정하는 마스크 값을 표시하지 않습니다. 위의 코드에서, 3x3 소벨 커널에서 각 픽셀의 적색 채널에 대해 수행 된 계산을 하드 코딩했습니다. 이는 내 플랫폼에서의 성능 향상을위한 것입니다.

코드에서 알지 못하는 한 가지는 (다시 말하면 내가 0으로 설정 한 합계를 누락 한 것처럼 누락되었을 수 있음) Sobel 연산자의 두 부분에 대한 벡터 크기의 결정입니다 . 그곳에 어쩌면 거기에 제곱근 연산을 기대할 수 있습니다.

+0

내 문제의 원인을 발견 : 계산 동적 범위가 다양하고 그것을 저장하는 데 사용되는 내 변수의 너비를 초과하고 그 소음 및 기타 유물이 등장했습니다. 약간의 재 작업을 수행했습니다. 픽셀 값을 저장하기 위해 uint8 또는 uint16 대신 int를 사용하여 수직 및 수평 필터링을 동시에 적용합니다. – user1821186

+0

http : // pastebin.com/VeNxRijd heres 코드에 관심이 있습니다 :) – user1821186

관련 문제