AI 시대에 AI 없이 CT 데이터 분석하기

CT에서 기도를 Segmentation해보자
더슬립팩토리's avatar
Dec 22, 2025
AI 시대에 AI 없이 CT 데이터 분석하기

안녕하세요, 더슬립팩토리에서 개발 인턴으로 일하고 있는 Henry입니다. 제가 이번 프로젝트를 진행하면서 느끼고 배운 점을 공유하기 위해 글을 남깁니다.

저희는 코골이, 수면무호흡 문제를 해결하는 스타트업입니다. MAD라는 구강장치를 다양한 IT 기술을 활용해 자동으로 설계 및 제조하고, 자신의 수면 상태를 확인할 수 있는 앱을 개발하고 있습니다.

이번에 치과를 연계한 B2B 사업을 추진하면서, 환자의 구강장치 착용 전후 기도 상황을 한눈에 파악할 수 있는 Viewer를 개발해야 했습니다. 원장님들께서 PASA 처방을 위해 별도의 툴을 학습하는 과정없이 임상업무에만 집중하실 수 있는 환경을 마련하기 위한 서포트 차원이었죠.

기도 내 공기만 정확히 감지하여 전후 비교를 하고, 기도의 폭경 및 부피 등을 계산하고, 3D로 돌려보는 기능들이 요구되었습니다.

문제를 해결하는 사고의 흐름

우주먼지와 같았던 저는 GPT가 뱉어내는 코드들을 이해하지도 못한 채 무턱대고 실행하고 이것저것 수정하는 과정을 반복하고 있었습니다.

이를 보고 팀을 리드하시는 Daniel님께서 AI 개발자를 꿈꾸는 저에게 몇 가지 조언을 해주셨습니다.

  1. AI 개발자로서(더 정확히는 한 명의 Problem Solver로서) 처음 해야할 것은 AI라는 수단에 집중하지 말고, 문제 해결이라는 목적에 집중하여 다양한 해결 방식을 생각하는 것이다.

    동일한 문제에 대한 해결책이 기획에도, 디자인에도, 고객에게도, AI에도, 그 밖의 엔지니어링에도 있을 수 있으니 ROI(Return on Investment)를 고려한 해결책을 찾는 것이 리소스가 부족한 스타트업에서 절대적으로 중요하다.

  2. 전세계의 다른 이들은 동일한 문제를 어떻게 해결했는지 조사하고, 시도할 수 있는 옵션을 리스트업한 후, ROI를 고려한 우선순위를 부여하라.(시니어가 될수록 비즈니스, 이해관계자 등 우선순위 설정 시 고려할 변수들이 많아지지만 주니어 레벨에서는 이정도도 충분하다.)

  3. 시도할 방향을 선택했다면 이것 저것 무턱대고 수정하지 말고 결과에 영향을 줄 수 있는 요인들을 하나씩 검증하면서 완성된 해결책에 다가가라.

2주 이상 난항을 겪고 있던 프로젝트는 Daniel님과 다시 방향성을 수립하고 단 3일만에 해결되었습니다. 그럼 제가 진행한 프로젝트의 기술적인 내용을 공유하겠습니다.

AI 없이 Segmentation을 해보자

조사를 해보니, 딥러닝 모델을 활용하면 완전 자동으로 기도를 Segmentation할 수 있지만, 3차원 데이터를 입력으로 받고 추론하기 때문에 연산량이 상당했고(128*128*128의 작은 사이즈로 리샘플링하더라도 Voxel의 수가 무려 200만개…) GPU 자원이 필수적이었습니다.

반면에 사람이 기도 내에 “Seed” 를 짚어주면, 반자동으로 기도를 Segmentation하는 로직은 CPU에서도 충분히 빠르게 동작했습니다.

저희는 비용을 고려하여, 딥러닝 모델없이 Region Growing 알고리즘의 철학을 참고하여 자동화된 Airway Segmentation 기능을 구현하기로 했습니다.

Dicom은 초면인데요?

실험대상으로 선정되신 대표님..

본격적인 설명에 앞서 DICOM에 대해 간단히 짚고 넘어가겠습니다.

