라즈베리파이에서 Processing을 이용한 영상처리- 영역처리(1)

메카 2017-04-13 (목) 22:29 1년전 1165  

7. 영역 처리

  5장에서는 픽셀의 값을 변화 시켜서 영상의 명암과 명도를 조절하였다. 이번 장에서는 픽셀의 주변 화소들을 이용하여 여러 가지 형태의 영상 출력을 다루고자 한다. 영역처리를 이해하기 위해서는 convolution에 대해 이해를 해야 한다. 구글 딥마인드가 개발한 인공지능 바둑 프로그램인 알파고(AlphaGo) 덕분에 deep learning이 많은 주목을 받고 있다. deep leaning 방법 중 하나가 CNN(convolutional Neural Network) 방법이다. 이 장에서 사용하는 방법의 대부분이 Deep Learning에서 사용되는 convolution을 이용할 것이다. 여러분들도 Deep Learning을 시작한 것이다.

일반적으로 널리 사용되고 있는 convolution은 영상 평활화(spreading), 엠보싱(embossing) 영상 강화(sharpening), 에지검출(edge detection), 잡음 제거(noise remove) 등의 효과를 내기위해 사용되는 영상처리 기법이다. convolution의 의미는 두 함수 중 하나를 이동시켜가면서 다른 함수와의 곱을 합한 것이라 정의할 수 있다. 영상처리에서는 이동하는 윈도우 3x3, 5x5 혹은 7x7 로 구성된 convolution kernel(혹은 convolution mask)이라는 행렬을 원 영상에 슬라이딩하면서 새로운 화소 값을 얻는 것이다. 그리 7-1에 나타낸 것처럼, 새로운 값은 kernel의 중앙을 영상의 현재 픽셀에 위치시킨 후 각 kernel의 픽셀 값과 해당되는 영상에서의 픽셀 값들을 서로 곱해서 합을 구하면 생성된다

 

 

9873fc170436f04f37d31125d44bcad0_1492088 

                                                                                        그림 7-1 convolution 수행 방법

 

그림에서 현재 픽셀의 위치 값은 P5이며 H[i,j]convolution 결과 값이 된다. H[i,j] 계산식은 아래와 같다.

 

9873fc170436f04f37d31125d44bcad0_1492088 

일반적으로 convolution kernel에서 가중치(그림 7-1에서 M 값들)의 합은 출력 영상의 모든 화소들의 밝기 값에 영향을 미친다. kernel들은 계수의 합이 1이 되도록 결정된다. 이 경우 convolution된 영상은 원영상과 같은 평균값을 갖게 된다. 그리고 에지 검출에 사용되는 convolution kernel의 가중치는 음수 계수들을 사용하며, 그들의 합은 0이 된다. 이 경우 결과 화소 값 H[i,j]는 음의 값이 생성되기도 한다.

convolution을 구현 할 때 문제가 되는 것은 영상의 외곽을 어떻게 다룰 것인가 하는 것이다. 3x3 윈도우 마스크(convolution kernel 혹은 윈도우 마스크)의 중심이 원영상의 (0,0)에 위치하는 할 때 슬라이딩 윈도우는 그림 7-2와 같이 일부는 윈도우 마스크의 M5, M6, M8, M9는 원영상과 중첩이 되어 문제가 없으나, M1, M2, M3, M4, M7은 중첩이 되지 않으므로 연산 오류가 발생한다. 이 문제를 해결하기위한 방법이 몇 가지 있다.

 

9873fc170436f04f37d31125d44bcad0_1492088 

                                             그림 7-2 영상을 윈도우와 중첩한 convolution

 

 

첫 번째 해결 방법: 윈도우 마스크의 빈 셀들(그림 7-2에서 노란색 영역)의 계수를 0으로 가정하는 것이다. 이 방법은 결과 영상의 끝 부분이 영상의 나머지만큼 중요할 경우에는 좋은 방법이 아니다. 그렇지만 구현 방법은 간단하다.

