IDL/Image Processing

Edge Detection in IDL

이상우_idl 2017. 3. 2. 17:00
728x90
반응형

Edge Detection이라는 개념은 이미지 처리 분야에서 자주 등장하는데, 이 Edge라는 것을 우리말로 표현한다면 일종의 "경계선"과 같은 개념이라고 보면 어떨까 합니다. 즉 Edge Detection은 "경계선 탐지" 정도의 의미라고 보면 충분할 것 같습니다. 이미지 처리에 있어서 이 경계선(Edge)이란 개념은 이미지 상에 존재하는 화소(Pixel)의 값이 급격하게 변하는 부분을 뜻하는 것으로 생각하면 됩니다. 즉 화소값이 확연하게 차이가 나는 영역들을 서로 구분해주는 분할선에 해당되겠지요. IDL에서도 이와 같은 경계선 탐지 기능을 수행하는 관련 루틴들이 여러 종류가 내장되어 있습니다. 이 중 몇 개만 소개해 볼까 합니다.


먼저 예제를 위하여 다음과 같은 JPG 파일을 활용하고자 합니다. 이 파일을 받아서 그냥 PC 자체 뷰어 프로그램으로 열어보면 어떤 이미지인지 미리 볼 수가 있는데, 미국 시카고의 Ohare 공항 상공에서 촬영된 이미지입니다. 이 이미지 파일은 원래 IDL 설치 디렉토리에서 examples/data 안에 ohare.jpg라는 이름의 파일로 포함되어 있는데, 원본의 크기가 5000x5000으로 너무 크기 때문에 제가 그 중 일부 영역을 잘라서 지금 첨부한 ohare_small.jpg라는 파일로 만들어 놓은 것입니다.


ohare_small.jpg


먼저 이 이미지 파일을 읽어서 원본 그대로 표출하는 과정을 다음과 같이 수행합니다. 그러면 다음 그림과 같이 원본 이미지가 뜹니다.


READ_JPEG, file, img, /GRAY

HELP, img

sz = SIZE(img, /DIM)

WINDOW, 0, XSIZE=sz[0], YSIZE=sz[1], RETAIN=2

TV, img



여기서 하나 염두에 둘 것은 원본 JPG 파일은 그냥 뷰어로 열어서 보면 컬러 이미지인데 위의 IDL 예제 코드에서 열어본 모습은 흑백 이미지라는 점입니다. 즉 원본은 RGB(24비트) 이미지이지만 후속 이미지 처리 과정을 위하여 일부러 8비트 이미지로 변환하였습니다. 이를 위하여 READ_JPEG 프로시저를 사용할 때 /GRAY라는 키워드를 사용하였습니다. 사실 "이미지 처리" 과정을 원활하게 수행하기 위하여 이와 같이 처리하는 경우가 많습니다. 만약 /GRAY 키워드를 사용하지 않고 그대로 읽으면 배열 img는 3x500x500의 구조를 갖게되지만, /GRAY 키워드를 사용하여 읽으면 배열 img는 그냥 500x500의 구조를 갖게 됩니다. 이미지 처리와 관련된 루틴들에 인자로 투입하려면, 이와 같이 가로x세로 형태의 구조를 갖는 배열이 되어야 합니다.


그러면 이제 이 img 배열을 IDL의 경계선 탐지 기능 루틴에 투입해 보겠습니다. 먼저 ROBERTS라는 경계선 탐지용 함수에 투입하여 그 결과를 별도의 그래픽창에 표출해 봅시다. 그 과정은 사실 다음과 같이 꽤 간단합니다. 그리고 그 결과는 다음 그림과 같습니다.


img_edge = ROBERTS(img)

PRINT, MIN(img_edge), MAX(img_edge)

WINDOW, 1, XSIZE=sz[0], YSIZE=sz[1], RETAIN=2

TVSCL, img_edge



원래의 이미지인 img의 모습과 비교해서 보면 어떤 방식의 경계선 탐지 작업이 수행된 것인지 대략 감이 올 것 같은데요. 물론 여기서 사용된 구체적인 알고리즘에 관한 내용은 IDL 도움말에서 ROBERTS 함수에 관한 부분을 찾아보면 자세히 설명이 되어 있으므로 이 내용을 참조하면 됩니다. 사실 경계선 탐지 알고리즘들은 다른 이미지 처리 알고리즘들과 마찬가지로 컨볼루션(Convolution)이라는 기법을 근간으로 합니다. 이 원본 이미지 배열에 대하여 컨볼루션을 수행하는데 있어서 어떤 커널(Kernel)을 어떤 방식으로 사용하느냐에 따라 수많은 기법들이 파생되는데, 경계선 탐지 역시 그러한 파생 기법들 중 하나라고 보면 됩니다.


