Edge Filter

윰이다·2022년 5월 18일
0

내가 언제 또_gpu

목록 보기
1/3

오늘은 edge 경계 부분을 찾는 필터에 대해서 알아볼것입니다!

먼저 우리가 상식적으로 생각해본다면 사물의 경계는 어떻게 찾을까요?
저라면,, 주변의 값보다 어떤 특별한 값을 갖는 부분을 사물의 경계라고 가정할 것입니다!

edge 필터는 각각의 픽셀의 변화값 (미분값!) 을 통해 변화의 방향과 크기를 예측합니다!
이것을 바로 'Sobel operator'이라고 칭합니다.
예를 들어 3*3 픽셀을 담게 해주는 곳에 픽셀의 미분값을 각각 넣어주면,
미분값을 통해 변화의 방향과 크기를 알 수 있습니다.
이때 우리는 x방향과 y방향 성분으로 나눠 두가지를 봐줘야합니다.
성분을 두개로 나누었기에 우리는 변화의 방향을 x, y 방향 각각을 알 수 있고,
변화의 크기는 x방향의 변화량과 y방향의 변화량을 제곱시켜 알아냅니다.

여기서 방향을 x, y 방향으로 나눠 생각해야 한다에 주목해주시길 바랍니다!

우리는 크게 두가지 과정, 세밀하게는 3가지 과정을 거쳐 이를 구현할 것입니다.

  1. blingPhong 필터 적용
  1. SobelOperator 적용
    -x 방향
    -y 방향
  1. 먼저 첫번째 pass -> blingPhong 필터 적용
    이는 먼저 화면에 이미지를 그려놓고 blingPhong 필터를 적용한다..
    두번째 Sobel operator를 적용할 이미지를 준비한다.. 라고 생각하면 될 것 같습니다.

먼저 벡터로 구현한 BlingPhong 필터입니다.

//	블링퐁 필터 (벡터 타입)
vec3 blinnPhong( vec3 position, vec3 n ) {  
  vec3 ambient = Light.La * Material.Ka;
  vec3 s = normalize( Light.Position.xyz - position );
  float sDotN = max( dot(s,n), 0.0 );
  vec3 diffuse = Material.Kd * sDotN;
  vec3 spec = vec3(0.0);
  if( sDotN > 0.0 ) {
    vec3 v = normalize(-position.xyz);
    vec3 h = normalize( v + s );
    spec = Material.Ks *
            pow( max( dot(h,n), 0.0 ), Material.Shininess );
  }
  return ambient + Light.L * (diffuse + spec);
}
// 첫번째 Pass
vec4 pass1() {
    return vec4(blinnPhong( Position, normalize(Normal) ),1.0);
}
  1. 이제, Sobel Operator를 적용할 것입니다!
// 두번째 Pass
vec4 pass2()
{
    ivec2 pix = ivec2(gl_FragCoord.xy);

// 3*3  각 픽셀의ㅣRGB 값 가져옴 (9개)
    float s00 = luminance(texelFetchOffset(RenderTex, pix, 0, ivec2(-1,1)).rgb);
    float s10 = luminance(texelFetchOffset(RenderTex, pix, 0, ivec2(-1,0)).rgb);
    float s20 = luminance(texelFetchOffset(RenderTex, pix, 0, ivec2(-1,-1)).rgb);
    float s01 = luminance(texelFetchOffset(RenderTex, pix, 0, ivec2(0,1)).rgb);
    float s21 = luminance(texelFetchOffset(RenderTex, pix, 0, ivec2(0,-1)).rgb);
    float s02 = luminance(texelFetchOffset(RenderTex, pix, 0, ivec2(1,1)).rgb);
    float s12 = luminance(texelFetchOffset(RenderTex, pix, 0, ivec2(1,0)).rgb);
    float s22 = luminance(texelFetchOffset(RenderTex, pix, 0, ivec2(1,-1)).rgb);
// 경향성 알아보기 X 축과 Y 축
    float sx = s00 + 2 * s10 + s20 - (s02 + 2 * s12 + s22);
    float sy = s00 + 2 * s01 + s02 - (s20 + 2 * s21 + s22);
// 변화량의 크기 g
    float g = sx * sx + sy * sy;
// 임의의 값보다 g가 크면 -> 경계임
    if( g > EdgeThreshold )
        return vec4(1.0);
    else
        return vec4(0.0,0.0,0.0,1.0);
}

글을 마치면서..
지금 LearnOpengl 코드가 뒤죽박죽으로 헤더 파일이 섞여있어서 제대로 실행을 못하고 있다..ㅠㅠ
내 부족한 역량 탓도 있지만 체계적으로 파일이 정리되어있지 못해서 다른 챕터들의 코드도 실행을 못하고 있어 지금 함수의 기능들만 알아보고 있는 중..
관련 책을 하나 빌려서 직접 코드로 구현해보는 편이 좋을 수도?

경계 값 필터의 아이디어는 픽셀의 변화량의 크기와 방향 에 있다. 이를 위해선 미분이 사용되고!
간단한 아이디어 임으로 쉽게 넘어가쟝

0개의 댓글