티스토리 뷰

 

 

 

영상처리에서 기초가 되며 상당히 많이 쓰이는 이론.

정리해본다.

추천하는 블로그 2곳.

★ [1]기본적인 이론을 쉽게 이해하기 좋은곳. -> http://realheart.egloos.com/2193436

★ [2]컨볼루션에 대한 다양한 내용들을 망라하여 정리됐다. -> http://golee07.tistory.com/312

위 블로그들을 보면서 이해했고, 내 것으로 만드는과정으로 본 글을 썼음.

 

 

 


 

컨볼루션(Convolution)연산이란 무엇인가???

공간필터링(Spatial Filtering) 이라고도 하는데,

간단하게 한문장으로 말하자면. 일정한 행렬을 이미지에 문지르다. 또는 훑는다 라고 할 수 있겠다.

참고블로그[1]에서 컨볼루션을 '주어진 목적에 따라 상응하는 마스크를 선택하여 처리함'이라고도 되어있다.

 

이 문지르는 행렬 또한. 마스크(Mask), 윈도우(Window), 커널(Kernel) 등 다양하게 부르고있지만 결국 같은것을 뜻한다고 볼 수 있다.

대체적으로 마스크라고 많이 쓴다.

 

기본적인 아이디어는 다음 그림을 보면 쉽다.

( 참고블로그[1]에서 너무 좋은 그림을 보여줬으니 참고... 본인은 차별화하려고 노력함)

 

첫번째(앞)의 창(Window)경우 마스크이다. 3*3 크기의 마스크이며, 마스크 크기는 3*3 가 아니더라도 5*5 와 같은 크기의 마스크도 존재한다.

두번째 창이 이미지의 일부 크기(마스크와 같은 크기) 부분이라고 할 수 있겠다. 마지막 윈도우는 최종 결과윈도우라고 볼 수 있다.

(노란부분은 최종 갱신되는 중심픽셀, 이외에는 변하지않는다. 그대로 둔다.)

마스크는 여러가지가 있는데, 결합하여 각각의 단점을 보완한 혼합형 마스크도 만들어져있다.(앞서 정의한것처럼 목적에 따라 다양한 마스크가 존재한다.)

 

보는 그림과 같이. W1은 X1과 곱해지며, 이런식으로 서로 매칭되어 곱해져 곱해진 9개의 값이 더해진 최종 결과 이미지는 한 픽셀에 내놓게 된다.

 W1*X1 + W2*X2 + W3*X3 + ..... + W9*X9

(모든것의 가중치 즉 마스크값들의 합이 1이 아닌 경우도 있어 영상이 전체적으로 밝아지거나 어두워질 수 있다. 이를 위해 정규화 라는걸 수행한다.)

즉. 이러한 마스크의 중심픽셀은 주변픽셀의 각각 가중치를 곱하여 갱신하는데, 이 마스크가 전체 이미지를 대상으로 돌게 된다.

이렇게 이미지를 싹~ 돌아가면서 문질러주는데 이를 회선처리 즉 컨볼루션이라 하는것이다.

 

마스크는 반드시 홀수*홀수가 되어야한다. 중앙에 값을 바꾸는데 이를 대칭으로 위,아래 또는 좌,우로 대칭 또는 사방으로 퍼지는형태의 대칭이므로, 가운데를 제외하곤 짝수여야하기때문에, 결론적으로 마스크는 홀수*홀수가 되어야한다.

 

용도.

다양하게 쓰인다.

 흐릿하게 만들어주는 블러.(이미지 보정할때 자주 쓰이는 툴중 하나) 에도 쓰이고.

이 블러 또한 마스크의 종류가 다양해서 여러가지의 블러효과를 볼 수 있다.

 샤프닝. 영상의 세밀하고 미세한 부분을 강조하거나 영상이 흐릿한경우 좀더 선명하게 처리할 수 있다.

 잡음제거 등.

 

잡담 : 본인은 영상처리를 픽셀단위로 처리하는것에 더 익숙한 편이다. (현재)

영상처리는 아무래도 픽셀보다는... 신호처리에 더 가까운것 같다.. 퓨리에 변환등...

 

 

 다음은 3*3 Vertical Spatial Mask이다.

수직공간에 대한 마스크이다.

 -1

 0

 1
 -1

 0

 1
 -1

 0

 1

Gray영상에 대하여 본 마스크를 돌려본 결과이미지는 다음과 같다.

 

 

 수직성분을 검출하는 마스크인데 좌,우로 대칭적인 요소에 대해 가중치를 줬다. 왼쪽엔 -1 오른쪽엔 1을 주었다. 왼쪽 요소와 오른쪽요소간의 데이터 차이가 크면 최종

