IDL/Image Processing

COLOR_QUAN 함수의 사용법

이상우_idl 2022. 4. 22. 16:46
728x90
반응형

오늘 소개할 COLOR_QUAN 함수24비트 RGB 이미지를 8비트 이미지로 변환하는 역할을 합니다. 물론 8비트 이미지로 변환되더라도 원본 이미지가 갖고 있던 컬러들이 어느 정도 유지되기는 하지만 비트의 수가 24비트에서 8비트로 줄어들기 때문에 컬러 디테일은 당연히 열화가 됩니다. 결국은 컬러 품질이 떨어질 수 밖에 없는데 그럼에도 불구하고 이 COLOR_QUAN 함수는 여전히 나름대로의 사용 가치는 존재합니다. COLOR_QUAN 함수가 필요한 경우는 대략 두가지로 볼 수 있습니다.

 

1) 이미지의 색상 갯수를 256개 또는 그 이하의 단계로 제한하는 것이 더 나을 경우

2) GIF 형식과 같은 8비트 이미지 파일로 저장해할 경우

 

이렇게 두가지 정도로 볼 수는 있지만 통상적으로는 주로 2)와 같은 목적인 경우가 많습니다. 특히 GIF 형식의 경우 그 특성상 8비트 이미지만 저장이 가능한데, 특히나 애니메이션 GIF를 만들어야 하는 경우라면 각 프레임별 그림을 GIF 형식으로의 저장하는 것이 꼭 필요하기 때문입니다. 애니메이션 GIF를 만드는 방법에 관해서 제가 예전에 관련 게시물을 올린 적이 있는데, 이 내용에서도 COLOR_QUAN 함수가 언급되기도 했었습니다. 하지만 오늘은 COLOR_QUAN 함수 자체에 더 집중해서 소개를 해보고자 합니다. 먼저 RGB 이미지를 품고 있는 JPG 파일을 읽어서 이미지 배열로 가져오고 이를 표출해봅시다. 일단 오늘 사용할 예제 JPG 파일은 아래에 첨부하였습니다.

 

eagle_nebula.jpg
0.18MB

 

이 파일을 읽고 표출하는 과정은 다음과 같습니다.

 

ifile = 'eagle_nebula.jpg'
READ_JPEG, ifile, img24
HELP, img24
sz = SIZE(img24, /DIM)
win1 = WINDOW(DIMENSIONS=[sz[1], sz[2]], /NO_TOOLBAR)
i1= IMAGE(img24, MARGIN=0, /CURRENT)

 

여기서는 먼저 READ_JPEG 명령을 사용하여 예제 파일인 eagle_nebula.jpg 파일을 읽고 그 데이터를 img24라는 배열로 가져옵니다. HELP 명령에 의하여 출력된 내용을 보면 img24는 (3, 1024, 1024)의 구조를 갖는 3차원 배열이 됩니다. 24비트 RGB 이미지를 읽어왔기 때문에 이렇게 (3, N, M)의 형태를 갖게 되는 것입니다.

 

IMG24             BYTE  = Array[3, 1024, 1024]

 

그러면 이미지의 가로 및 세로 크기는 두번째 및 세번째 차원에 해당됩니다. 따라서 SIZE 함수로 가져온 정보를 활용하여 그래픽창을 띄울 때 sz[1], sz[2]를 사용한 것입니다. 표출된 이미지의 모습은 다음과 같습니다.

 

 

이 모습은 24비트 RGB 컬러가 그대로 반영된 상태입니다. 그러면 이제 COLOR_QUAN 함수를 사용하여 24비트 이미지 데이터를 8비트로 변환해봅시다. 그 과정은 다음과 같습니다.

 

img8 = COLOR_QUAN(img24, 1, r, g, b)
HELP, img8
HELP, r, g, b

 

