[딥러닝 전처리] DICOM MRI 데이터를 NIfTI로 변환하고 3D 볼륨을 GIF로 시각화하기

2026. 4. 6. 14:02·개념 정리 step2/메디컬 이미지

의료 영상 처리(Medical Image Processing)를 시작할 때 가장 먼저 마주하는 장벽은 데이터 형식의 변환과 3차원 볼륨의 시각화입니다. 이번 포스팅에서는 실제 MRI 데이터(DICOM)를 3차원 볼륨(NIfTI)으로 변환하고, 이를 다양한 축(Axis)으로 잘라 2D 슬라이스 애니메이션(GIF)으로 만드는 과정을 정리합니다.

1. 필수 라이브러리 설치

의료 영상 처리를 위해 pydicom(DICOM 읽기), nibabel(NIfTI 읽기/쓰기), dicom2nifti(변환 도구), 그리고 시각화를
위한 matplotlib과 scikit-image를 설치합니다.

!unzip -q "/content/drive/MyDrive/.../brain_images.zip" # 데이터 압축 해제
!pip install scikit-image natsort pydicom nibabel dicom2nifti matplotlib

import matplotlib.pyplot as plt
import matplotlib.animation as anim
import numpy as np
import pydicom
import nibabel as nib
import dicom2nifti
from skimage.util import montage
from natsort import natsorted
from pathlib import Path
from IPython.display import Image as show_gif

2. DICOM 읽기 및 기본 탐색

먼저 DICOM 폴더 내의 이미지들을 자연어 정렬(natsorted)하여 로드합니다. 여러 장의 2D 슬라이스를 montage를 사용하여 한눈에 볼 수 있는 그리드 형태로 표현해 전체적인 형태를 파악합니다.

BASE_PATH = Path("/content/brain_images/00825/T2w")
dicom_images = natsorted(list(BASE_PATH.glob("*.dcm")))

# 모든 DICOM 파일의 픽셀 배열을 3차원 배열로 결합
concat_images = np.array([pydicom.dcmread(i).pixel_array for i in dicom_images])

# 3행 15열 그리드로 전체 슬라이스 미리보기
plt.figure(figsize=(10, 10))
plt.imshow(montage(concat_images, grid_shape=(3, 15)), cmap='bone')
plt.axis('off')
plt.show()

3. DICOM을 NIfTI(.nii.gz) 형식으로 변환

딥러닝 모델 학습 시에는 주로 NIfTI(Neuroimaging Informatics Technology Initiative) 형식을 사용합니다. dicom2nifti 라이브러리를 사용하여 DICOM 폴더를 NIfTI 파일로 변환합니다.

# DICOM 폴더를 NIfTI 형식으로 변환
dicom2nifti.convert_directory("/content/brain_images/00825/T2w", "./")

# 변환된 NIfTI 파일 로드
nifti_path = '/content/8_t2w.nii.gz'
sample_img = nib.load(nifti_path)
img_array = np.asanyarray(sample_img.dataobj)

print(f'Original NIfTI Shape: {img_array.shape}') 
# 일반적으로 (height, width, depth) 형태를 가짐

4. 3D 볼륨 데이터 전처리 (축 변환)

NIfTI 파일의 차원 순서는 데이터 생성 도구나 저장 방식에 따라 다를 수 있습니다. 일반적으로 뇌 영상에서는 Z축(슬라이스 방향)이 마지막 차원이나 첫 번째 차원에 위치합니다. 시각화 및 모델 입력을 위해 차원 순서를 (depth, height, width)로 맞추기 위해 transpose를 사용합니다.

# 차원 순서 변경: (height, width, depth) -> (depth, height, width)
# transpose((2, 1, 0))은 Z축을 첫 번째 축으로 이동시킴
transpose_img = img_array.transpose((2, 1, 0))
print(f'Processed Shape: {transpose_img.shape}')

5. 3D 데이터를 2D 슬라이스 GIF로 시각화하기

