라즈베리파이에서 Processing을 이용한 그레이 영상만들기

메카 2017-03-22 (수) 09:04 2년전 1480  

4장 그레이스케일 영상 만들기

 

이번 실습에서는 컬러 영상을 그레이스케일 영상(0~255)으로 변환을 해봅시다. 컬러영상은 한 개의 픽셀에 대해 기본적으로 R, G, B 세 가지 색의 정보를 가지고 표현한다. 그레이스케일 영상은 검은색(0)과 흰색(255)의 중간색인 회색의 색상으로 이미지를 표현한 것이다. 중간 단계인 회색은 128의 값을 가진다. R, G, B 색상을 이용한 그레이스케일 변환 식들을 아래에 나타내었다.

 

gray1 = ( Red + Green + Blue ) / 3 - (1)

gray2 = 0.299 * R + 0.587 * G + 0.114 * B - (2)

 

(1)은 가장 단순한 형태로써, R, G, B각각의 값을 더하여 3으로 나눈 값, 즉 평균값을 이용하는 방법이다. (2)는 아날로그 방송 시스템에서 사용되는 컬러 인코딩 방식인 PAL(Phase-Alternating Committee)에서 사용하는 방법이다. 컬러 TV가 처음 나왔을 때, 흑백TV에서도 컬러로 방송되는 것을 잘 보기 위해 만들어진 방식이다.

 

[실습4-1] 그레이스케일 영상을 화면에 그리기

영상 1개를 불러와서 식(1)을 이용하여 그레이스케일 영상을 화면에 그리는 실습이다.

 

a) 소스코드 및 결과 영상

 PImage img;

 

void setup()

{

img = loadImage("TestImage1.jpg");

size(1280, 480);

}

 

void draw()

{

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

img.loadPixels();

for ( int y = 0; y < img.height; y++)

{

for ( int x = 0; x < img.width; x++)

{

int pos = x + y*img.width;

color c = img.pixels[pos];

float r = red( c );

float g = green( c );

float b = blue( c );

float gray = (r + g + b)/3.0;

gray_img.pixels[pos] = color(gray);

}

}

gray_img.updatePixels();

image(img,0, 0);

image(gray_img, 640, 0);

}

 

d359d6799b90841aa23d89d82d81c825_1490140
 

 

[그림 4-1] 실습4-1 소스 코드 및 결과 영상

 

b) 코드 설명

createImage() 함수는 새로운 PImage 클래스 변수 gray_img를 생성하며, 크기와 색상을 지정한다. 이것은 원 영상 변수(여기서는 img)의 값을 수정하여 다른 영상 변수(여기서는 gray_img)에 색상 정보를 저장하기위해 사용한다. img에 저장된 영상의 크기와 같은 것을 사용하기위해 img의 속성정보(img.width, img.height)를 이용하였다. 영상의 픽셀 정보를 불러오고 사용하기위해 먼저 loadPixels() 함수를 선언해야 한다. 이것은 뒤에서 사용되는 pixels[]배열을 사용하기위해서이다. 영상의 각 픽셀 위치는 계산에 의해 pos 변수에 저장된다. 우리가 시각적으로 보는 영상은 2차원 이지만, 내부적으로 저장되어 있는 것는 것은 1차원이므로 계산에 의해 1차원 배열을 이용한다. 컬러 데이터 형태의 값들을 저장하기위해 color 데이터 형태를 사용하였다. 변수 cRGB컬러 정보를 받을 수 있다. red(), green(), blue() 함수는 컬러 변수 c로부터 빨강 성분, 초록 성분, 파랑 성분을 추출하는 함수이다. color() 함수는 괄호속의 값을 RGB로 변환해준다. 여기서는 RGB 모두 같은 색으로 저장이 된다. 다른 색으로 저장 하고 한다면 color( ?, ?, ?) RGB에 각각 원하는 값을 넣어주면 된다. updatePixels() 함수는 PImage 오브젝트의 화소 데이터를 pixel[] 배열의 데이터로 갱신해주는 함수이다. 위에서는 gray_img가 사용하므로 gray_img의 각 화소 값이 갱신된다. gray_img가 포함된 image()함수의 결과는 새론 데이터가 저장된 영상이 화면에 나타난다.

 