COLOR_QUAN 함수에서는 첫번째 인수는 대상이 될 24비트 이미지 배열이 되어야 하므로 img24가 투입되었습니다. 그리고 두번째 인수는 대상 이미지 배열의 Color Interleaving의 방식을 구분하는 숫자가 되어야 합니다. 여기서 Color Interleaving이란 굳이 번역을 하자면 "색상 끼워넣기" 또는 "색상 배정하기" 정도로 해석되긴 하는데, 이미지 배열 내에서 색상값들을 배정하는 방식이라고 보면 됩니다. 여기서는 대상 배열인 img24가 (3, N, M)의 구조이기 때문에 1이라는 값을 사용해야 합니다. 만약 대상 배열의 구조가 (N, 3, M)이면 2가 되어야 하고 (N, M, 3)이면 3이 되어야 합니다. 그리고 뒤쪽에 있는 인수들인 r, g, b는 COLOR_QUAN 함수의 실행 후 얻게 되는 획득 인수들로서, 변환된 8비트 이미지 데이터의 컬러테이블을 구성하는 red, green, blue 채널별 화소값들을 각각 담은 배열들이 됩니다. 그래서 HELP 명령들에 의하여 출력된 내용을 보면 먼저 img8은 (1024, 1024)의 구조를 갖는 2차원 배열이 됩니다. 그리고 r, g, b는 각각 256개의 값들로 구성된 1차원 배열이 됩니다.

 

IMG8             BYTE  = Array[1024, 1024]

R                 BYTE  = Array[256]

G                 BYTE  = Array[256]

B                 BYTE  = Array[256]

 

그러면 이제 COLOR_QUAN 함수로 얻은 img8을 표출해야 하는데, 이를 위해서는 먼저 img8이라는 8비트 이미지에만 연동되는 고유의 컬러테이블 정보를 생성해야 합니다. 이 정보는 나중에 IMAGE 함수에 의한 표출 과정에서 RGB_TABLE 속성에 컬러테이블 정보로서 부여하게 됩니다. 이 정보는 앞서 COLOR_QUAN 함수를 실행하면서 얻은 r, g, b를 가공하여 얻게 되는데, 그 과정은 다음과 같습니다.

 

ct = [[r], [g], [b]]
HELP, ct

 

앞서 COLOR_QUAN 함수를 통하여 얻은 r, g, b 배열들을 위와 같이 합성하여 ct라는 배열로 만들었는데, HELP에 의하여 출력된 내용은 다음과 같습니다.

 

CT                 BYTE  = Array[256, 3]

 

이와 같이 (256, 3)의 2차원 구조를 갖는 배열로 생성된 ct는 img8이라는 8비트 이미지 데이터의 고유 컬러테이블이 품고 있는 256개의 색상들에 대한 RGB 값들을 담게 됩니다. 이제 img8을 표출하면 되는데 그 과정은 다음과 같습니다.

 

sz = SIZE(img8, /DIM)
win2 = WINDOW(DIMENSIONS=[sz[0], sz[1]], /NO_TOOLBAR)
i2 = IMAGE(img8, RGB_TABLE=ct, MARGIN=0, /CURRENT)

 

여기서는 앞서 얻은 ct를 IMAGE 함수의 RGB_TABLE 속성에 부여하였음을 주목해야 합니다. 그리고 img8이란 이미지의 가로 및 세로 크기는 첫번째 및 두번째 차원에 해당됩니다. 따라서 SIZE 함수로 가져온 정보를 활용하여 그래픽창을 띄울 때 sz[0], sz[1]을 사용하였습니다. 표출된 모습은 다음 그림과 같습니다.

 

 

맨 처음에 img24를 표출했던 그림과 지금 img8을 표출한 그림을 서로 잘 비교해봅시다. 멀리서 얼핏 보면 비슷하게 보일 수도 있겠지만 조금만 자세히 들여다보면 색상 디테일이 확연히 차이나 나는 것을 확인할 수 있습니다. 원활한 비교를 위하여 두 그림을 함께 나란히 붙여서 봅시다.

 

 

