참고 : http://homepages.inf.ed.ac.uk/rbf/HIPR2/log.htm

         http://fourier.eng.hmc.edu/e161/lectures/gradient/node9.html


LoG는 이미지의 외곽선을 추출하기 위해 

이미지에 가우시안 블러를 적용하고 블러가 적용된 이미지에 라플라시안 필터를 적용하여

라플라시안보다 노이즈가 적은 외곽선을 추출하는 기법.


가우시안 블러 수식 

라플라시안 필터 수식

LoG 수식


수식에 필요한 값은 가운데 좌표가 0인 x, y 값과 가우시안 표준편차인 σ 값이 필요하다.

이 LoG 수식을 그래프로 표현한 것이 아래 그림이다. 



LoG값으로 커널을 생성할 수 있는데 커널을 생성하기 위해선 비례식이 필요하다. 

커널의 사이즈에 따라 비례식이 변하게 되는데 기준은 LoG(0,0)이다. 

LoG(0,0)의 경우 x와 y 값이 모두 0이기 때문에 결국 모두 같은 값으로 계산된다.

LoG(0,0) = -1/(πσ^4)

커널의 가운데 값이 가장 작은 값으로 존재해야 하므로 커널의 비례식은 아래와 같이 표현 할 수 있다.

α : -10*Radius = LoG(x,y) : LoG(0,0)

커널 반지름 : Radius

LoG(0,0)과 매치되는 -10*Radius의 경우는 .. 솔직히 아래 커널 값을 보고 이정도면 맞겠구나 하고 

때려 맞춰 넣은 값이다. 저 LoG 식에서 커널 값을 도출해 내는 정확한 방법을 찾고 있지만... 검색 능력이 딸리는 것인지 찾기 못했다 ㅠㅠ.. 

여튼 저 비례식을 이용하면 아래와 비슷한 커널값을 도출해 낼 수 있다.

이 커널 값은 커널 반지름(반경)은 4이고 가우시안 표준편차(σ)는 1.4를 적용하였을 때 커널 값이다. 


LoG vertex Shader

precision highp  float;

attribute vec3 aVertex;

attribute vec2 aTexCoord;

varying vec2 vTexCoord;

void main(void)

{

vTexCoord = vec2(aTexCoord);

gl_Position = vec4(aVertex, 1);

}


LoG frag Shader

uniform sampler2D uTexID0; // 흑백처리된 이미지

varying vec2 vTexCoord; 

uniform float uScale; //가우시안 표준편차(σ)

uniform vec2 uTexel; //Texel size

uniform float               uOffset; //커널 반지름(Radius)

uniform float uStrength; //임계치(Threshold)

 

void main() 

{

    float twoScale2Recip = 1.0 / (2.0 * uScale * uScale);

    float PiScale4Recip = 1. / (3.141592*pow(uScale,4.));

    vec2 pos;

    vec4 texValue;

    vec4 totalTex = vec4(0.,0.,0.,0.);

    float LoGValue;

    float totalLoG = 0.;

    for(pos.x = -uOffset; pos.x<=uOffset; pos.x += 1.){

      for(pos.y = -uOffset; pos.y<=uOffset; pos.y += 1.){

       // LoG 수식 적용

       LoGValue = -PiScale4Recip*(1.-((pow(pos.x,2.)+pow(pos.y,2.))*twoScale2Recip))

                   * exp(-((pow(pos.x,2.)+pow(pos.y,2.))*twoScale2Recip));

       // LoG의 비례식 적용

       LoGValue = (LoGValue*(uOffset*-10))/-PiScale4Recip;

       texValue= texture2D(uTexID0, vTexCoord + vec2(pos.x * uTexel.x, pos.y * uTexel.y))

                 * LoGValue;

       totalTex += texValue;

       totalLoG += LoGValue; // LoG의 모든 값의 합은 0이 되어야 함

                                       // 비례식이 정확하지 않아 모든 합이 0이 되지는 않음 ㅠㅠ

      }

    }

    if(uStrength == 0) //임계값이 없으면 그냥 출력

      gl_FragColor = 1-totalTex; //엣지를 검정으로 표현하기 위한 반전

    else{

      if(totalTex.r >= uStrength)

        gl_FragColor = vec4(0,0,0,1);

      else

        gl_FragColor = vec4(1,1,1,1);

    }

}


'Programmer의 텅빈 공간 > OpenGL/GLSL' 카테고리의 다른 글

Kuwahara Effect  (0) 2014.06.11
Edge Effect Shader  (0) 2014.06.11
unsharp mask 를 이용한 sharpen filter  (0) 2014.05.27
Emboss shader  (0) 2014.05.21
Mosaic Shader  (0) 2014.05.20

+ Recent posts