Matlab을 이용한 영상처리 - 6. 필터링이란?

Programming/Image Processing 2010. 8. 27. 14:28

Filter는 그 단어의 의미대로 특정 픽셀을 거르는 역할을 한다.

마스크에 해당하는 배열을 넘겨주면 그것을 현재 픽셀과 그 주변 픽셀과의 계산을 통해 적절한 결과를 낸다.

그 계산 과정을 c 언어로 표현하자면, 

for(int i = 1 ; i < N; i ++ ){
  for( int j = 0; j < M; j++){
    for(int offset_I = -3; offset_I < 3 ;  offset_I ++){
       for(int offset_j = -3; offset_j < 3; offset_j++){
           product =  마스크배열[offset_i][offset_j] * 주변픽셀[offset_i][offset_j];
           sum += product;
       }    
    }//주변 픽셀 검색
     image[i][j] = sum;
  }
}//전체 이미지 픽셀
와 같은 형태다. 

주어지는 마스크 배열에 따라 이 결과는 천차만별인데 , 이를 이용해 이미지에 다양한 변화를 줄 수가 있다.

이번 포스팅에서는 평균필터링과 고주파 필터링에 대해 살펴본다.

평균필터의 형태는 다음과 같다. ( 3 X 3 일때 )

1/9 * [ 1 1 1 ; 1 1 1 ; 1 1 1] 

위의 알고리즘과 연계해서 생각해보면, 현재 수정하고 있는 픽셀의 값은 주변 픽셀들과 자신을 평균내어 결정 된다는 것이다.

평균을 낸다면 이미지는 ? 경계선뿐만아니라 이미지가 전체적으로 흐려지게 될것이다. 
(모든 픽셀이 주변픽셀들의 값과 비슷해진다는 얘기니까.)

이해를 돕기위해 간단한 예를 들어보자.

255    0   255
250    0   250
150   10  150

와 같은 3 X 3 의 원본 이미지가 있다. 
원본이미지는 중앙에 선명한 검은 선이 있다.
현재 정중앙의 픽셀을 검색하고 있다고 할 때 이 이미지에 평균 필터링을 적용하면,

255 * 1/9 + 255 * 1/9 + 250 * 1/9 + 250 * 1/9 + 150 * 1/9 + 150 * 1/9 = 146.6666...

이미지는 

255  0   255
250 146 250
150  10 150

이 된다. 한 픽셀에만 적용해보았지만 중앙의 경계선이 뭉개졌다.
이와 같은 과정이 전체 이미지에 적용된다면 전체 이미지가 흐려질 것이라고 이해할 수 있다.

Matlab에서는 필터를 만들때 fspecial이라는 함수를, 
필터를 적용할때 filter2(filter,image, shape)의 함수를 이용한다.

직접 저렇게 필터배열을 넘겨주어도 되지만 자주 이용되는 필터는 Matlab에 이미 배열로 저장되어 있다.

평균필터링은 'average'로 호출할수있으며, fspecial 첫번째 인자로 지정가능하며 두번째 인자로 마스크의 크기를 지정할 수 있다.

평균필터링의 실행 결과를 보자.



확연한 차이를 보이기위해 마스크의 크기를 11 X 11로 처리했다.
원영상과 비교해 확실히 흐리게 나타났다.

Matlab을 이용한 영상처리 - 4. 양자화와 디더링

Programming/Image Processing 2010. 8. 25. 16:00

1. 양자화

GrayScale 에서, 대부분 256 색을 가지고있다. 이 색은 인간이 인식가능한 대부분의 색을 표현하는 데 무리가 없다. 그런데 ,만약 표현가능한 색이 256보다 제한되있다고 한다면 ?

양자화는 이런 제한사항을 가진 이미지를 만든다 .

매우 간단하게 2가지 색만 가진다고 한다면, 다양한 이미지에 적용될 수 있는 간단한 이분법은 중간값(256에선 128)을 기준으로 그 이하의 값을 가진 픽셀은 0 으로 , 그 값을 초과하는 픽셀은 1로 표시 할 수 있다.

f = floor(double(Image)/d);
와 같이 나누고
q = uint8(f*d);
를 통해 디스플레이에 좋은 값으로 스케일링해 표시 할 수 있다.
( 단순히 나눠 뿌리기만하면 d개의 다른 색이 표현되긴 하겠지만 인간이 인지할 수 없는 차이의 색이 선택될 것이다.)

그러나 영상처리에 관한한 아주 Powerful한 기능을 제공하는 Matlab은 보다 적합한 하나의 함수를 만들어 놓았다.
 
grayslice(Image,d)를 이용하여 d개의 그레이를 만들고,
gray(d)를 이용하여 디스플레이에 좋게 스케일링한다.

지루한 이론 설명은 이쯤하고 소스와 실행결과를 살펴보자.


중요한건 7번 라인이다. 앞에서 장황하게 늘어놓았던건 다 이 하나의 라인을 설명하기 위한 것이었다.

Figure 1. 양자화 결과

2개의 스케일 (흰색,검은색) 만을 가지기 때문에 이진영상과 같은 결과가 나왔다.
4개의 스케일을 가지게 하면 ,


하늘(흰색), 뒤쪽산(연한 회색) , 앞산(진한 회색) , 나무(검은색) 들이 4가지 색으로 표현 되었다.

2. 디더링

뭐 나름 이런 이미지도 분위기 있고 좋지만, 색상이 제한되어 있다 하더라도 이미지를 그자체로 느끼기가 너무 어렵다 !