두 번째 해결 방법: convolution의 시작을 윈도우 마스크와 원 영상이 완전히 중첩되는 부분부터 시작하는 것이다. 윈도우 마스크가 3x3이며, 영상의 크기가 MxN 일 경우, convolution의 시작은 원 영상의 (0,0)이 아니라 (1,1)이며, 종료는 (M-1, N-1)이다. 이 방법은 구현은 간단하지만 영상의 가장자리 픽셀들이 포함되지 않는 단점이 있다. 결과 영상은 (M-2) x (N-2)영상이 된다.

세 번째 해결 방법: 이 방법은 윈도우 마스크의 빈 셀들의 값을 가장 가까운 화소 값으로 대치하는 것이다. 즉 영상의 가장자리 화소 값들을 복사하여 사용하는 방법이다.

본 강좌에서는 가장자리 픽셀이 영상이 전체에 여향을 미치지 않으므로 두 번째 방법을 선택하여 사용한다

 

[실습7-1] 블러링(Blurring)

  영상처리에서도 고주파와 저주파용어를 사용한다고주파는 두 픽셀의 픽셀 값 변화가 크게 나타나는 경우를 말하며저주파는 변화가 작게 나타나는 것을 의미한다블러링은 영상을 흐리게 하는 것으로써영상의 세세한 부분들을 제거한 저주파 공간적 필터링 이라 할 수 있다이 방법은 여러 응용에 상당히 많이 사용되고 있으며카메라의 초점을 흐리게 하거나 배경을 약화시키고자 할 경우 많이 사용된다이러한 블러링은 convolution을 통하여 만들 수 있다일반적인 블러링을 위한 윈도우 마스크의 모든 계수는 같은 값을 가지며그 합은 1이 되도록 한다. 3x3 마스크의 모든 원소들의 계수는 1/9이며, 5x5 마스크 경우는 1/25가 된다마스크의 종류를 그림 7-3에 나타내었다. convolution에 사용된 가중치는 평균 출력 영상의 발기에 영향을 미치지 않도록 선택되며 계수의 합은 1이다. 

                      9873fc170436f04f37d31125d44bcad0_1492088         9873fc170436f04f37d31125d44bcad0_1492088

                                             (a)                                                         (b)
                                            9873fc170436f04f37d31125d44bcad0_1492088
                                                                                   (c)

그림 7-3 블러링 윈도우 마스크 종류

 

 

그림 7-3 (b)의 경우는 가우시안 스무딩 필터이며 사용된 식은 아래와 같다.

9873fc170436f04f37d31125d44bcad0_1492089 

식에서 σ 는 가우스 스무딩 필터의 폭을 조절하는 파라미터이다σ 값이 작으면 가우스 스무딩의 폭이 좁아지며 (윈도우 마스크의 크기가 작아짐), σ 값이 클수록 넓어진다(윈도우 마스크의 크기가 커짐). 

 

a) 소스코드 및 결과 영상

 PImage img;

double[][] blurMask = {{1/9.0, 1/9.0, 1/9.0},

{1/9.0, 1/9.0, 1/9.0},

{1/9.0, 1/9.0, 1/9.0}};

void setup() {

img=loadImage("Street.jpg");

size(640, 240);

}

void draw() {

PImage img_blurring = createImage( img.width, img.height, RGB );

image(img, 0, 0);

img.loadPixels();

for ( int y = 1; y < img.height-1; y++) {

for ( int x = 1; x < img.width-1; x++) {

float S=0.0;

for (int i = -1; i <= 1; i++) {

for (int j = -1; j <=1; j++) {

int pos = (x+j) + (y+i)*img.width;

float val = red(img.pixels[pos]);

S += blurMask[i+1][j+1]*val;

}

}

if(S>255.0) S=255.0;

if(S<0.0) S=0.0;

img_blurring.pixels[x + y*img.width]=color(S,S,S);

}

}

img_blurring.updatePixels();

image(img_blurring, 320, 0);

}

 

 

9873fc170436f04f37d31125d44bcad0_1492089
                                                                   (a)