IDL에서는 경계선 탐지용 함수가 ROBERTS외에도 꽤 여러 종류들이 지원되는데, 이번에는 SOBEL이라는 함수를 사용해 보겠습니다. 이를 위해서는 위의 예제 코드에서 ROBERTS를 다음과 같이 SOBEL로 대체하기만 하면 됩니다. 나머지 내용은 같습니다.


img_edge = SOBEL(img)


이와 같이 SOBEL 함수를 적용한 결과는 다음 그림과 같습니다.



아마 그냥 눈으로 보기에는 ROBERTS나 SOBEL의 결과는 서로 큰 차이는 없어 보일 수도 있습니다. 물론 IDL 도움말에서 각 루틴의 내부 알고리즘을 살펴보면 분명히 다릅니다만, 그냥 눈으로 보기에는 둘 중 어느 것을 사용해도 큰 상관은 없을 것 같습니다. 그러면 좀 다른 느낌의 결과를 주는 경계선 탐지 루틴을 사용해 봅시다. 이를 위하여 CANNY라는 내장함수를 다음과 같이 사용하면 됩니다. 그러면 그 결과는 다음 그림과 같습니다.


img_edge = CANNY(img)



이번에는 확실히 느낌이 다르죠? 말 그대로 Canny 알고리즘을 사용하는 방식인데 역시 IDL 도움말에서 이 CANNY 함수에 관한 내용을보면 이 알고리즘에 대한 세부 내용이 잘 나와 있습니다. 그리고 이 CANNY 함수의 결과 배열인 img_edge의 최소 및 최대값을 출력해보면 0, 1이라는 것을 알 수 있는데, 일종의 바이너리(Binary) 이미지에 해당됩니다. 따라서 표출된 결과 이미지를 보면 어중간한 색상이 없고 완벽하게 검정색과 흰색으로만 구분된 모습을 보이게 됩니다. 어쨌든 나름 그럴싸한 경계선 탐지 결과가 나온 것으로 보입니다.


이외에도 IDL에서는 경계선 탐지 기능을 수행하는 함수들이 몇 개 더 지원이 되는데 그 이름들만 적어보면 대략 다음과 같습니다.


EDGE_DOG, EMBOSS, LAPLACIAN, PREWITT, SHIFT_DIFF


이 함수들도 위와 같은 방식으로 직접 적용해 볼 수 있으므로 여러분들이 직접 사용해보시길 권장합니다. 이 중 EMBOSS라는 함수를 다음과 같이 사용해 본 결과를 마지막으로 한번 봅시다.


img_edge = EMBOSS(img)



이 결과 이미지는 앞서 봤던 결과들과는 또 다른 느낌입니다. 혹시 이 함수의 이름에서 뭔가 느낌이 올 수도 있는데, 아마 "엠보싱"이라는 단어가 그리 낯설지 않으실 겁니다. 옛날에 "엠보싱 화장지" 이런 제품도 있었거든요. 그 약간 볼록볼록한 느낌과 비슷하지 않습니까? 어쨌든 이와 같은 경계선 탐지 기능을 수행하는 루틴들의 이름을 보면 마치 사람의 이름처럼 보이는 것들도 있는데, 실제로 그 기법을 처음고안한 사람의 이름을 딴 경우들이 꽤 있습니다. 앞서 언급했듯이 경계선 탐지라는 기법 자체가 컨볼루션을 기반으로 하는데 어떤 형태의 커널을 어떤 방식으로 사용하느냐에 따라 그 종류가 여러가지가 있을 수 있습니다. 따라서 특정한 방식을 고안한 사람의 이름을 따는 경우도 있다는 점 참고로 알아두시면 좋을 것 같습니다.


오늘 소개한 내용은 여러분들이 갖고 계신 이미지 파일들에도 직접 적용해 볼 수도 있습니다. 따라서 다양한 예제 이미지들을 사용하여 테스트해보시면 여러모로 재미있을 것 같습니다.

ohare_small.jpg
0.05MB
반응형