IDL/Direct Graphics

DG 체계에서 등위선(contour)과 이미지(image)의 중첩

이상우_idl 2016. 4. 4. 08:30
728x90
반응형

2차원 데이터를 표출하는데 있어서 이미지(Image)와 등위선(Contour)은 가장 대표적인 방법입니다. 그리고 이 두가지를 중첩하여 하나의 그림에서 함께 표출하는 방법도 자주 애용됩니다. 자료 처리 및 표출용 프로그래밍 언어들 상당수가 이러한 표출 방법을 지원을 하고 있으며 IDL도 당연히 그 중 하나입니다. IDL에서 이미지와 등위선의 중첩 표출 방법은 몇가지가 있습니다. 가장 최근에는 아무래도 NG 체계에서 지원되는 IMAGE, CONTOUR 함수들을 사용하는 방법이 자주 사용됩니다. 저도 개인적으로는 이 방법을 가장 애용하고 있습니다. 물론 NG보다 오래전부터 존재해왔던 DG 체계에서 나름의 방법들이 존재합니다. 제가 사실 이 블로그에서 주로 NG 체계 위주로 많은 이슈들을 다뤄오고 있는데, 오늘은 모처럼 DG 체계 위주로 얘기를 해보고자 합니다. 그래서 DG 체계에서 이미지와 등위선을 중첩 표출하는 방법에 촛점을 맞추고 얘기를 해볼까 합니다.

 

제 기억으로는 DG 체계에서는 그 유명한 Coyote 라이브러리에 있는 TVIMAGE라는 프로시저가 이러한 작업에 있어서 가장 널리 사용되어온 것 같습니다. 그런데 이미지와 등위선의 중첩 표출이라는 꽤 중요하고 일반적인 작업에 있어서 IDL의 기본 내장 프로시저가 아닌 외부 라이브러리의 프로시저가 애용되어 왔다는 점은 특이하긴 합니다. 사실 여기에는 나름의 이유가 있습니다. IDL에서 이미지를 표출할 때 사용하는 TV 또는 TVSCL 프로시저와 등위선을 표출할 때 사용하는 CONTOUR 프로시저가 구현하는 좌표계를 서로 동기화시키기가 다소 까다롭다는 것이 가장 핵심적인 원인입니다. 다들 아시다시피, 2차원 데이터를 CONTOUR 프로시저를 사용하여 표출하면 XY축이 그려지고 그 안에 등위선들이 그려집니다. 예를 들면 다음과 같습니다.

 

img = HANNING(300, 300)

DEVICE, DECOMPOSED=0

WINDOW, XSIZE=500, YSIZE=500, RETAIN=2

CONTOUR, img, COLOR=0, BACKGROUND=255

 

 

 

여기서는 300X300의 구조를 갖는 2차원 데이터를 가상으로 만들고 DG 체계에서 CONTOUR 프로시저를 사용하여 표출하였습니다. 그리고 배경색을 흰색으로 하고 그림 자체는 검정색으로 처리하였습니다. 그런데 같은 데이터의 이미지를 이 위에 중첩하여 표출한다고 하면, CONTOUR에서 그려진 XY축 공간상에 이미지가 딱 맞게 들어가도록 해야 제대로 표출한 것으로 볼 수 있겠지요. 하지만 이미지 표출을 위하여 사용되는 TV 프로시저의 경우 기본적으로는 Device 좌표계, 즉 픽셀 단위의 좌표 체계에 최적화되어 있습니다. 지금 우리가 원하는 XY축 공간에 딱 맞춘다는 것은 Device가 아닌 Data 좌표계를 기준으로 하는 작업입니다. 물론 TV 프로시저 자체도 Data 좌표계를 지원은 하지만, 이미지의 화소 크기와 XY축 각각의 범위가 서로 수치상으로 안맞을 경우 이것을 서로 맞춰줘야 하는 등의 작업은 필요합니다. 따라서 TV 프로시저로 이러한 모든 작업들을 진행하려면 시스템 변수들을 건드리는 등 다소 귀찮은 과정들이 필요하고, 이러한 종류의 작업들은 일반적인 IDL 유저들 입장에선 다소 난해하게 느껴질 여지가 충분히 있습니다.

 

그래서 이러한 귀찮은 부분들에 굳이 신경쓰지 않고도 중첩을 손쉽게 해줄 수 있는 IDL 루틴들이 몇몇 개발되었는데 그 중 가장 대표적인 것이 바로 David Fanning 선생의 Coyote 라이브러리에 있는 TVIMAGE 프로시저입니다. 저도 예전에 DG 체계에서 작업을 많이 하던 시절에 정말 많이 애용하던 프로시저이기도 합니다. 아마 지금도 이걸 사용하시는 분들이 꽤 계실 것 같기도 합니다. 그래서 지금도 이것을 사용중이고 아무 불편함이 없다고 느끼시는 분들은 여기까지만 읽으시고 나가셔도 될 것 같습니다. 사실 오늘 저는 이 TVIMAGE 및 Coyote 라이브러리를 사용하지 않고도 이러한 중첩 작업을 할 수 있는 방법을 얘기해보고자 합니다. 그 이유는 몇가지가 있는데요. 우선 첫번째는 이미지와 등위선의 중첩이란 작업이 NG뿐 아니라 DG에서도 충분히 수요가 많은 작업이라는 좀 상투적이고 뻔한 이유입니다. 그리고 두번째는 TVIMAGE를 사용하는데 있어서 편의성의 문제인데요. 사실 이 TVIMAGE를 제대로 사용하려면 소스코드 파일 하나만 확보하면 되는 것이 아니라 Coyote 라이브러리의 다른 루틴들도 필요하기 때문에 어차피 Coyote 라이브러리 전체를 설치해야 합니다. 그런데 이 라이브러리 전체가 필요하지 않은 유저들도 있을 것입니다. 그리고 Coyote 라이브러리 자체가 사실 몇 년 전부터 CG 라이브러리라는 통합적인 형태로 운영이 되기 시작하면서, 그 이전 시대에 만들어졌던 루틴들 중 후속 업데이트가 안되고 있는 것들도 꽤 있습니다. 물론 예전 버전의 라이브러리만 설치해놓으면 큰 문제는 없을텐데, 아무래도 IDL 자체가 그 이후로 계속 업데이트가 되고 있기 때문에 그로 인한 옛날 프로그램들과의 충돌 등의 문제도 무시못할 부분입니다.

 

