스케일 스페이스(scale space)란 무엇인가?

스케일(Scale)은 사람의 시각과 관련해서 가장 중요한 개념 중에 하나이다. 우리가 눈으로 어떤 장면을 볼 때 얼마나 멀리 떨어진 거리에서 보느냐에 따라 우리가 볼 수 있는 내용은 사뭇 다르다. 가까이서 볼수록 물체들의 좀 더 디테일한 부분들까지 볼 수 있고, 멀리서 볼수록 대략적인 구조와 틀을 볼 수 있다. 흔히 무언가를 '작은 스케일로 본다', '큰 스케일로 본다'고 표현하는데, 가까이서 세세하게 보는 것이 작은 스케일로 보는 것이고, 좀 더 떨어져서 전체적으로 보는 것이 큰 스케일로 보는 것이다. 그림1(a)는 한 장면을 큰 스케일로 본 것이다. 빨간 지붕의 집들이 여러 채 옹기종기 모여있고 멀리는 섬과 바다가 보인다. 반면, 그림1(b)는 작은 스케일로 본 것이다. 큰 스케일로 봤을 때는 안 보였던 지붕의 기와들이 어떻게 생겼고, 어떤 방식으로 배치되어 있고, 또 벽에 벽돌이 어떻게 쌓여있는지 등이 세부적으로 보인다.  


그림1. 큰 스케일로 보는 것과 작은 스케일로 보는 것. 참고로 이 사진은 크로아티아 두브로브니크 성벽 투어 중 찍은 것이다.


우리가 어떤 장면을 볼 때 전체적인 틀을 파악하는 것과 세부적인 내용을 아는 것 둘 다 상황에 따라 필요한 것이기 때문에, 성공적인 컴퓨터 비전 및 이미지 프로세싱을 위해서는 이 스케일이라는 개념을 도입해야 한다. 왜냐하면 우리는 동시에 여러 스케일로 장면을 보기 때문이다. 그렇다면 어떻게 이 개념을 반영할 수 있을까? 그래서 나온 것이 scale space이다. 


영상처리를 할 때 단 하나의 스케일의 이미지가 아니라 여러 스케일로 본 이미지들을 가지고 필요한 작업을 하는 것이다. 이 여러 스케일의 이미지들을 모아놓은 것scale space라고 말할 수 있다. 이미지 스케일을 변화시키는 가장 간단한 방법은 이미지를 확대하거나 축소시키는 것이다(그림2). 이를 이미지 피라미드라고 한다. 


그림2. 이미지 피라미드


그림2를 보면 큰 스케일로 보는 장면(오른쪽에 있는 작은 이미지)은 작은 스케일로 본 장면(왼쪽에 있는 큰 이미지)에 비해서 디테일한 면에서는 살짝 떨어진다. 전반적으로 모호하게 보인다. 이 특성을 이용해서 이미지의 사이즈는 그대로 유지하면서 이미지를 블러링(blurring)시킴으로 스케일이 커지게 할 수 있다. 블러링에 가장 적합한 필터는 가우시안 필터이다. 


...(공식1: 가우시안 필터)


여기서 는 블러링의 정도를 결정하는 파라미터로, 클 수록 이미지를 더 블러시킨다. 이미지가 더 많이 블러될 수록 스케일이 커지는 것이기 때문에 스케일 파라미터라고도 부른다. 그러면 이번에는 가우시안 필터를 이용해서 scale space를 만들어보자. 


...(공식2: 이미지를 가우시안 필터로 컨볼루션하기)


가우시안 필터로 이미지를 블러링한다. 점차적으로 큰 스케일 파라미터로 블러링을 한다. 결과적으로 그림3과 같이 점점 더 블러된 이미지들을 얻게 된다. 흐릿할 수록 스케일이 큰 것이다. 


그림3. 가우시안 scale space


더 나아가서 이미지를 먼저 블러링한 다음에 사이즈를 축소(다운샘플링)시키고, 또 다시 블러링하고 다운 샘플링...하는 방법도 많이 활용된다. 




▶ 글을 마무리 하면서..


아직 글의 내용이 많이 불충분하지만 scale space에 대해 대략적인 감각만이라도 전달되었기를 바라며 일단 글을 마친다. (좀 더 공부한 후에 추가 수정될 것입니다.) 



