image 표출에서 NaN의 활용

영상, 특히 위성 영상을 다루다 보면, 값이 없는 곳이 존재합니다. 일반적으로 이런 픽셀들을 -999 같은, 실제 영상에서 사용하지 않는 값으로 기록해 두는데, IDL에서 이 상태 그대로 표출을 하게 되면, IDL은 정말로 값이 -999 라고 간주하고 진지하게 표출을 하게 됩니다.

우리가 원하는 것은 그게 아니죠. 이럴 때, NaN 이라는 컴퓨팅에서 정의된 값을 사용해서 대부분 쉽게 해결될 수 있습니다. NaN은 Not a Number 의 의미입니다. 컴퓨터 메모리 구조상 배열을 빈칸으로 둘 수는 없거든요. 그래서 이 부분에 “무의미한 값”을 의미하는 실수(float) 혹은 정밀실수(double) 타입 데이터 NaN을 사용하여 “의미상 빈 칸”임을 명시하는 것입니다.  IDL에서는 !values.f_nan (실수형)과 !values.d_nan (정밀실수형) 의 시스템 상수로 정의되어 있습니다.

IDL> help, !values.f_nan
<Expression> FLOAT = NaN
IDL> help, !values.d_nan
<Expression> DOUBLE = NaN
IDL> print, !values.f_nan
NaN
IDL> print, 3+!values.f_nan
NaN

보다시피 이 값과 엮여서 계산이 되면 그 결과도 NaN입니다. 좋은 일입니다. 이 값은 실수(mistake)로 의미없는 값이 계산에 얽혀 들어가는 것을 원천봉쇄하는 역할도 합니다. 3+!values.f_nan 대신 3+(-999) 였다고 생각해 보면, (-999)가 사실상 의미 없는 값임에도 불고하고, -996이라는 멀쩡해 보이는 계산 결과를 내 보낼 것이고, 이후 이 값이 마치 의미 있는 값인 것처럼 숨어 다닐 가능성도 있는 것이죠. 이런 버그는 정말 잡아내기 어렵죠.

위성영상 얘기로 다시 돌아오겠습니다.

sat_img_zero_filled

이 영상은 보정을 수행하는 과정에서 테두리 부분에 빈 곳이 생기게 되었던 것 같습니다. 이 부분을 0으로 채워 놓았구요. 그러다 보니 그냥 image() 함수로 디스플레이를 하면 정말로 값이 0일 거라고 생각하고 그려냅니다. 그러다 보니 컬러테이블에서 가장 작은 값을 의미하는 검은색으로 표현이 되었네요.

이 의미없는 영역을 투명처리하고자 하면 어떻게 하면 좋을까요? 앞에 소개한 NaN을 이용하면 간단합니다.

sat_img_nan_filled

첫 줄에 보듯이, 실수(float)형 NaN을 사용하기 때문에 배열을 실수형으로 먼저 바꾸었습니다(정수형 NaN은 정의되어 있지 않습니다). 값이 0인 부분을 찾아서 이 부분을 !values.f_nan으로 교체한 것이죠. 그 결과는 그림에 보듯이 NaN 픽셀을 투명 처리하여 표출합니다. 빈 칸으로 처리한 셈이죠. 다음과 같이 배경색을 넣어 보면 흰색으로 처리한 것이 아니라 투명으로 처리했다는 것이 좀 더 분명해집니다.

sat_img_nan_filled_trans

이와 같이 배경색 키워드 BACKGROUND_COLOR를 이용하면, 값이 없는 위치를 좀 더 명확하게 눈에 띄는 색으로 강조할 수도 있을 것입니다.