Post

AI 기반 CDSS 고도화 여정, 3D 시각화부터 정밀 종양 탐지까지

AI 기반 CDSS 고도화 여정, 3D 시각화부터 정밀 종양 탐지까지

개요

본 포스트는 임상 의사 결정 지원 시스템(CDSS)을 개발하고 고도화하는 과정에서 마주했던 기술적 과제와 해결 과정을 담은 프로젝트 회고록입니다. Django와 React를 기반으로 구축된 시스템에 CT 이미지 3D 시각화 기능을 안정적으로 구현하고, 나아가 TotalSegmentatornnU-Net을 결합하여 특정 장기의 종양을 정밀하게 탐지하는 AI 파이프라인을 설계 및 검증하기까지의 여정을 공유합니다.


1단계: 초기 3D 시각화 기능 구현 및 안정화

프로젝트의 첫 번째 목표는 사용자가 업로드한 CT 이미지를 3D 모델로 시각화하여 직관적인 분석 환경을 제공하는 것이었습니다. 이 과정에서 몇 가지 핵심적인 기술적 허들을 넘어야 했습니다.

Challenge 1: <iframe> 렌더링과 X-Frame-Options 보안 정책

가장 먼저 부딪힌 문제는 3D 뷰어 라이브러리를 <iframe>으로 렌더링할 때, 브라우저가 콘텐츠 표시를 거부하는 현상이었습니다.

문제: Refused to display '...' in a frame because it set 'X-Frame-Options' to 'deny'.

해결 과정:

  1. Django settings.py 분석: 처음에는 Django의 X_FRAME_OPTIONS 설정이 원인이라 판단하여 수정을 시도했습니다.
  2. 웹서버(Nginx) 설정 확인: Django 설정을 변경해도 문제가 해결되지 않아, 웹 서버 단에서 보안 헤더를 강제하는지 확인했습니다. grep 명령어로 확인 결과, Nginx 설정에는 이상이 없음을 파악했습니다.
  3. 근본 원인 발견: 최종적으로 Django의 XFrameOptionsMiddleware가 별도 설정이 없을 경우, 보안을 위해 기본값으로 DENY 헤더를 설정한다는 사실을 확인했습니다.
  4. 최종 해결: settings.pyMIDDLEWARE 리스트에서 해당 미들웨어를 주석 처리하여 Django가 더 이상 헤더에 관여하지 않도록 조치함으로써 문제를 해결했습니다.

Challenge 2: 데이터 불일치로 인한 분석 결과 누락

RadiologistPanel에서는 보이던 CT 분석 결과가 의사용 DashboardPage에서는 보이지 않는 문제가 발생했습니다.

문제: API를 통해 분석 기록을 가져왔지만, 프론트엔드에서 필요한 3D 모델 경로 등의 핵심 데이터가 누락되었습니다.

해결 과정:

  • 원인 분석: 백엔드의 환자 분석 기록 API가 ListSerializer를 사용하여 데이터를 직렬화하면서, 상세 결과(result 객체)를 포함하지 않는 것이 원인이었습니다.
  • 해결: 해당 API가 상세 정보를 포함하는 DetailSerializer를 사용하도록 수정하여, 프론트엔드에 완전한 데이터가 전달되도록 조치했습니다. 이 과정에서 발생한 연쇄적인 ImportError들을 해결하며 백엔드 API의 데이터 구조를 안정화시켰습니다.

Challenge 3: 사용자 경험(UI/UX) 개선

두 페이지의 뷰어 영역이 너무 좁아 사용성이 떨어진다는 피드백이 있었습니다.

문제: OHIF 뷰어와 3D 뷰어가 화면을 충분히 활용하지 못하고, 레이아웃이 비효율적이었습니다.

해결 과정:

  • Material-UI의 Grid 시스템을 적극적으로 활용하여 반응형 레이아웃을 재구성했습니다.
  • 뷰어 컴포넌트가 포함된 그리드 영역의 너비를 확장(md={8})하고, 내부의 두 뷰어가 항상 50:50 비율을 유지하도록(xs={6}) 수정하여 가독성과 사용성을 크게 개선했습니다.

2단계: AI 파이프라인 고도화 - 정밀 종양 탐지를 향하여