필자가 만화를 좋아하므로 , 만화책을 생각해보자!
요새는 만화책 원고 작업도 디지털화되어서 잘은 모르겠지만, 가까운 몇년전만해도
색을 표현해야할때 톤을 붙이는 것이 일반적이었다.
기억나는지 ? 톤은 흰색과 검은색밖에 없지만 , 진한 부분은 검은 점이 잦게 찍혀있었고, 그렇지 못한 부분은 검은점이 드물게 찍혀있었다.
필자가 초등학생땐, 만화-라긴 민망하고 낙서에 가까웠다-를 그릴때 톤처럼 표현하겠다고 모나미 펜으로 일일히 점을찍기도......

쨌든!
요는 , 제한 된 개수의 색에서도 색을 좀 더 다채롭게 표현하는 이 '톤'의 기법이 Dithering 이다.

표준 디더링 매트릭스 D = [ 0 128 ; 192 64 ] 를 이용하여 디더링해보자!


13번 라인: repmat - 아마도 repeat matrix의 abbreviation? D 매트릭스를 128 X 128 개 갖는 매트릭스를 생성한다.
14번 라인: g는 grayImage이고, 매트릭스끼리의 비교는 동일한 인덱스끼리 이루어진다. 비교 대상 픽셀의 값이 계속해서 바뀌기 때문에 값이 같은 픽셀끼리도 다른 색이 될 수 있다. 하지만 상대적으로 밝은 부분은 아무리 인덱스가 바뀌어도 대부분 하얀색을 유지할것이며, 그렇지 않은 부분은 검은색을 유지하는데, 이 비교대상 픽셀값의 변경으로 '톤'과 같은 효과를 낼 수가 있다.

Figure 2. 디더링 결과


Figure 1과 같이 사실은 이진영상이지만 , 비교적 다채로운 색상이 표현되었다!

Matlab을 이용한 영상처리 - 3. 비트평면과 공간 분해능

Programming/Image Processing 2010. 8. 25. 01:33


비트평면에 대해서도 이미지를 첨부할까 했지만 본인의 귀차니즘으로인해 .. -ㅅ-
글로만 정리하게 될 것 같다. 자주 사용되는 기능은 아닌것 같으니 ( 뭐 Most significant bit는 영상의 또렷함?을 강조하기위해 사용될 수도 있을거 같긴하다!)..

1. bit plane

grayscale 영상은 비트평면(bit plane)으로 분리, 2진 영상의 수열로 변환할 수가 있다.
각 화소의 그레이 값이 8비트의 2진 워드일때, 최하위 비트(0번째)는 이미지에 가장 영향을 적게 미치는, 자주 변하게 되는 값일 것이며, 최상위 비트(7번째)는 가장 큰 영향을 미치는 비트일 것이다.
- 이 말이 잘 와닿지 않는가 ?  숫자 128 을 생각해보자. 128에서 가장 영향이 큰 숫자는 당연히 최상위 10진 비트 , 1( 이 예에서 숫자 8의 자리수의 100배의 영향 ) 의 값을 가진 100의 자리다. -

grayscale 이미지 g에서 , mod를 이용해 나머지를 얻어낼 수 있으며, floor를 통해 내림효과를 낸다.
이를 조합해 최상위비트(7번째)의 비트 평변을 얻어내는 소스는 다음과 같다

g7 = mod(floor(g/128),2);



2. 공간 분해능


Line 4 : 같은 이미지를 불러왔다.
Line 6 : GrayScale화.
Line 7 : 공간분해능 
 이 부분이 공간 분해능의 Core이다. nested imresize의 형태를 취하고 있는데, 첫번째(안쪽)의 imresize는 먼저 이미지를 1/16로 축소를 한다.

이 작업을 설명하기 위해 단순화 시킨 예를 먼저 생각해보자.

W(1,1)  W(1,2)  W(1,3)  W(1,4)  ....
W(2,1)  W(2,2)  W(2,3)  W(2,4)  ....
W(3,1)  W(3,2)  W(3,3)  W(3,4)  ....
W(4,1)  W(4,2)  W(4,3)  W(4,4)  ....

위 배열은 순서쌍을 인덱스로 하여 Matrix W를 나열한 것이다.
만약 imresize(W,1/2) 를 수행하면 위 Matrix는

W(1,1)  W(1,2)  W(1,3)  W(1,4)  ....
W(2,1)  W(2,2)  W(2,3)  W(2,4)  ....
W(3,1)  W(3,2)  W(3,3)  W(3,4)  ....
W(4,1)  W(4,2)  W(4,3)  W(4,4)  ....

색깔이 칠해진 배열만을 선택하여 출력하게 된다. 4 X 4 에서 색칠한 배열은 정리하면 2 X 2 가 되니 뭐 그럭저럭 원하는 대로 축소된 셈이다.

이 이미지를 다시 imresize(W,2)를 통해 2배 확대를 하면 어떻게 되는가 ?
축소전의 W(1,1) W(1,2) 등은 복구가 불가능하다.
때문에 확대시에는

W(2,2)  W(2,2)  W(2,4)  W(2,4)  ....
W(2,2)  W(2,2)  W(2,4)  W(2,4)  ....
W(4,2)  W(4,2)  W(4,4)  W(4,4)  ....
W(4,2)  W(4,2)  W(4,4)  W(4,4)  ....

와 같이 남은 인덱스를 그 자승만큼의 수가 될 수 있도록 복사한다.
때문에 출력된 이미지는 모자이크와 같은 이미지가 된다.

Figure 1. 공간분해능 실행결과



생각보다 Blurring에 가까워 졌다 .. 왜지 ? ㅡㅡ 이렇게 하면 이론상으론 모자이크에 가까워야하는데 . .
아무튼 저 이론은 맞다. 원인을 파악하는대로 수정하겠다. (무책임..)