잊지 않겠습니다. 

그리고 바꾸겠습니다. 

다시는 이런 일이 일어나지 않도록 .. 

'Canon 100d' 카테고리의 다른 글

2015-04-04 모터쇼  (0) 2015.04.10
2015-04-08 벚꽃  (0) 2015.04.09
170814 - 140816 전주  (0) 2014.09.13
140531 홍대 - 여의도  (0) 2014.06.01
속초 140501 - 140503  (0) 2014.05.06


참고 : 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


출처 : http://scosco.com.ne.kr/Stereo3DHtml/vr_0004_unsharp.htm


UnSharp Mask Filter

가우시안 필터가 이미지를 부드럽게 만드는 것이라면 UnSharp Mask Filter는 이미지를 날카롭게 만드는 방법이다. 기본적으로 UnSharp는 원본이미지와 Bluring된 원본이미지가 필요하다. 그리고 아래와 같이 연산을 하면 된다. g(x, y) = f(x, y) - f_smooth(x, y) h(x, y) = f(x, y) + g(x, y) f(x, y)는 원본 이미지의 픽셀이고, f_smooth(x, y)는 앞에서 설명한 가우시안 필터를 이용하여 생성해 낸 픽셀이다. g(x, y)는 원본 이미지와 Bluring 이미지를 뺀 값인데 결과적으로 영상의 경계선 부분만 검출된다.


                                       원본                                                                           블러


 경계선결과


저 수식을 그림으로 표현하면 아래와 같다.








결과적으로 Highpass 부분만 남은 (c)를 (a)에 더함으로써 경계선 부분이 선명한 이미지가 출력되었다.
수식을 보면 알겠지만 g(x, y)에 k라는 factor를 두어 영상의 경계선을 더욱더 부각시킬수도 있고
경계선을 없애버릴 수도 있다. k는 일반적으로 0.0f 이상을 사용해야 하지만 음수여도 상관은 없다. 
수정된 공식은 아래와 같다.

h(x, y) = f(x, y) + k * g(x, y)



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

Edge Effect Shader  (0) 2014.06.11
LoG : Laplacian of Gaussian edge detection  (0) 2014.05.29
Emboss shader  (0) 2014.05.21
Mosaic Shader  (0) 2014.05.20
Hertzman Painterly Rendering  (0) 2014.05.16

+ Recent posts