sum(더한 값) 은 커지겠다. 위 그림과 같이 수직성분이 강한 에지영상을 얻을 수 있다.

 


 이렇게 컨볼루션의 이론을 접하고 나면 본인을 포함한 여러사람이 의문이 생길것이다.

왜 이런 마스크를 돌리는데 블러나 샤프닝 등의 효과를 얻을 수 있을까?

Mask = {-1,0,1,-1,0,1,-1,0,1} 과 같은 마스크는 어떻게 수직성분을 얻게 해줄까?

자문이 좀...이상하다.....음..쉽게말해서.

" 응 그렇게 되나보다 " 하기보다 시물레이션이나 예시를 들어봐야 이해가 쉬울 것 같다.

(머리가 좋지 않다.)

보면 알겠지만 이 마스크가 움직이면서 값이 누적되게 된다. 변해진값, 갱신된 이전값이 다음마스크가 문질러지는데 영향이 간다는 뜻이다.

 중심픽셀값을 다른 영상에 맵핑하는 것 같진 않다.

 

 어떠한 영상의 GrayScale 로 변환 후 보기좋게 확대해 본 모양이다.

3*3 마스크박스를 표시했고, 각각 색깔 다르게 표시해보았다.

먼저 빨간색 윈도우(여기선 느낌상 마스크보단 윈도우가 좋겠다 ㅋ) 경우 왼쪽줄에 -1들을 곱하고 오른쪽줄에 1을 곱해서 나온 값을 더할 경우

합은 0에 가까울 것 같다. 즉 왼쪽 명암값을 위에서 아래로 200, 230, 200 으로 가정하고. 오른쪽줄은 위에서 아래로 150,120,150 이라 하여

각각 가중치를 곱하면, -200-230-200+150+120+150 = -210 이 나온다. 

ㅡ.ㅡ 0~255 값이 나와야할터인데..-210이 나왔다. 난감하다...  솔직히 어떻게 처리해야할지 모르겠으나 일단. 음수값이니 0으로 처리하겠다.

물론. 이 윈도우가 오기전 왼쪽으로부터 넘어왔으니 현재 주변픽셀데이터는(왼쪽) 이전 윈도우처리로부터 새로 저장된 상태일 지도 모르겠다.

 

위 이미지에서 가르키는 숫자는 마스크가 아닌 픽셀 줄을 가르키고 있다.(column)

 

현재 마스크의 위치는 숫자2가 가르키는 픽셀의 줄을 마스크 중심이라고 가정 하자.

앞서 사용한 Vertical Spacial Mask를 돌려보자. 계산은 생략하고 어두운 부분이 값(value)가 작으므로(0에 가까우므로) 가중치 1을 곱한다해도 얼마 안나올 것 같다. 반면, 왼쪽줄(숫자1) 경우 밝은 편같다. 대략 200정도 되려나? 가중치 -1을 곱하면 대략 많이 큰 값이 나오겠다.

합을 구한다면 큰 음수값이 나올 듯 하다. 이것도 0으로 만들자. (맞나 모르겠다. 내맘대로 에잇)

이제 숫자3의 중심픽셀을 중심으로 하는 마스크를 보자.

 마스크는 왼쪽 위에서 내려온다고 가정한다면, 이미 마스크 1~9 중에 1의 경우 0으로 처리가 됐을 수 있다.

왼쪽은 상대적으로 어둡고 오른쪽은 심하게 밝다. 255에 가까울 것같다. 가중치를 곱해지면 아무래도 큰 양수가 나올 것 같다.

정규화를 하더라도 분명 0~255중 밝은 색이 나올 것 같다. 중심픽셀은. 밝은 색으로 채워질 것이다.

 

이제 마스크의 중심을 4번의 Column을 기준으로 하자.

왼쪽은 어두우니(3번줄) 가중치 -1 을 곱하더라도 0에 가까운수들을 곱하면 작은 음수값이 될 것이다.

다만. 위에서 마스크가 내려오므로, 위픽셀은 이미 처리가 된 상태일것이다. 밝은색으로 채워졌을 것이다.

즉, 왼쪽이 어둡다고 하지만 이미 회선처리로부터 밝은색으로 재구성되었을 것이다. 이 값을 곱하고 오른쪽줄(5번)들과 더해봐야 알겠지만

많이 밝아질 것 같진 않다.  즉 4번줄에 어느정도 밝은 성분을 보여줄 수 있지만 3번에서 가장 강한 성분을 볼 수 있을 것 같다.

 

 위에 이미지는 컬러이미지,

 두번째는 그레이스케일 이미지 마지막으로 수직성분검출 영상이다.(이진화 영상은 아니다.) 

 