3차원 뇌 영상은 고정밀도가 필요하므로, 슬라이스별로 이미지를 추출하여 애니메이션(GIF)으로 만드는 것이 효율적입니다. 아래 클래스는 matplotlib의 ArtistAnimation을 사용하여 슬라이스를 프레임별로 추가하고 GIF로 저장하는 역할을 합니다.

class ImageToGIF:
    def __init__(self, size=(500, 500), xy_text=(80, 30), dpi=100, cmap='CMRmap'):
        self.fig = plt.figure()
        self.fig.set_size_inches(size[0] / dpi, size[1] / dpi)
        self.xy_text = xy_text
        self.cmap = cmap
        self.ax = self.fig.add_axes([0, 0, 1, 1])
        self.ax.set_xticks([])
        self.ax.set_yticks([])
        self.images = []

    def add(self, image, label, with_mask=False):
        plt.set_cmap(self.cmap)
        plt_img = self.ax.imshow(image, animated=True)
        plt_text = self.ax.text(*self.xy_text, label, color='red')
        self.images.append([plt_img, plt_text])
        plt.close()

    def save(self, filename, fps):
        animation = anim.ArtistAnimation(self.fig, self.images)
        animation.save(filename, writer='imagemagick', fps=fps)

5-1. 축 방향 1: Z축 슬라이스 (Axial View)

가장 일반적인 단면인 축 방향(Axial) 슬라이스를 시각화합니다. transpose_img의 첫 번째 축(Depth)을 따라 순회하며 각 슬라이스를 GIF 프레임으로 추가합니다.

sample_data_gif = ImageToGIF()
label = nifti_path.replace("/", ".").split('.')[-2]
filename = f'{label}_axial.gif'

for i in range(transpose_img.shape[0]):
    image = transpose_img[i]
    sample_data_gif.add(image, label=f'{label}_{str(i)}')

sample_data_gif.save(filename, fps=15)
show_gif(filename, format='png')

결과 해석: 위 코드는 뇌의 위쪽에서 아래쪽(또는 그 반대)으로 슬라이스를 따라가며 단면을 보여주는 애니메이션을 생성합니다.

5-2. 축 방향 2: Z축 반대 방향 슬라이스 (Rotated View)

뇌 구조를 더 명확히 관찰하기 위해 이미지를 회전시켜 보는 경우도 있습니다. np.rot90을 사용하여 이미지를 180도 회전 시킨 후, 마지막 축(Width 또는 Height에 해당)을 따라 슬라이스를 자릅니다.

sample_data_gif = ImageToGIF()
label = nifti_path.replace("/", ".").split('.')[-2]
filename = f'{label}_rotated.gif'

# 마지막 축(2번 인덱스)을 따라 슬라이스
for i in range(transpose_img.shape[2]):
    # 이미지를 180도 회전 (k=2: 90도 x 2회)
    # axes=(1, 0): 0번과 1번 축을 기준으로 회전
    image = np.rot90(transpose_img[..., i], k=2, axes=(1, 0))
    sample_data_gif.add(image, label=f'{label}_{str(i)}')

sample_data_gif.save(filename, fps=15)
show_gif(filename, format='png')

결과 해석: 이 방식은 뇌의 좌우 대칭 구조나 특정 병변의 형태를 다른 각도에서 관찰할 때 유용합니다.


요약

  1. DICOM -> NIfTI 변환: dicom2nifti 라이브러리를 사용하여 의료 영상 표준 형식으로 변환합니다.
  2. 차원 순서 조정: transpose를 통해 모델 입력이나 시각화에 적합한 (Depth, Height, Width) 형태로 차원을 재배
    열합니다.
  3. 3D -> 2D 슬라이스 시각화: matplotlib.animation을 활용하여 3D 볼륨 데이터를 2D 슬라이스 애니메이션(GIF)으로
    변환합니다.
    • shape[0] 축 순회: 일반적인 Axial View
    • shape[2] 축 순회 + 회전: 변형된 단면 관찰