<참고 자료>

[1] http://www.cs.uu.nl/docs/vakken/ibv/reader/readerINFOIBV.pdf => 9장 내용


댓글()

[Grammar in use intermediate] wish와 hope 용법 비교

신호와 소음 - 삶/영어|2017. 9. 29. 15:54

wish는 '원하다, 바라다, 기원하다', hope는 '바라다, 희망하다' 뜻을 담고 있다. 비슷한 의미를 담고 있지만 사용법은 다르다. 많이 실수할 수 있는 부분이니 정리하고 넘어가자. 


먼저 wish'wish + somebody + something'과 같이 사용하고, hope'hope that something happens'와 같이 사용할 수 있다. wish는 누군가에게 무엇을 기원해주는 것이라면, hope는 어떤 상황이 발생하기는 바라는 의미를 담고 있다. 즉, wish 다음에는 명사들이 나온다면, hope 다음에는 절이 온다. 


예문을 통해 좀 더 분명히 이해해보자.


예문1>> 

I wish you a pleasant stay here. 나는 너가 여기에서 즐겁게 머무르길 바래.


예문2>>

I hope you have a pleasant stay here. 나는 너가 여기에서 즐겁게 머무르길 바래.


예문1, 예문2 모두 갖은 의미를 가지고 있지만, 조금 다른 문장 구조를 갖고 있다. 예문1의 경우, wish를 사용해서 'you'에게 'a pleasant stay here'를 기원해주고 있다. 예문2에서는 hope를 사용해서 'you have a pleasant stay here'를 기원해주고 있다. 


예문3>>

I wish you luck in your new job. 나는 너의 새로운 직장에서 너에게 행운이 있길 기원해.


예문4>>

Enjoy your vacation. I hope you have a great time. 휴가 잘 보내. 나는 너가 좋은 시간을 보내길 바래. 