왼쪽(어두움)에서 오른쪽(밝은)으로 가는 구간(경계선)경우  다음과같이 이미지 왼쪽처럼 강하게 성분이 표시되는것을 볼 수 있다.

(참고 : 편집과정에서 좌우 또는 상하로 움직였을 수 있다. 위 자료로는 픽셀 대 픽셀로 매칭해서 비교는 힘들듯하다.)

 

 

 

 이번엔 마스크를 변경해보았다.

왼쪽에 -1 가중치를 주던것을 오른쪽에 주고 왼쪽은 1을 주었다.

예상대로, 그레이스케일에서 밝은곳이 왼쪽으로부터 오른쪽 어두운곳으로 넘어갈때 왼쪽에 -1 주는것으로 바꾸었기때문에

아래과같은 결과를 얻을 수 있었다.

 

그림 A. [-1,0,1,-1,0,1,-1,0,1] 마스크 적용 결과.

 

그림 B. [1,0,-1,1,0,-1,1,0,1] 마스크 적용 결과.

 

 

 

OpenCV 실행코드로 알아볼까? 간단히 코드를 작성해보자.

 

 

IplImage* gray = cvLoadImage(filename, -1); // 알아서 load할것..

CvMat* mat = cvCreateMat(3, 3, CV_32FC1);
cvSetReal2D(mat,0,0,1);
cvSetReal2D(mat,0,1,0);
cvSetReal2D(mat,0,2,-1);
cvSetReal2D(mat,1,0,1);
cvSetReal2D(mat,1,1,0);
cvSetReal2D(mat,1,2,-1);
cvSetReal2D(mat,2,0,1);
cvSetReal2D(mat,2,1,0);
cvSetReal2D(mat,2,2,-1);

cvFilter2D(gray, dst, mat, cvPoint(0,0));

cvShowImage("gray", gray);

cvWaitKey();

 

물론, 좀더 코드가 더러워지겠지만, OpenCV함수없이도 가능하다.

 이미지 픽셀데이터에 접근 할줄안다면 단순히 4중for문을 이용해서 일일이 정의해놓은 상수값을 곱해서 처리해도 된다.

 

 

 

더 이해가 된다면. 이미지에서의 Convolution 연산 (2) 편을 작성해야겠다.

 

 

댓글
  • 프로필사진 비밀댓글입니다 2013.06.06 15:37
  • 프로필사진 Favicon of http://alzi.tistory.com BrownEyes28 MFC는 그냥 UI나 출력만 하는거구
    영상처리는 OpenCV를 이용해서(안해두 되구요)
    처리하고 넘겨주시면 됩니다
    convolution은 4중 for문으로 이루어집니다.
    전체 이미지를 돌기위한 2중 for문
    안쪽에 마스크를 담당하는 2중 for문.

    for(int h=0; h->image.height; h++)
    for(int w=0; w->image.width; w++)
    for(int in_h = h; in_h < mask_height; in_h++)
    for(int in_w=w; in_w <mask_width; in_w++)


    링크 하나 걸어드릴건데 이건 convolution과 비슷한거라 이해하시는데 도움이 되시라고 올리는거구.
    이건 전혀 다른것으로 convolution과 다른 경우입니다.(얼굴 찾는 알고리즘입니다) 다만 윈도우를 전체 이미지에 돌려서 처리하는것은 같은 맥락이라 올려봅니다.
    http://vimeo.com/12774628
    2013.06.07 09:32 신고
  • 프로필사진 윤승규 안녕하세요. 좋은 글 보고 갑니다.
    여쭤볼게 있어서 글을 남기는 데요, 보실지는 모르겠지만...
    Convolution 개념은 알겠는데, 수학적으로 나타내면 f(x,y)*g(x,y) = integral ( f(n,m) X g(x-n, y-m)) 으로 알고 있는데,
    여기서 쓰신글은 윈도우자체가 이미 순서가 바뀐 상태인가요?

    input 값과 window 값이 순서대로 곱해지는 게 맞는지 헷갈리네요.
    2013.08.19 11:31 신고
  • 프로필사진 Favicon of http://alzi.tistory.com BrownEyes28 죄송합니다 배움이 부족하여.....잘 모르겠네요...ㅠㅠ
    2013.08.26 09:53 신고
  • 프로필사진 하하 보통 컨볼루션 연산값이 -210 같이 음수값으로 나오는 경우 절대값을 구하여 210 으로 변환 양수로 처리합니다. 2014.10.23 11:58 신고
  • 프로필사진 오지랖 왕초보라 이 개념에 혼란이 있었는데 쉬운 예시로 잘 배우고 갑니다 ^^ 2014.11.03 20:26 신고
댓글쓰기 폼
공지사항
Total
186,707
Today
38
Yesterday
48
TAG
more
«   2018/10   »
  1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31      
글 보관함