제가 한동안 좀 뜸하다가 모처럼 글을 올리게 되었네요. 오늘은 불규칙 격자 분포를 하는 2차원 데이터를 이미지의 형태로 표출하는 작업에 관하여 이런저런 얘기들을 좀 해보기로 하겠습니다. 제가 이 블로그에서 유사한 느낌의 주제로 게시물들을 올린 적이 있긴 합니다. 그런데 오늘 다루고자 하는 내용은 데이터 포인트들의 분포가 기본적으로 X 및 Y 방향으로 2차원적인 격자 체계를 가지면서도 특정한 방향(X 또는 Y 방향)으로는 격자점들의 간격이 일정하지 않은 경우에 관한 것입니다. 말로 표현하자니 약간 애매하므로 예제 데이터를 직접 만들고 표출해서 직접 보면서 알아보기로 하겠습니다. 먼저 다음과 같은 방식으로 예제 데이터를 만들어봅시다.
xg = [100, 103, 108, 110, 114, 122, 128, 135, 144, 150]*1.0
yg = [25:70:3.0]
xn = N_ELEMENTS(xg)
yn = N_ELEMENTS(yg)
data = HANNING(xn, yn)*100
HELP, data, xg, yg
PRINT, MIN(data), MAX(data)
이 예제 데이터는 분명히 2차원 배열의 형태를 띄며, X축 및 Y축 방향으로 격자점들이 분포해 있습니다. 다만 X축 방향의 격자점들은 갯수는 10개인데 분포 간격이 일정하지 않습니다. 즉 xg라는 배열을 구성하는 X축 방향 격자점 좌표들은 100~150 범위 내에 있는데, 각 격자점 사이의 간격이 작게는 3에서 많게는 9까지 다양하며 일정하지 않습니다. 그리고 yg라는 배열을 구성하는 Y축 방향 격자점 좌표들은 25~70의 범위 내에서 16개의 격자점들이 3.0의 일정한 간격을 갖도록 설정하였습니다. 그래서 격자점들의 갯수는 X축 방향으로 10개, Y축 방향으로 16개이고, 이에 따라 data라는 배열을 10x16의 2차원 배열의 형태로 정의하였습니다. 그리고 data 배열을 구성하는 총 160개의 값들은 0~100의 범위를 갖도록 하였습니다. 그리고 HELP 명령을 사용하여 이 원본 데이터들에 관한 전반적인 정보를 출력하도록 하였습니다. 출력된 정보는 우리가 예상한대로 다음과 같이 나옵니다.
DATA FLOAT = Array[10, 16]
XG FLOAT = Array[10]
YG FLOAT = Array[16]
이와 같이 2차원 데이터와 X 및 Y 방향 격자점 좌표 데이터를 갖고 있을 때, 이를 NG 체계에서 이미지의 형태로 표출하고자 할 경우에는 기본적으로 다음과 같은 방식으로 작업을 해볼 수 있습니다.
win = WINDOW(DIMENSIONS=[600, 600], /NO_TOOLBAR)
ct = COLORTABLE(34)
im = IMAGE(data, xg, yg, RGB_TABLE=ct, AXIS_STYLE=2, $
XRANGE=[100, 150], YRANGE=[25, 70], MARGIN=0.1, $
ASPECT_RATIO=0, /CURRENT)
이와 같이 IMAGE 함수에 인수를 부여하는데 있어서 2차원 배열인 data만 부여하는 대신 data, xg, yg를 모두 부여함으로써 X 및 Y 방향 격자점 분포를 고려한 표출이 되도록 할 수 있습니다. 이렇게 하여 표출된 결과는 다음 그림과 같습니다.
이 그림을 보면 X축 방향으로 패턴이 다소 뒤틀린듯한 모습이 보입니다. 우리가 만든 예제 2차원 배열은 HANNING 함수에 의하여 10x16의 형태로 만들어진 것인데, 원래 HANNING 함수로 만든 2차원 패턴은 상하 및 좌우 방향으로 완벽한 대칭적 모습을 갖습니다. 그러나 여기서는 X축 방향의 격자점들이 불규칙한 간격으로 분포하기 때문에 그것이 고려되어서 이와 같이 X축 방향으로는 비대칭적이고 다소 뒤틀린듯한 모습으로 표출된 것입니다. 어쨌든 이 정도면 X축 방향의 격자점들의 간격이 불규칙함이 반영되어 무난하게 표출이 된 것으로 볼 수 있습니다. 실제로 대부분의 경우 이 정도로 표출을 하고 마무리하는 경우가 많습니다. 사실 그렇게 해도 별 문제는 없습니다.
그런데 여기서 조금만 더 생각을 해봅시다. 위의 그림을 보면 원본 데이터에 비하여 이미지 자체의 격자들이 상당히 많아진듯한 느낌이 들지않으십니까? 분명히 원본 2차원 데이터는 10x16의 형태를 갖는데, 표출된 이미지를 보면 X 및 Y 방향 모두 격자점 갯수가 그보다는 훨씬 많다는 것을 조금만 신경써서 보면 육안으로도 금방 확인할 수 있습니다. 즉 IMAGE 함수가 원래 데이터의 격자 분포를 기반으로 나름대로 격자 체계를 가공을 해서 표출 처리를 한 것처럼 보인다는 얘기입니다. 맞습니다! 실제로 그렇습니다. 그러면 원래 10x16의 형태였던 2차원 배열이 IMAGE 함수 내에서 대체 어떤 형태로 가공 처리가 되었을까요? 그 내막은 다음과 같은 방식으로 확인할 수 있습니다.
im.GetData, im_data, xg_data, yg_data
HELP, im_data, xg_data, yg_data
즉 이와 같이 IMAGE 함수로 표출된 이미지 개체에 대하여 SetData 메서드를 사용하여 이미지 개체로부터 관련 데이터를 다시 끄집어내서 그 정보를 확인하는 것입니다. HELP 명령으로 출력된 정보는 다음과 같습니다.
IM_DATA FLOAT = Array[100, 100]
XG_DATA DOUBLE = Array[100]
YG_DATA DOUBLE = Array[100]
이 정보를 앞서 원본 데이터에 관하여 HELP 명령으로 확인했던 정보와 비교해보면 분명히 다릅니다. 즉 원래 10x16의 형태였던 데이터이지만 이미지로 표출하는 과정에서 내부적으로 100x100의 형태로 변환해서 최종적으로 표출되었다는 얘기가 됩니다. 물론 이러한 나름대로의 가공 처리는 IMAGE 함수가 자체적으로 수행한 것입니다. 물론 이것이 잘못되었다거나 문제가 있다는 것은 아닙니다. 다만 불규칙한 간격의 격자점 분포를 하는 데이터를 NG 체계에서 IMAGE 함수를 이용하여 이미지 형태로 표출하는데 있어서는, 내부적으로 규칙 격자화된 형태로 나름의 내삽 처리를 거쳐서 최종적인 표출에 반영되는 과정이 숨어있다고 이해하면 됩니다.
* 참고로 DG 체계에서 이미지 표출에 사용하는 TV나 TVSCL의 경우는 이렇게 불규칙한 간격의 격자 기반의 표출은 직접적으로 지원하지 않습니다. 그래서 이러한 작업을 DG 체계에서 하려면 중간에 별도의 내삽 처리 과정을 거치는 것이 필요합니다.
어쨌든 이렇게 처리가 됩니다. 그런데 만약에 이렇게 불규칙한 간격을 하는 원래 격자의 모습을 있는 그대로 살려서 표출을 하고 싶다면 어떻게 해야 할까요? 결과 그림부터 먼저 본다면 다음과 같이 격자의 형태 자체는 사각형이지만 그 사각형의 크기가 일정하지 않은 모습을 그림상에서 그대로 살려서 표출하고자 할 경우를 뜻합니다.
이러한 표출은 이미 그림에서 봤듯이 가능은 합니다. 다만 IMAGE 함수에서는 이러한 형태의 표출 방식을 직접 지원하지는 않습니다. 즉 뭔가 별도의 방법을 사용해야만 가능하단 얘기입니다. 몇가지 대체 방법들을 생각해볼 수 있겠지만 여기서는 다음과 같이 POLYGON 함수를 사용하여 각각의 격자를 사각형으로 그려내는 작업을 반복형 구문을 사용하여 반복적으로 수행하는 방식을 사용해보았습니다.
win = WINDOW(DIMENSIONS=[600, 600], /NO_TOOLBAR)
ct = COLORTABLE(34)
im = IMAGE(data, xg, yg, RGB_TABLE=ct, AXIS_STYLE=2, /NODATA, $
XRANGE=[100, 150], YRANGE=[25, 70], XTICKLEN=0.01, $
YTICKLEN=0.01, MARGIN=0.1, ASPECT_RATIO=0, /CURRENT)
FOR j = 0, yn-2 DO BEGIN
FOR i = 0, xn-2 DO BEGIN
xp = [xg[i], xg[i+1], xg[i+1], xg[i], xg[i]]
yp = [yg[j], yg[j], yg[j+1], yg[j+1], yg[j]]
clr = REFORM(ct[BYTSCL(data[i, j], MIN=0, MAX=100), *])
plg = POLYGON(xp, yp, FILL_COLOR=clr, /DATA)
ENDFOR
ENDFOR
여기서는 각 격자별 사각형을 POLYGON 함수로 표출할 때마다 내부 색상이 데이터 값에 대응되도록 하기 위하여, BYTSCL 함수를 적절히 사용하여 해당 컬러의 RGB값 배열인 clr을 매번 산출하도록 하였습니다. 그리고 시각적인 깔끔함을 위하여 X, Y축의 눈금 길이를 원래보다 대폭 축소하는 처리를 XTICKLEN, YTICKLEN 속성들을 사용하여 수행하였습니다. 이 결과가 바로 위의 그림입니다. 그래서 이러한 그림이 원본 데이터의 불규칙한 격자들의 형태를 충실하게 재현한 경우에 해당됩니다. 다만 이 과정을 실제로 여러분이 직접 실행해보시면 아마 느끼시겠지만, 꽤 많은 갯수의 격자별 사각형들이 POLYGON 함수에 의하여 반복적으로 구현되어야 하기 때문에 반복이 진행될수록 실행 속도가 점점 느려진다는 단점이 있습니다. 따라서 격자 형태가 불규칙하면서 그 갯수도 많다면 이러한 방법으로 표출하는 것이 바람직하지 않을 수도 있다는 점을 유의해야 합니다. 격자의 형태가 불규칙하더라도 그 갯수가 충분히 많을 경우에는 그냥 첫번째 그림을 얻을 때와 같은 방법으로 처리하는 것이 더 효율적일 수도 있습니다.
이제 다시 첫번째 그림과 같은 결과를 얻는 경우로 돌아오겠습니다. 앞서 언급했듯이 원본 데이터는 10x16의 형태인데 IMAGE 함수에 의한 표출 과정에서 내부적으로 100x100의 형태로 변환되어 표출되었습니다. 그런데 이왕 변환하는거 100x100이 아니라 내가 원하는 크기로 지정해서 변환하여 표출하려면 어떻게 해야 할까요? 즉 예를 들어 300x600 또는 500x450 등과 같은 형태로 변환하여 표출하고자 하는 경우입니다. 이 방법에 관해서는 다음 회차에서 살펴보기로 하겠습니다.
'IDL > Image Processing' 카테고리의 다른 글
Histogram Equalization 기법에 관하여 (0) | 2021.01.11 |
---|---|
불규칙 격자 2차원 데이터의 이미지 표출에 관하여 [2] (0) | 2018.12.04 |
Region Growing 기법에 관하여 (0) | 2018.06.06 |
이미지를 원하는 형태로 추출해내는 방법에 관하여 (0) | 2017.05.03 |
이미지의 마스크(Mask) 영역에 대한 색상 처리 (0) | 2017.03.09 |