9873fc170436f04f37d31125d44bcad0_1492089
                                                                    (b)

9873fc170436f04f37d31125d44bcad0_1492089
                                                                    (c)

 

그림 7-4. [실습 7-1] 소스 코드 및 결과영상. (a) 그림 7-3 (a) 3x3 Mask 사용, (b) 그림 7-3 (b) 3x3 Mask 사용, (c) 그림 7-3 (c) 5x5 Mask 사용

 

b) 코드 설명

  윈도우 마스크 3x3 5x5을 이용하였으며, blurMask[] 배열에 계수 값을 미리 저장해 놓는다. 계수 값의 예는 그림 7-3을 참조하여 변형하면 된다. 5x5를 사용 할 경우 주의해야한다. 소스코드에서 for()문을 보면 시작을 1부터하며, N-1까지 사용하였다. 위의 예는 3x3인 경우 이므로, 5x5인 경우는 2부터 N-2까지를 사용하면 된다. 그리고 blurMask[i+1][j+1]blurMask[i+2][j+2]로 변경해주어야 한다

 

 

[실습7-1] 엠보싱(Embossing)

엠보싱은 양각화를 말하며 경계선 추출 필터의 일종이다. 다른 점은 Offset값을 사용하는 것과 음의 값을 가지고 있다는 것이다. 아래 소스코드를 실행시켜 보자.

a) 소스코드 및 결과 영상

 PImage img;

double[][] EmboMask1 = {{-1., 0., 0.}, {0., 0., 0.}, {0., 0., 1.}};

double[][] EmboMask2 = {{0., 0., -1.}, {0., 0., 0.}, {1., 0., 0.}};

double[][] EmboMask3 = {{0., -1., 0.}, {0., 0., 0.}, {0., 1., 0.}};

double[][] EmboMask4 = {{0., 0., 0.}, {-1., 0., 1.}, {0., 0., 0.}};

float Offset=127.0;

void setup() {

img=loadImage("Street.jpg");

size(640, 240);

}

void draw() {

PImage img_embossing = createImage( img.width, img.height, RGB );

image(img, 0, 0);

img.loadPixels();

for ( int y = 1; y < img.height-1; y++) {

for ( int x = 1; x < img.width-1; x++) {

float S=0.0;

for (int i = -1; i <= 1; i++) {

for (int j = -1; j <=1; j++) {

int pos = (x+j) + (y+i)*img.width;

float val = red(img.pixels[pos]);

S += EmboMask1[i+1][j+1]*val;

}

}

S = S+Offset;

if(S>255.0) S=255.0;

if(S<0.0) S=0.0;

img_embossing.pixels[x + y*img.width]=color(S,S,S);

}

}

img_embossing.updatePixels();

image(img_embossing, 320, 0);

}

 

 

9873fc170436f04f37d31125d44bcad0_1492089
                                                                   (a)

9873fc170436f04f37d31125d44bcad0_1492089
                                                                  (b)

9873fc170436f04f37d31125d44bcad0_1492089
                                                                   (c)

9873fc170436f04f37d31125d44bcad0_1492089
                                                                  (d)

그림 7-5. [실습 7-2] 엠보싱 소스 코드 및 결과영상. (a) 소스 코드의 EmboMask1[]을 사용한 결과, (b) 소스 코드의 EmboMask2[]을 사용한 결과, (c) 소스 코드의 EmboMask3[]을 사용한 결과, (d) 소스 코드의 EmboMask4[]을 사용한 결과 

 

b) 코드 설명

  윈도우 마스크 3x3을 사용하였으며, EmboMask[] 배열에 있는 계수 값의 합은 0이 된다. 파란색으로 된 EmboMask?[]에서 숫자를 변경해서 실행 하면 그림 7-5 같은 결과를 얻을 수 있다. EmboMask1[] EmboMask2[]는 대각에 대한 성분이며, EmboMask3[] EmboMask4[]는 수평과 수직에 대한 성분을 추출하는 경우이다.

 

 


모바일 버전으로 보기