시작부터 너무 잡설만 길게 적고 있는 것 같아 죄송합니다. 핵심을 언급하자면 TVIMAGE보단 투박하고 간소하지만 아주 가볍게 사용할 수 있는 프로그램을 제가 하나 만들어 보았습니다. 이름은 TV_OVER라고 지어보았습니다. 이 루틴의 소스코드 파일은 이 게시물 맨 하단부에 첨부해놓겠습니다. 앞서 CONTOUR 프로시저로 그려놓은 XY축 공간상에 이 TV_OVER 루틴을 사용하여 이미지를 중첩해보려면 다음과 같은 내용을 추가하면 됩니다. 그 결과는 다음 그림과 같습니다.

 

LOADCT, 34

TV_OVER, img, /SCALE

 

 

 

여기서 사용된 TV_OVER는 다음과 같은 문법을 갖고 있습니다.

 

TV_OVER, img, SCALE=scale, INTERP=interp

 

여기서 img라는 인자는 대상이 될 이미지 배열인데, 현재는 2차원 배열만 지원됩니다. RGB 기반의 3차원 배열 지원은 나중에 추가될 예정입니다. SCALE 키워드는 이미지 배열내 화소값의 범위에 대하여 바이트스케일(Byte-Scaling)을 적용할 것인지(1) 말지(0)를 결정하는 역할을 합니다. 마치 이미지 표출을 TV 또는 TVSCL 방식 중 어느 것으로 할 것인가에 해당된다고 보면 됩니다. 그리고 INTERP 키워드는 픽셀값들에 대하여 픽셀 자체를 그대로 살릴 것인지(0) 아니면 2차원 내삽기법(Bilinear Interpolation)을 적용할 것인지(1)를 결정하는 역할을 합니다. 마치 CONGRID 함수의 INTERP 키워드와 동일한 역할이라고 보면 됩니다.

 

그런데 위의 그림의 경우 사실 우리가 원하던 최종적인 모습은 아직 아닙니다. 왜냐하면 이미지가 중첩되면서, 그 이전에 그려졌던 등위선 등의 내용들이 모두 가려졌기 때문입니다. 따라서 이들을 살려내려면 DG의 특성상 CONTOUR 프로시저를 한번 더 사용할 필요가 있습니다. 즉, 다음과 같은 내용을 추가하면 됩니다. 그 결과는 다음 그림과 같습니다.

 

LOADCT, 0

CONTOUR, img, COLOR=0, THICK=2, /NOERASE

 

 

 

여기서 컬러테이블의 경우는 이미지 표출을 위해서는 34번을 사용하였고 등위선 표출을 위해서는 0번을 사용하였습니다. 어쨌든 이제서야 그림이 제대로 그려졌다는 느낌이 오는 것 같습니다. 여기서 CONTOUR 프로시저를 재사용할 때에는 NOERASE 키워드를 반드시 사용해야 한다는 점을 유의해야 합니다. 이 키워드는 DG 체계에서만 사용되는 것으로, 기존에 그려진 그래픽 컨텐츠를 지우지 말고 그대로 둔 채 작업을 진행하란 의미입니다. 원래 DG 체계에서는 그림을 그릴 때 화면을 다 지우고 그리는 것이 일반적인 방식이므로, 별도로 이러한 옵션이 제공되는 것입니다.

 

앞서 잠시 언급했던 INTERP 키워드는 사실 픽셀 크기가 큰 이미지 배열을 다룰 경우에는 가시적으로 큰 영향을 주진 않습니다. 하지만 픽셀 크기가 좀 작은 경우에는 그 차이가 드러나게 되는데요. 예제 이미지 배열인 img를 다음과 같이 30X30이라는 작은 크기로 바꾸고 위와 동일한 순서로 작업을 진행하여 그림을 그려보면 됩니다. 그래서 TV_OVER 사용시 INTERP 키워드를 사용한 경우와 그렇지 않은 경우는 각각 다음과 같은 그림들로 나타나게 됩니다.

 

img = HANNING(300300)

~~~~~~

TV_OVER, img, /SCALE, /INTERP 또는 TV_OVER, img, /SCALE

~~~~~~

 

 

 

 

 

여기서 상단의 그림은 INTERP 키워드를 사용한 경우로서 픽셀간 화소값들이 Bilinear Interpolation으로 내삽된 상태이고, 하단의 그림은 내삽을 전혀 하지 않은 채 픽셀 자체의 모습이 그대로 살아있는 상태입니다. 필요에 따라서 상단 또는 하단의 방식을 적절히 선택하면 됩니다. 오늘 소개하면서 사용한 TV_OVER 프로시저의 소스코드 파일은 아래에 첨부합니다. 사실 IDL이 익숙하신 유저들께서는 소스코드의 내용을 나름대로 수정해서 사용해보실 수도 있을 것 같습니다. 그래도 제 버전의 경우 향후에 업데이트가 있게 되면 여기서 또 언급을 하도록 하겠습니다.

 

tv_over.pro
0.00MB

 

반응형