초기 기능 안정화 이후, 프로젝트의 목표는 단순히 장기를 분할하는 것을 넘어 특정 장기 내의 ‘종양’을 정밀하게 찾아내는 것으로 발전했습니다.

단일 모델의 한계

문제: nnU-Net의 사전 학습된 Liver 모델로 추론을 실행했을 때, 종양이 실제보다 훨씬 크거나 엉뚱한 위치에 생성되는 등 정확도 문제가 발생했습니다.

원인: 전체 CT라는 방대한 데이터 안에서 작은 종양을 찾도록 하는 것은 AI 모델에게 매우 어려운 작업이며, 노이즈나 다른 부위를 종양으로 오인할 가능성이 높기 때문입니다.

해결책: 2-Step 파이프라인 설계 및 검증

이 문제를 해결하기 위해, 각기 다른 강점을 가진 두 AI 모델을 순차적으로 실행하는 2-Step 파이프라인을 설계하고 Google Colab을 통해 프로토타입을 검증했습니다.

  1. 1단계 (장기 위치 특정): TotalSegmentator
    • 먼저 TotalSegmentator를 사용하여 전체 CT에서 목표 장기(예: 간)의 정확한 위치와 영역을 찾아냅니다. 이 모델은 ‘전체 장기 분할’에 특화되어 있어 매우 안정적인 성능을 보입니다.
  2. 2단계 (정밀 종양 탐지): nnU-Net
    • 1단계에서 얻은 장기 마스크(Mask)를 원본 CT에 적용하여, 해당 장기 영역만 남기고 나머지 부분은 모두 제거합니다.
    • 이렇게 범위를 크게 좁힌 ‘Masked CT’를 종양 탐지 전문 nnU-Net 모델의 입력으로 사용합니다. 이를 통해 모델의 예측 정확도를 비약적으로 향상시킬 수 있습니다.

이 프로토타이핑 과정에서 발생한 Gzip 압축 오류, 파일 경로 불일치, 셸 명령어와 파이썬 코드 간의 실행 타이밍 문제 등을 해결하며 파이프라인의 안정성을 확보했습니다.


3단계: Multi-omics 연계 및 향후 계획

프로젝트의 최종 목표는 이 AI 파이프라인을 다중 오믹스 분석과 연동하여 진정한 의미의 임상 의사 결정 지원 도구를 완성하는 것입니다.

최종 워크플로우

  1. 오믹스 분석 고도화: 단순 암 유무 판별을 넘어, 어떤 종류의 암(예: LIVER_CANCER)인지 분류하는 모델로 업그레이드합니다.
  2. 사용자 요청: 의사가 Dashboard에서 “간암” 진단 결과를 확인하고, “종양 3D 시각화” 버튼을 클릭합니다.
  3. 자동화된 2-Step 분석 실행: 백엔드에서는 해당 환자의 CT를 대상으로 위에서 설계한 2-Step 파이프라인(TotalSegmentator + nnU-Net)을 비동기적으로 실행합니다.
  4. 최종 결과 제공: 분석이 완료되면, 반투명한 간 모델 내부에 불투명한 노란색 종양 모델이 함께 표시되는 최종 3D 시각화 결과를 사용자에게 제공합니다.

기술적 로드맵

  • Backend: OmicsResult 모델에 cancer_type 필드를 추가하고, 2-Step 파이프라인을 실행할 새로운 Celery Task와 이를 호출할 API 엔드포인트를 구현합니다.
  • Frontend: 오믹스 결과에 “종양 3D 시각화” 버튼을 추가하고, API 호출 및 분석 완료 후 결과를 모달 팝업 등에 렌더링하는 UI/UX를 구현합니다.

결론

초기 3D 시각화 기능 구현 과정에서 겪었던 다양한 문제들을 해결하며 시스템의 안정성을 확보했으며, 더 나아가 딥러닝 모델의 한계를 명확히 인지하고 이를 극복하기 위한 2-Step AI 파이프라인을 성공적으로 설계 및 검증했습니다. 현재 프로젝트는 검증된 프로토타입을 실제 서비스에 통합하는 단계에 있으며, 앞으로 다중 오믹스 데이터와 유기적으로 연동하여 더욱 정밀하고 가치 있는 CDSS를 만들어 나갈 것입니다.

This post is licensed under CC BY 4.0 by the author.