wish는 가정법의 의미로 사용되기도 하는데 그에 대한 내용은 링크 건 포스팅들을 참고하자.(http://bskyvision.com/122 => wish 가정법 과거, http://bskyvision.com/135 => wish 가정법 과거완료)  


댓글()

폴더 속의 이미지 파일들의 이름을 읽어내고 싶을 때는?, dir 함수

영상처리를 하다보면 폴더 내에 있는 이미지 파일 이름들을 쭉 읽어내야 하는 경우가 있다. 그런 경우에 dir 함수를 이용하면 쉽게 읽어낼 수 있다. 그림 1과 같이 여러 장의 이미지가 포함되어 있는 폴더가 있다. 


그림 1. 여러 장의 이미지가 담겨 있는 폴더.

여기서 이미지 파일의 이름과 확장자를 한번에 읽어보는 코드를 구현해보자. 핵심은 dir 함수를 사용해야한다는 것이다. 이름을 보아하니 directory에서 기인한 것 같다. 즉 파일의 목록을 보여주는 함수이다. dir(폴더명), 이렇게 사용해주면 된다. 

 

dir_ex.m

clc, clear, close all


folder_name = 'D:\노래, 사진, 영화\사진Photo\2017-04-04_고문화거리'; 

list = dir(folder_name);


위와 같은 두 줄의 코드를 작성하고 실행한 후 list라는 변수에 들어있는 내용을 확인해보자(그림 2). 


그림 2. list 변수의 내용물


보아하니 dir로 얻은 list변수 안에는 파일의 이름, 폴더명, 날짜, 용량 등이 포함되어 있다. 우리가 필요한 것은 이미지 파일의 이름이니, 이것만 읽어내보자. 3부터 18까지가 이미지 파일을 지칭하고 있다. list변수는 구조체 형식이기 때문에, .을 활용해야 한다. list.name으로 파일명을 읽어낼 수 있다. 필자는 파일명을 열벡터에 담기도록 만들었다. 위에서 작성한 코드에 이 부분을 추가했다. 

 

dir_ex.m

clc, clear, close all


folder_name = 'D:\노래, 사진, 영화\사진Photo\2017-04-04_고문화거리'; 


list = dir(folder_name);


img_name = [];


for i = 3:18

    img_name = [img_name; list(i).name]; 

end


추가된 코드를 간단히 설명하자면, img_name이라는 빈 공간을 만들어낸 다음, 파일명이 하나씩 차곡차곡 밑으로 추가되게 만들었다. 결과적으로 생긴 img_name 변수 안을 들여다보자(그림 3).


그림 3. 이미지 파일명을 담은 변수.


이미지 파일명이 차곡차곡 하나씩 담겨있는 것을 볼 수 있다. 그럼 이제 간단히 이미지파일을 읽은 후 subplot을 이용해서 한번에 보여주는 코드를 작성해보자.


dir_ex.m

clc, clear, close all


folder_name = 'D:\노래, 사진, 영화\사진Photo\2017-04-04_고문화거리'; 


list = dir(folder_name);

img_name = [];


for i = 3:18

    img_name = [img_name; list(i).name];

end


figure,

for i = 1:16

    img = imread([folder_name, '\', img_name(i, :)]);

    subplot(4, 4, i)

    imshow(img);

end


16개의 이미지를 한번에 보여주기 위해서 이미지를 4열, 4행으로 전시되게 했다. 결과적으로 그림 4가 화면에 떴다. 


그림 4. 폴더 내의 이미지들을 읽어서 모니터에 출력한 결과


만약에 이미지가 폴더 내에 1000개, 10000개 이렇게 많이 들어있는 경우에는 이미지를 하나씩 읽어서 사용하는 것은 사실상 불가능하기에 여기서 소개하는 방법을 활용하는 것을 추천한다. 


코드에 이해가 안되는 부분 있다면, 댓글을 남겨주시면 좀 더 상세히 설명하겠습니다! 


댓글()

Laplacian of Gaussian (LoG), 엣지 검출의 한 방법 (matlab 소스코드 포함)

지난 번에 엣지 검출이 왜 영상처리분야에서 중요한지에 대해서 생물학적인 근거를 가지고 이야기했었다. (http://bskyvision.com/132) 오늘은 엣지 검출의 한 방법인 Laplacian of Gaussian(LoG)에 대해 다루려고 한다. 



▶ LoG는 무엇인가?


LoG는 Marr과 Hildreth에 의해 1980년에 제안된 방법이다. 먼저 2D 가우시안 함수(공식 1)를 사용하여 이미지를 블러시킨다. 노이즈를 제거 및 완화시키기 위함이다. 노이즈를 엣지로 착각할 수 있기 때문이다.


...(공식 1: 2D 가우시안 함수)


여기서, x, y는 이미지의 픽셀 위치를 의미하고, 는 표준편차를 의미한다(때때로 space constant라고도 불린다). 값이 커질수록 이미지는 더욱 더 흐릿해진다.


그 다음에 라플라시안 연산자(공식 2)를 사용하여 수평 방향, 수직 방향으로의 2차 미분을 구한다. 엣지를 찾기 위함이다.  

 

...(공식 2: 라플라시안 연산자)


이것을 하나로 통합시키면 아래와 같다. 


...(공식 3: LoG 연산자)


LoG 함수의 모양은 그림 1과 같다. 멕시코 전통 모자의 형태와 비슷하므로 LoG 연산자는 Mexican hat 연산자라고도 불린다. 그림 1의 왼쪽 그래프는 공식 3을 그대로 나타낸 결과이고, 오른쪽은 공식에 마이너스(-)를 곱한 결과이다. 왼쪽 그래프의 경우 중앙부는 움푹 깊이 들어가있고, 주변부는 살짝 올라와있다. 오른쪽 그래프의 경우 중앙부는 솟아나와 있고, 주변부는 살짝 들어가 있음을 볼 수 있다.  


그림 1. LoG 함수의 그래프. 이 그래프들은 matlab에서 fsurf 함수를 활용해서 구현했다.

 


이 그래프들을 통해, LoG 연산자는 http://bskyvision.com/132에서 설명한 우리 눈 안의 망막 신경절 세포를 모델링한 것으로 볼 수 있다. 참고로 망막 신경절 세포는 망막에 맺힌 이미지에서부터 엣지를 검출하는 역할을 한다. 두 가지 유형의 망막 신경절 세포가 있는데, OFF-center 신경절 세포는 왼쪽 그래프와 같은 반응을 보인다. 세포의 중앙부에 빛이 비치면 반응이 많이 억제되고, 주변부에 빛이 비치면 평소보다 반응을 활성화된다. 반면 ON-center 신경절 세포는 오른쪽 그래프와 같이 동작한다. 중앙부에 빛이 비치면 크게 활성화되고, 주변부에 빛이 비치면 억제된다. 두 유형의 세포 모두 중앙부, 주변부에 동시에 빛이 비치면 빛이 비치지 않을때와 마찬가지의 활성도를 갖는다. 즉 활성도에 변화가 없다. 이러한 특성을 통해서 어떻게 엣지를 검출해내는지는 http://bskyvision.com/132를 참고하길 바란다. 


라플라시안 연산자(공식 2)의 역할을 n x n 사이즈의 마스크로 근사하게(거의 비슷하게) 수행할 수 있다. 라플라시안 마스크는 딱 하나로 정해져있는 것은 아니다. n이 홀수이어야 하고, 모든 요소의 값을 더했을 때 0이 되고, 그림 1의 멕시칸 모자의 형태만 모방하는 꼴이면 된다. 모든 요소의 값의 합이 0이 되어야 하는 이유는 픽셀값의 변화가 없는 부분(즉 엣지가 아닌 부분)에서는 반응하지 않아야 하기 때문이다. 그림 2에 있는 것들이 라플라시안 마스크로 사용될 수 있다. 


그림 2. 라플라시안 마스크.



LoG 연산의 알고리즘을 정리해보자. 

1. gaussian 필터 처리해서 블러된 이미지를 얻는다. 

2. 블러된 이미지를 라플라시안 마스크로 컨볼루션해주면 엣지 영상을 얻을 수 있다. 


n x n LoG 필터의 사이즈(gaussian filter와 라플라시안 마스크의 사이즈)를 결정할 때  n은 와 같거나 큰 수 중에 가장 작은 홀수여야 한다. 즉, 가 0.5라면 3 x 3 사이즈의 마스크를 사용해야 하고, 가 1.4라면 9 x 9의 마스크를 사용해야 한다. (왜 이렇게 사용해야하는지 이유는 아직 정확히 모르겠다.. )



▶ LoG 매트랩 코드


그러면 매트랩으로 LoG 연산을 구현해보자. 먼저 gaussian 필터를 적용해서 블러된 이미지를 얻은 다음, 라플라시안 마스크로 컨볼루션해주면 끝! 아래 매트랩 코드를 참고하자.


clc, clear, close all


img = imread('GOPR0688.jpg');


img = rgb2gray(img);

imshow(img);

img = double(img);


% 가우시안 마스크

h1 = fspecial('gaussian', 3, 0.5); 

h2 = fspecial('gaussian', 5, 0.8); 

h3 = fspecial('gaussian', 9, 1.4); 


% 가우시안 마스크로 블러된 영상 얻기

blurred_img1 = conv2(img, h1); 

blurred_img2 = conv2(img, h2); 

blurred_img3 = conv2(img, h3); 

 

% 라플라시안 마스크

lap1 = [1 1 1; 

          1 -8 1; 

          1 1 1]; 

lap2 = [0 0 1 0 0; 

          0 1 2 1 0; 

          1 2 -16 2 1; 

          0 1 2 1 0; 

          0 0 1 0 0]; 

lap3 = [0 1 1 2 2 2 1 1 0; 

          1 2 4 5 5 5 4 2 1; 

          1 4 5 3 0 3 5 4 1; 

          2 5 3 -12 -24 -12 3 5 2; 

          2 5 0 -24 -40 -24 0 5 2;

          2 5 3 -12 -24 -12 3 5 2;

          1 4 5 3 0 3 5 4 1;

          1 2 4 5 5 5 4 2 1;

          0 1 1 2 2 2 1 1 0]; 


% 블러된 영상을 라플라시안해서 엣지 영상 얻기

LoG_img1 = conv2(blurred_img1, lap1);

LoG_img2 = conv2(blurred_img2, lap2);

LoG_img3 = conv2(blurred_img3, lap3);


figure, imshow(mat2gray(LoG_img1));

figure, imshow(mat2gray(LoG_img2));

figure, imshow(mat2gray(LoG_img3));


이 코드로 구현된 엣지 영상들이다(그림 3). 작은 사이즈의 LoG 필터를 사용할 수록 좀 더 날카롭고 세밀한 엣지를 검출했고, 사이즈가 커질 수록 좀 더 큼직한 엣지들을 검출한 것을 볼 수 있다.


그림 3. LoG 필터로 얻은 엣지 이미지들.


오늘 정리한 LoG는 Difference of Gaussian (DoG)에 의해서 근사될 수 있다. 


...(공식 4: DoG 연산자)


DoG에 대해서 간단히 말하자면, 원본 이미지를 다른 값들로 가우시안 필터링한 두 개의 블러된 이미지를 빼면 LoG로 얻은 엣지 영상과 굉장히 비슷한 영상을 얻을 수 있다는 것이 핵심이다. 이 때 두 개의 값들은 1.6:1의 비율을 가져야 한다. DoG가 연산상의 편리함으로 인해 LoG보다 좀 더 많이 사용되는 것 같다. 



<참고 자료>

[1] Gonzalez 2010, "Digital Image Processing, Third Edition", p.736-741

[2] http://homepages.inf.ed.ac.uk/rbf/HIPR2/log.htm => 9 x 9 사이즈의 LoG 필터 마스크 참고. 



댓글()

[Grammar in use intermediate] If I had done의 용법(가정법)

신호와 소음 - 삶/영어|2017. 9. 25. 15:37

지난 번에 http://bskyvision.com/122에서 If I do, If I did의 용법에 대해서 살펴보았다. 오늘은 If I had done의 용법에 대해서 정리하려고 한다. 


If I had done 역시 가정법인데, 과거의 상황을 가정할 때 사용된다. 과거에 실제로 일어난 상황에 반대되는 상황을 상상하면서 말할 때 사용된다. 이 문법은 가정법 과거 완료라고 불린다. 뜻이 과거 완료라서가 아니라 if 절에 사용된 동사의 시제가 과거 완료이기 때문이다. 예문을 살펴보자.


예문 1>>

The view was wonderful. If I had had a camera, I would have taken some pictures. 경관이 훌륭했어. 만약 내가 카메라를 가지고 있었다면, 나는 사진을 몇장 찍었을거야.


그때 이 사람은 사진기를 갖고 있지 않았기 때문에 찍을 수 없었다. 카메라를 가지고 있는 상황을 가정하면서 과거를 회상하는 것이기에 If I had done이 사용되었다. 또 여기서 살펴볼 수 있는 것은 주절에 would have done이 사용된 점이다. 참고로, 가정법 과거(If I did)에서는 주절에 would do가 사용된다. 예문 하나를 더 살펴보자. 


예문 2>> 

I didn't see you when you passed me in the street. If I had seen you, I would have said hello. 난 너가 거리에서 나를 지나칠 때 보지 못했어. 만약 내가 너를 봤다면, 나는 안녕이라고 말했었을 거야.


과거의 사실에 반대되는 것을 가정하는 것이므로 역시 마찬가지로 If I had did, I would have done의 문법이 사용되었다. 


또한 가정법 과거의 경우와 마찬가지로 wish를 사용하는 가정법 과거완료의 용법도 존재한다. 이때 wish 다음에 나오는 동사는 had done의 형태를 갖는다. 과거의 행동에 대한 후회, 안타까움, 아쉬움의 어감을 지닌다. 


예문 3>>

I feel sick. I wish I hadn't eaten so much cake. 나 아파. 케익을 그렇지 많이 먹지 말아야했어. 


케익을 너무 많이 먹었던 것을 후회하며 말하고 있다. 즉, 과거로 돌아간다면 많이 안 먹었을 거야라는 의미를 내포하고 있다. 


가정법 과거(If I did, I would do)와 가정법 과거 완료(If I had done, I would have done)는 정말 중요하니 꼭 제대로 익히고 넘어가자. 형태 때문에 가정법 과거, 가정법 과거 완료라고 불리는 것이지, 의미적으로는 가정법 과거는 현재이고 가정법 과거완료는 과거라는 사실! 



<참고 자료>

[1] Raymond Murphy, Cambridge, Grammar in use intermediate, p. 76-77.

댓글()