CT로 촬영한 3D 볼륨 데이터는 여러 장의 2D 슬라이스로 구성됩니다. 각 슬라이스는 dcm 파일에 저장되고, 이들을 z축 위치순으로 쌓으면 3D 볼륨이 완성됩니다.

각 dcm 파일에는 픽셀 데이터만 있는 것이 아니라, 환자 정보, 픽셀 간의 실제 거리 등 다양한 메타데이터가 함께 들어있습니다.

픽셀 값을 기반으로 HU값을 계산할 수 있습니다. HU(Hounsfield Unit)는 물질의 X선 흡수 정도를 수치화한 것으로, 다음 공식으로 계산됩니다.

HU = 원본 픽셀 값 * RescaleSlope + RescaleIntercept

HU의 일반적인 기준점은 다음과 같습니다.

물질

HU 값

1,000

0

공기

-1,000

이론적으로 순수한 공기는 -1,000 HU입니다. HU값으로만 필터링하면 기도 내 공기를 쉽게 감지할 수 있겠다는 기대감에 잠시 부풀었습니다만, 실제 CT 데이터를 분석해보니 -1,200 ~ -300 까지 편차가 컸습니다.

CT의 한 픽셀은 일정 크기의 공간을 대표하는데, 공기 외에 연조직, 점액 등이 한 픽셀에 섞여 평균값이 측정되는 점과 CT장비에 따른 차이 등을 원인으로 추측하고 있습니다.

알고리즘에 대하여

관심영역(연두색), Seed(파란색), 클러스터링 후 병합한 공기 영역(빨간색)

기도 내의 공기 영역을 Segmentation하는 Task의 가장 중요한 점은 영역 확장의 시작점이 되는 Seed를 정확하게 찍는 것입니다.

우선 850~3,000 의 HU 값으로 뼈를 찾고, 뼈의 바운딩 박스의 좌우 55% 범위, 전후 70% 범위로 Seed가 있을 만한 관심영역을 설정했습니다.

그리고 전체 볼륨의 하단 30% 슬라이스들로부터 Seed 후보군을 추출했습니다. 간혹 목뼈나 턱 밑 허공을 Seed 후보로 설정하는 경우가 있어서 관심영역에서 y축의 3/4 지점에 가까울수록 높은 score를 부여했습니다.

Seed를 정했으면, 위아래 방향으로 슬라이스를 하나씩 이동하며 기도를 추적합니다. 기도는 연속된 관 구조이므로, 인접한 슬라이스에서 기도의 위치는 크게 바뀌지 않습니다. 이전 슬라이스의 중심점을 기억해두고, 다음 슬라이스에서는 그 근처에 있는 공기 영역을 선택합니다.

기도 협착으로 인해 일시적으로 공기 영역이 보이지 않는 슬라이스가 있을 수 있습니다. 이를 위해 최대 15개 슬라이스까지는 건너뛰며 추적을 계속합니다.

이렇게 추적한 결과에는 노이즈가 섞여있을 수 있습니다. 실제로 기도 바깥 일부 영역까지 병합되어 보이는 오류가 빈번했습니다. 이를 해결하기 위해, 슬라이스마다 공기 영역을 선택하여 병합할 때 클러스터링을 수행하여 중심점에서 가깝고, 밀집도가 높은 클러스터만 선택하여 병합했습니다.

마지막으로 3D morphological closing을 적용해 듬성한 부분을 채우고, Marching Cube 알고리즘으로 Voxel 데이터를 Mesh로 변환합니다. 그리고 각 슬라이스의 단면적을 계산해서 색상으로 매핑합니다. 최종 결과물은 웹에서 바로 렌더링할 수 있도록 GLB 파일로 저장했습니다.

개발 중인 3D Viewer

마치며

이 글에서 소개한 접근법은 완벽하지 않습니다. 딥러닝 모델에 비해 엣지 케이스에서 실패할 확률이 높을 수 있습니다.

AI가 대세인 시대에 AI없는 솔루션을 선택한 것이 역설적으로 들릴 수 있습니다. 하지만 문제 해결에는 여러 도구가 있고, 도구보다는 해결에 집중하는 것이 중요하다는 것을 알 수 있는 프로젝트였습니다.

※ 본 글에 사용된 CT 데이터는 더슬립팩토리 직원분들의 동의를 받아 촬영 및 공개되었습니다.

Share article

Pasa