왼쪽은 RGB 24비트 이미지 데이터인 img24이고 오른쪽은 COLOR_QUAN 함수에 의하여 8비트로 이미지 변환된 결과인 img8입니다. 아무래도 img8에서 보이는 색상의 변화가 img24에 비하여 부드럽지 못한 것을 바로 알아볼 수 있습니다. 그러면 이제 img8을 GIF 형식의 그림 파일로 저장해봅시다. 이를 위해서는 WRITE_GIF 명령을 사용해야 하며 그 방법은 다음과 같습니다.

 

WRITE_GIF, 'my_img8.gif', img8, r, g, b

 

WRITE_GIF 명령에서 첫번째 인수는 생성될 GIF 파일의 이름이 되어야 합니다. 그리고 두번째 인수는 저장될 8비트 이미지 배열이 되어야 하므로 여기서는 img8이 사용되었습니다. 그리고 세번째~다섯번째 인수들은 컬러테이블 정보를 담은 red, green, blue 채널별 색상값 배열들이 되어야 합니다. 따라서 앞서 COLOR_QUAN 함수를 실행하면서 얻었던 r, g, b가 여기서 인수들로 반드시 사용되어야 한다는 것을 잊지 말아야 합니다. 이렇게 생성된 GIF 파일인 my_img8.gif를 아래에 첨부해봅니다.

 

my_img8.gif
0.62MB

 

그리고 여기서 한가지만 더 살펴보고 싶은 것이 있는데, 바로 img8이라는 8비트 이미지가 갖고 있는 고유의 컬러테이블의 실제 모습입니다. 여기서는 제가 얼마 전에 올렸던 "컬러테이블만 표출하는 방법"이라는 게시물에서 소개한 방법을 그대로 사용하여 표출해봅시다. 그 과정은 다음과 같습니다.

 

win_ct = WINDOW(DIMENSIONS=[800, 300], /NO_TOOLBAR)
cb = COLORBAR(RGB_TABLE=ct, FONT_SIZE=11, $
  TICKLAYOUT=1, TICKVALUES=[0, 50, 100, 150, 200, 255], $
  POSITION=[0.05, 0.1, 0.95, 0.85], /BORDER)
tx = TEXT(0.5, 0.9, 'Color Table of img8', ALIGNMENT=0.5, FONT_SIZE=16, /NORMAL)

 

즉 앞서 우리가 얻었던 컬러테이블 색상값 배열인 ct를 대상으로 하여 그 컬러테이블의 모습을 표출한 것입니다. 표출된 그림의 모습은 다음과 같습니다.

 

 

이와 같이 24비트 RGB 이미지에 대하여 COLOR_QUAN 함수를 사용하여 8비트 이미지로 변환하게 되면, 원래의 RGB 이미지가 갖고 있던 색상들을 최대한 비슷하게 가져와서 나름대로의 컬러테이블로 재구성하게 됩니다. 그러다보니 아무래도 이 컬러테이블을 구성하는 색상들의 구성 및 분포는 이렇게 독특할 수 밖에 없습니다. 따라서 8비트로 변환된 이미지를 제대로 표출하기 위해서는 이 컬러테이블 정보가 반드시 있어야만 한다는 것을 꼭 염두에 두어야 하겠습니다.

 

이와 같이 COLOR_QUAN 함수를 사용하여 24비트 RGB 이미지를 8비트 256색상 이미지로 변환하는 방법을 알아보았습니다. 여기서 사용한 예제 이미지의 경우를 보면, 다양한 색상들이 촘촘하게 사용된 원본 이미지에 비하여 8비트로 변환된 이미지에서는 색상 품질이 떨어질 수 밖에 없다는 것을 알 수 있습니다. 반면 원본 이미지에서 사용된 색상들의 종류가 그리 많지 않은 경우라면 8비트로 변환하더라도 품질의 열화가 그리 두드러지게 느껴지지 않을 수도 있습니다. 그리고 애니메이션 GIF를 만드는 과정에서 이 COLOR_QUAN 함수가 중요한 역할을 하는데, 구체적인 방법은 관련 게시물에서 언급되어 있으므로 관심있는 분들은 한번 확인해보시기 바랍니다.

반응형