[실습4-2] 그레이스케일 영상을 화면에 그리기

영상 1개를 불러와서 식(2)을 이용하여 그레이스케일 영상을 화면에 그리는 실습이다.

 

a) 소스코드 및 결과 영상

소스코드는 실습 4-1과 동일하며, gray 계산식을 아래와 같이 바꾸면 된다.

gray = 0.299 * r + 0.587 * g + 0.114 * b;

d359d6799b90841aa23d89d82d81c825_1490140
 

[그림 4-2] 실습4-2 결과 영상

a) 설명

실험 결과 실험 4-1과 거의 동일한 결과를 나타낸다.

 

 

[실습4-3] 영상을 파일로 저장하기

이번 실습에서는 영상을 파일로 저장하는 것이다. 영상 저장 함수는 save()함수와 saveFrame() 함수를 이용해서 영상 파일을 저장한다.

a) 소스코드 및 결과 영상

 

 

 PImage img,gray_img;

 

void setup()

{

img = loadImage("TestImage1.jpg");

size(640, 480);

}

 

void draw()

{

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

img.loadPixels();

for ( int y = 0; y < img.height; y++)

{

for ( int x = 0; x < img.width; x++)

{

int pos = x + y*img.width;

color c = img.pixels[pos];

float r = red( c );

float g = green( c );

float b = blue( c );

float gray = 0.299 * r + 0.587 * g + 0.114 * b;

gray_img.pixels[pos] = color(gray);

}

}

gray_img.updatePixels();

image(gray_img,0,0);

save("GrayScaleImage1.jpg");

}

 

 

 d359d6799b90841aa23d89d82d81c825_1490140 

 

[그림 4-3] 최종 결과 영상 저장하기

a) 설명

프로그램의 맨 아래 줄에 save()함수를 사용하였으며, 저장 파일 이름은 “GrayScaleImage.jpg"로 하였다. image() 함수의 결과 영상이 저장된다. image()함수를 통하여 그레이스케일 영상이 화면에 그려지며 이 그려진 영상을 “GrayScaleImage.jpg"로 저장하게 되는 것이며, 프로그램에서 정지 버튼을 누를 때까지 갱신이 계속 반복된다. (정지 버튼을 누르지 않고 폴더에서 파일을 확인 할 수 있다.)

 

 

[연습 4-1] (1)과 식(2)에 의한 결과의 차이를 영상처리 결과를 이용해서 설명하시오.

(2)를 이용한 방법이 식(1)를 이용한 방법 보다 약간 밝게 처리된다는 것을 알 수 있다. 결과영상에서 왼쪽 빨간색 사각형안쪽이 오른쪽 빨간색 사각형 보다 밝다.

 

소스코드

 PImage img;

 

void setup()

{

img = loadImage("TestImage1.jpg");

size(1280, 480);

}

 

void draw()

{

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

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

img.loadPixels();

for ( int y = 0; y < img.height; y++)

{

for ( int x = 0; x < img.width; x++)

{

int pos = x + y*img.width;

color c = img.pixels[pos];

float r = red( c );

float g = green( c );

float b = blue( c );

float gray = 0.299 * r + 0.587 * g + 0.114 * b;

float gray1 = (r+g+b)/3.0;

gray_img.pixels[pos] = color(gray);

gray_img1.pixels[pos] = color(gray1);

}

}

gray_img.updatePixels();

image(gray_img,0, 0);

image(gray_img1, 640, 0);

}

 

 

d359d6799b90841aa23d89d82d81c825_1490140

 

메카리워즈 Image Map


모바일 버전으로 보기