이 과정을 통해 복잡한 3D 의료 영상 데이터를 직관적으로 이해하고, 딥러닝 모델 학습 전 데이터의 품질을 확인할 수 있습니다.

'개념 정리 step2 > 메디컬 이미지' 카테고리의 다른 글

[메디컬] 의료 인공지능을 위한 신호 처리 개념 정리 및 전처리  (0) 2026.04.23
[Technical Deep Dive] 메디컬 이미지 데이터의 이해와 Python DICOM 실습  (0) 2026.04.05
'개념 정리 step2/메디컬 이미지' 카테고리의 다른 글
  • [메디컬] 의료 인공지능을 위한 신호 처리 개념 정리 및 전처리
  • [Technical Deep Dive] 메디컬 이미지 데이터의 이해와 Python DICOM 실습
고니3000원
고니3000원
프로젝트의 구현 과정과 기술적 노하우를 담았습니다. AI 모델 연구와 매일의 학습 기록을 차곡차곡 공유하고 있습니다.
  • 고니3000원
    곤이의 공부 블로그
    고니3000원
  • 전체
    오늘
    어제
    • 분류 전체보기 (218) N
      • 1. AI 논문 + 모델 분석 (21)
        • AI 논문 분석 (13)
        • AI 모델 분석 (8)
      • 2. 자료구조와 알고리즘 (16)
        • 2-1 자료구조와 알고리즘 (13)
        • 2-2 강화학습 알고리즘 (3)
      • 3. 자습 & 메모(실전, 실습, 프로젝트) (27)
        • 3-1 문제 해석 (4)
        • 3-2 메모(실전, 프로젝트) (14)
        • 3-3 배포 실전 공부 (7)
        • 3-4 최신 기술 분석 (2)
      • 4. [팀] 프로젝트 및 공모전 (31)
        • 4-1 팀 프로젝트(메모, 공부) (1)
        • 4-2 Meat-A-Eye (6)
        • 4-3 RL-Tycoon-Agent (3)
        • 4-4 구조물 안정성 물리 추론 AI 경진대회(D.. (4)
        • 4-5 AgentShield(보안 플랫폼) (17)
      • 5. [개인] 프로젝트 및 공모전 (25) N
        • 4-1 귀멸의칼날디펜스(자바스크립트 활용) (5)
        • 4-2 바탕화면 AI 펫 프로그램 (4)
        • 4-3 개인 프로젝트(기타) (3)
        • 4-4 공모전 (9) N
        • 4-5 나만의 로컬 LLM 멀티 에이전트 구축 (4)
      • 6. 경진 대회 (kaggle, dacon 등) (1) N
      • 개념 정리 step1 (32)
        • Python 기초 (7)
        • DBMS (1)
        • HTML | CSS (3)
        • Git | GitHub (1)
        • JavaScript (5)
        • Node.js (5)
        • React (1)
        • 데이터 분석 (6)
        • Python Engineering (3)
      • 개념 정리 step2 (60)
        • Machine | Deep Learning (15)
        • 멀티모달(Multi-modal) (23)
        • 강화 학습 (10)
        • AI Agent (9)
        • 메디컬 이미지 (3)
      • 개인 공부 - 내가 공부하고 싶은 모든 것 (3) N
        • 1. 인프라 (2)
        • 2. 자율주행 (0)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

    • Notion-포트폴리오
    • Github
  • 공지사항

    • ‘박영곤’ 나의 핵심 가치
  • 인기 글

  • 태그

    Vision
    프로젝트
    RAG
    OCR
    Ai
    Lora
    보안
    알고리즘
    Python
    파인튜닝
    transformer
    인공지능
    전처리
    github
    ViT
    데이터분석
    Agent
    강화학습
    학습
    llm
    paddleocr
    구현
    자료구조
    자바스크립트
    API
    공모전
    pandas
    논문 리뷰
    파이썬
    Ollama
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.5
고니3000원
[딥러닝 전처리] DICOM MRI 데이터를 NIfTI로 변환하고 3D 볼륨을 GIF로 시각화하기
상단으로

티스토리툴바