Oleg Pianykh, Digital Imaging and Communications in Medicine (DICOM) (Springer, 2008) 정리 3편
참고 챕터: Ch 5.6 – 5.7
1. Patient-Study-Series-Image — DICOM의 4계층 정보 모델
DICOM은 모든 영상 데이터를 4단계 계층으로 조직한다.
Patient (환자)
└── Study (검사) — 1명에게 여러 검사 가능
└── Series (시리즈) — 1검사에 여러 시리즈
└── Image (영상) — 1시리즈에 여러 영상 (= Instance)
1.1 실제 임상 워크플로우 매핑
👤 환자 John Smith (Patient)
│
├── 📅 2026-05-26 검사 (Study 1)
│ ├── 🧲 MR T2W axial (Series 1)
│ │ ├── slice 1
│ │ ├── slice 2
│ │ └── ... slice 30
│ ├── 🧲 MR DWI (Series 2)
│ └── 🧲 MR ADC (Series 3)
│
└── 📅 2026-08-15 추적검사 (Study 2)
└── 🧲 MR T2W axial (Series 1)
└── ...
- 1 환자 → 평생 동안 여러 번 병원 옴 (Study가 쌓임)
- 1 검사 → 한 번의 방문에서 여러 modality, 여러 sequence를 찍을 수 있음 (Series로 나뉨)
- 1 시리즈 → 같은 protocol로 찍은 영상 묶음 (slice들이 Image로)
1.2 각 계층의 식별자
| 계층 | 식별자 | Tag | VR |
|---|---|---|---|
| Patient | Patient ID | (0010, 0020) |
LO |
| Study | Study Instance UID | (0020, 000D) |
UI |
| Series | Series Instance UID | (0020, 000E) |
UI |
| Image | SOP Instance UID | (0008, 0018) |
UI |
💡 Patient ID만
LO(Long String)이고 나머지는 다UI(globally unique identifier). 왜? Patient ID는 사람이 손으로 입력하기 때문에 자유 형식이 필요. 나머지는 장비가 자동 생성하니까 엄격한 UID 형식 사용.
1.3 핵심 규칙
같은 UID = 같은 객체
Study UID가 같으면 같은 검사. Series UID가 같으면 같은 시리즈.
이게 깨지면 PACS가 데이터를 못 묶음.
2. Patient ID의 현실적 문제들 ★
이름 대신 Patient ID를 쓰는 이유는 명확하다.
- 이름은 오타 가능 (
John SmithvsJhon Smith) - 결혼/개명으로 바뀜
- 영문 시스템에 한글/일본어 입력 어려움
- 프라이버시 위반
하지만 Patient ID에도 문제가 많다.
2.1 표준화 부재
전 세계 통일 Patient ID 체계가 없다. 각 병원이 자기 정책으로 부여:
- 사회보장번호 사용 (재방문 시 일관)
- 단순 일련번호 (이 병원에서만 유효)
- 환자 이름 자체를 ID로 사용 (의미 없음)
- 검사 종류/판독의에 따라
123.ForDrSmith,123.Followup등으로 변형
2.2 실제 사고 사례
저자가 경험한 케이스들:
Case 1: "W/I" 환자
한 병원이 ID 없는 환자를 모두 "W/I" (Without ID)로 등록 → DICOM은 다 같은 환자로 봄 → 수백 명이 한 명으로 merge.
Case 2: 3자리 ID 한계
ID를 3자리(000–999)로만 부여하던 영상센터 → 1000명 넘어가니 ID 재사용 → 서로 다른 환자가 merge.
Case 3: 쌍둥이 자매
같은 의사에게 같은 발목 문제로 동시 방문. 성이 20자 길이 한국식 풀네임이라 first name이 잘림. 의사도 누구 영상인지 구분 불가.
2.3 PACS의 방어 로직
좋은 PACS는 Patient ID 하나만 믿지 않는다. 추가 검증 로직:
# 의사코드
def is_same_patient(record_a, record_b):
if record_a.patient_id == record_b.patient_id:
# ID 같다고 끝이 아니라 cross-check
if (record_a.name == record_b.name and
record_a.birth_date == record_b.birth_date and
record_a.sex == record_b.sex):
return True
else:
flag_for_human_review() # 같은 ID인데 다른 사람?
# ID 다르지만 다른 정보 일치 시
if (record_a.name == record_b.name and
record_a.birth_date == record_b.birth_date):
suggest_merge()
→ patient merge / split 기능이 모든 PACS의 필수.
⚠️ 자동 merge/split은 금지. 사람이 확인해야 함. 잘못 merge하면 진단 정보 오염.
2.4 AI 추론 앱 입장에서
AI 추론 앱은 PACS에서 영상을 받아 처리할 때:
[PACS] ──C-Move──> [AI 앱] ──추론──> [Orthanc] ──C-Store──> [PACS]
│
└── Patient ID + Name + Birth Date 다 보고
"동일 환자" 검증 후 처리
- 받은 영상의 Patient ID만 믿지 말고 cross-check
- 추론 결과를 PACS에 보낼 때 원본 Study/Patient UID 그대로 유지 (그래야 PACS가 같은 검사에 묶어줌)
3. Study/Series/Image UID의 문제들
Patient ID와 달리 이 셋은 장비가 자동 생성한다. 그래서 비교적 안정적이지만 함정도 있음.
3.1 흔한 사고: Series UID 깨짐
CT 한 시리즈가 2,000장인데, 어떤 기술적 이유로 각 슬라이스마다 Series UID가 다르게 생성되는 경우 발생.
❌ 잘못된 경우:
slice 1 → Series UID: 1.2.3.4.1
slice 2 → Series UID: 1.2.3.4.2 ← 달라짐!
slice 3 → Series UID: 1.2.3.4.3
...
→ PACS가 2,000개의 "1장짜리 시리즈"로 인식
→ 3D 재구성, 뷰어에서 슬라이스 묶음 안 됨
해결책은 거의 없음. modality(장비) 쪽에서 고쳐야 한다. PACS는 Series UID만 보고 묶기 때문에 사후 복구가 어려움.
(Patient ID와 달리 Series에는 merge 기능이 없는 경우가 많음)
3.2 UID는 인스턴스마다 달라야 한다
영상을 조금이라도 수정하면 (crop, rotate, lossy compression):
- 임상 정보는 같아 보여도
- SOP Instance UID 새로 부여 필요 (2편 10.2 참조)
원본: SOP UID = ...1.1
JPEG 압축: SOP UID = ...1.2 ← 새 UID!
크롭됨: SOP UID = ...1.3 ← 또 새 UID!
PACS에 똑같이 생긴 영상이 두 개 따로 저장돼 있다면 → 둘 중 하나가 수정본일 가능성.
3.3 Secondary Capture의 함정
필름을 스캔하거나 외부 영상을 DICOM으로 변환할 때:
- 디지타이저는 "이 영상들이 같은 환자/검사/시리즈인지" 모름
- 사용자가 수동으로 Study/Series UID 부여 해야 함
- → 이 기능이 부실한 SC 장비를 사면 영상이 다 흩어짐
AI 추론 앱이 secondary capture(추론 결과 영상)를 만들 때도 같은 문제. 원본 Study UID를 유지하고, Series UID는 새로 생성해야 같은 검사 하위에 묶임.
4. Hierarchical vs Relational Query
DICOM은 데이터 조회 방식을 두 가지 정의한다.
4.1 Hierarchical Query (계층적, 필수)
위에서부터 차근차근 내려가야 한다.
"John Smith의 지난달 CT 영상 찾기"
1. Patient Level: Patient Name="Smith*" → Patient ID 획득
2. Study Level: 그 Patient ID + StudyDate=last month → Study UID 획득
3. Series Level: 그 Study UID + Modality="CT" → Series UID 획득
4. Image Level: 그 Series UID → Image UID 목록
모든 DICOM 장비 필수 지원. 간단하고 효율적이지만 4번 왕복.
4.2 Relational Query (관계형, 선택)
상위 정보 없이 바로 검색:
"Modality=CT AND Date=last month AND Series Description='axial'"
→ 바로 매칭되는 Series UID 반환
DB의 WHERE 절처럼 자유롭게 조건 조합. 한 번에 끝.
| Hierarchical | Relational | |
|---|---|---|
| 지원 | 필수 (Mandatory) | 옵션 (Optional) |
| 쿼리 단계 | 4단계 | 1단계 |
| 효율 | 단순함 | 유연함 |
| Conformance Statement | 항상 있음 | 명시되어야 함 |
🛠 PACS 모듈 개발 시: PACS 벤더의 Conformance Statement에서 "Relational Query 지원하는지" 꼭 확인. 지원 안 하면 무조건 hierarchical로 짜야 함.
5. Module, Information Entity, IOD — 데이터 조직화
2,000개의 데이터 element를 그냥 막 쓸 수는 없다. 의미 있는 단위로 묶어야 함. DICOM은 3계층 조직화를 정의:
┌─────────────────────────────────────────────┐
│ IOD (Information Object Definition) │ ← 가장 큰 단위
│ ┌─────────────────────────────────────────┐ │
│ │ IE (Information Entity) │ │ ← 실세계 엔티티
│ │ ┌──────────────────────────────────┐ │ │
│ │ │ Module │ │ │ ← 속성 묶음
│ │ │ ├─ Data Element │ │ │
│ │ │ ├─ Data Element │ │ │
│ │ │ └─ Data Element │ │ │
│ │ └──────────────────────────────────┘ │ │
│ └─────────────────────────────────────────┘ │
└─────────────────────────────────────────────┘
5.1 Macro Attributes — "함수처럼 재사용"
여러 곳에서 똑같이 쓰이는 속성 묶음. 매번 풀어 쓰지 않고 매크로처럼 참조.
예: "Referenced Series Sequence" 매크로
(0008, 1115) Referenced Series Sequence SQ
>(0020, 000E) Series Instance UID
>(0008, 114A) Referenced Instance Sequence SQ
>>(0008, 1150) Referenced SOP Class UID
>>(0008, 1155) Referenced SOP Instance UID
> 깊이로 중첩 표현. 다른 IOD에서 "이 매크로 포함" 한 줄로 가져올 수 있음.
5.2 Information Module — 기본 빌딩 블록
관련 속성을 묶은 단위. 약 100개의 표준 모듈 존재.
예시 1: Patient Identification Module
| Attribute | Tag |
|---|---|
| Patient Name | (0010, 0010) |
| Patient ID | (0010, 0020) |
| Other Patient IDs | (0010, 1000) |
| Other Patient Names | (0010, 1001) |
| Patient's Birth Name | (0010, 1005) |
| Patient's Mother's Birth Name | (0010, 1060) |
| Medical Record Locator | (0010, 1090) |
→ "환자 식별과 관련된 모든 속성"을 한 묶음으로.
예시 2: Cine Module (동영상 재생용)
| Attribute | Tag | 설명 |
|---|---|---|
| Frame Time | (0018, 1063) |
프레임 간 시간 (ms) |
| Cine Rate | (0018, 0040) |
FPS |
| Preferred Playback Sequencing | (0018, 1244) |
Loop or Sweep |
| Start Trim / Stop Trim | (0008, 2142/2143) |
재생 시작/끝 프레임 |
→ 초음파 cine loop 같은 multiframe 영상에서만 필요. CT/MR에는 없음.
5.3 Module의 사용 분류
| 코드 | 의미 |
|---|---|
| M | Mandatory (필수) |
| C | Conditional (조건부 필수) |
| U | User-defined (선택, 옵션) |
→ Modality(영상 종류)마다 어떤 Module이 M/C/U인지 정의.
예: Patient Identification Module은 모든 modality에서 M.
5.4 ⚠️ Module은 정규화돼 있지 않다
DB 설계자라면 놀랄 부분: 여러 모듈이 같은 attribute를 중복으로 포함한다.
Patient Name (0010,0010)이 Patient Module, Patient Identification Module 등 여러 곳에 등장- Cine Module 안에 Frame Time과 Cine Rate가 둘 다 있음 (
Cine Rate = 1000 / Frame Time)
이게 좋은 설계는 아니지만, 표준이 25년에 걸쳐 진화하면서 누적된 결과.
🛠 DICOM 개발자 조언 (저자 인용):
"DICOM 모듈을 기본 데이터 빌딩 블록으로 사용하라. base Module 클래스를 만들고, 각 모듈마다 자식 클래스로 확장. 객체지향의 힘을 활용하면 코드가 깔끔해진다."
대부분의 DICOM 소프트웨어가 모듈 무시하고 element 직접 다루다가 버그 양산 중.
6. Information Entity (IE) — 실세계 엔티티
Module이 "속성 묶음"이라면, IE는 실세계 엔티티(객체) 다.
Common Patient IE = Patient Module
+ Specimen Identification Module
+ Clinical Trial Subject Module
Common Study IE = General Study Module
+ Patient Study Module
+ Clinical Trial Study Module
6.1 DICOM의 IE들 (약 20개)
Patient ─── Study ─── Series ─── Image
│ │
│ ├── Waveform (음성/심전도)
│ ├── SR Document (구조화 리포트)
│ └── Presentation State
│
├── Frame of Reference (3D 좌표계)
└── Equipment (장비 정보)
각 박스가 IE. 이 모델이 바로 DICOM의 "세계관"이다.
6.2 4계층 vs IE
5.1에서 본 Patient/Study/Series/Image 4계층은 IE 중 핵심 4개의 hierarchy. 실제로는 더 많은 IE가 존재 (Waveform, SR, Frame of Reference 등).
7. IOD (Information Object Definition) — 최종 객체
여러 IE를 모아 실제 DICOM 객체 타입을 정의한 것이 IOD.
7.1 CT Image IOD 분해 예시
CT 영상 하나를 만들기 위해 필요한 IE + Module 조합:
| IE | Module | Usage |
|---|---|---|
| Patient | Patient | M |
| Clinical Trial Subject | U | |
| Study | General Study | M |
| Patient Study | U | |
| Clinical Trial Study | U | |
| Series | General Series | M |
| Clinical Trial Series | U | |
| Frame of Reference | Frame of Reference | M |
| Equipment | General Equipment | M |
| Image | General Image | M |
| Image Plane | M | |
| Image Pixel | M | |
| Contrast/Bolus | C (조영제 사용 시) | |
| CT Image | M | |
| Overlay Plane | U | |
| VOI LUT | U | |
| SOP Common | M |
→ 이 모든 모듈을 합쳐서 하나의 CT Image IOD 완성.
MR Image IOD는 이 중 CT Image 모듈만 MR Image 모듈로 교체하면 거의 됨. NM(핵의학)은 multiframe 등 더 많이 바꿔야 함.
7.2 Normalized vs Composite IOD
DICOM은 IOD를 두 종류로 분류.
Normalized IOD: 단일 실세계 엔티티만 표현
- 예: Study IOD → Study 고유 속성(검사 날짜, 시간 등)만
- "그 Study의 환자 이름"은 포함 안 함 (그건 Patient의 속성)
- DB 정규화 개념과 같음
Composite IOD: 여러 엔티티를 섞어 통합
- 예: CT Image IOD → 환자 정보 + Study 정보 + 장비 정보 + 영상 자체
- 한 객체 안에 다 들어있어서 자기 완결적
- DICOM 영상 객체는 거의 다 Composite
[Composite CT Image IOD]
├── Patient 정보 (Name, ID, Birth Date)
├── Study 정보 (Study UID, Date, Description)
├── Series 정보 (Series UID, Modality)
├── Equipment 정보 (제조사, 모델)
├── Image 정보 (Rows, Columns, Pixel Spacing)
└── Pixel Data ← 실제 영상
→ 그래서 CT 영상 한 장(.dcm 파일 하나)에 환자 이름까지 다 들어있는 것.
7.3 IOD ↔ Class / Instance 관계
IOD = 추상 클래스 (e.g., "CT Image 타입")
DICOM Object = 그 클래스의 인스턴스 (실제 영상 데이터)
SOP Class UID = 어떤 IOD 타입인지 가리키는 UID
SOP Instance UID = 그 인스턴스의 UID (= Image UID와 동일)
객체지향 비유
class CTImageIOD: # IOD = Class
patient_name: str
study_uid: str
pixel_data: bytes
# ... 약 50~100개 속성
my_image = CTImageIOD() # DICOM Object = Instance
my_image.patient_name = "Smith^John"
my_image.pixel_data = b"..."
→ 2편에서 본 "DICOM Object"는 사실 모두 IOD의 instance.
7.4 SOP Class UID로 IOD 식별
DICOM 영상마다 (0008, 0016) SOP Class UID 가 있어서 "이게 어떤 IOD인지" 알려준다.
| SOP Class UID | IOD |
|---|---|
1.2.840.10008.5.1.4.1.1.2 |
CT Image Storage |
1.2.840.10008.5.1.4.1.1.4 |
MR Image Storage |
1.2.840.10008.5.1.4.1.1.6.1 |
US Image Storage |
1.2.840.10008.5.1.4.1.1.88.22 |
Enhanced SR Storage |
1.2.840.10008.5.1.4.1.1.7 |
Secondary Capture Image Storage |
→ AI 추론 앱이 추론 결과를 PACS에 보낼 때, 올바른 SOP Class UID를 선택해야 함. CT 결과를 MR Image Storage로 보내면 PACS가 reject.
8. 전체 그림 — 모든 개념의 연결
┌─────────────────────────────────────────────────────────┐
│ 🌐 DICOM Information Model │
└─────────────────────────────────────────────────────────┘
📋 Data Dictionary (2,000+ 표준 attribute)
│
▼
🧩 Module (관련 attribute 100여 묶음)
│
▼
📦 Information Entity (Patient, Study, Series, Image, ...)
│
▼
🎯 IOD (CT Image, MR Image, SR, ...)
│ (추상 Class)
▼
💾 DICOM Object = IOD Instance
│
▼
📁 DICOM File (.dcm) ← 디스크에 저장됨
OR
🌐 DICOM Network ← Association으로 전송됨
┌─────────────────────────────────────────────────────────┐
│ 계층 구조 (조회 시 사용) │
│ Patient ID → Study UID → Series UID → SOP Instance UID │
└─────────────────────────────────────────────────────────┘
9. AI 추론 앱 관점에서의 정리
AI 추론 앱이 PACS와 상호작용하는 시나리오 정리
9.1 영상 수신 (PACS → AI 앱)
PACS AI 앱
│ │
│ ① C-Find: Modality=MR │
│ ←──────────────────────────── │
│ ② Study UID 목록 응답 │
│ ──────────────────────────────→ │
│ ③ C-Move: Study UID 지정 │
│ ←──────────────────────────── │
│ ④ C-Store: 영상 전송 (Composite IOD)│
│ ──────────────────────────────→ │
│
▼
[Orthanc 또는 로컬 디스크]
Patient/Study/Series 계층으로 저장
→ SOP Class UID 확인
→ Pixel Data 추출 → 입력
9.2 추론 결과 전송 (AI 앱 → PACS)
결과
│
▼
[Secondary Capture IOD 또는 SR IOD 생성]
│
├─ Patient ID: 원본과 동일 ✅
├─ Study UID: 원본과 동일 ✅ ← 같은 검사 하위로 묶이게
├─ Series UID: 새로 생성 ✅ ← 별도 시리즈로 구분
├─ SOP Instance UID: 새로 생성 ✅
└─ SOP Class UID: 1.2.840.10008.5.1.4.1.1.7 (SC) 또는 SR
│
▼
C-Store → PACS
핵심 원칙:
- 상위 식별자(Patient, Study)는 절대 바꾸지 말 것 → 안 그러면 같은 검사로 묶이지 않음
- Series/Image UID는 새로 생성 → 원본과 구분
- 그래야 PACS 뷰어에서 환자 검사 펼쳐보면 "원본 시리즈들 + AI 결과 시리즈" 가 같이 보임
10. 핵심 정리
| 개념 | 한 줄 |
|---|---|
| 4계층 | Patient → Study → Series → Image. 모든 PACS 데이터의 뼈대 |
| Patient ID | 표준화 안 됨. 병원/장비마다 천차만별. Cross-check 필수 |
| Study/Series/Image UID | 장비 자동 생성. globally unique. 한번 부여되면 불변 |
| Hierarchical Query | 4단계로 내려가는 필수 쿼리 방식 |
| Relational Query | DB WHERE처럼 자유 쿼리. 옵션 |
| Module | 관련 attribute 묶음 (약 100개). M/C/U 분류 |
| Information Entity (IE) | 실세계 엔티티 (Patient, Study, Image 등). 약 20개 |
| IOD | 여러 IE를 조합한 최종 객체 타입 (= 추상 Class) |
| DICOM Object | IOD의 instance |
| Normalized IOD | 단일 엔티티만 (정규화) |
| Composite IOD | 여러 엔티티 통합. 영상 IOD는 대부분 이것 |
| SOP Class UID | "이게 어떤 IOD인지" 알려주는 UID |
11. 다음 글에서 다룰 것
4편: DICOM SOP — C-Echo, C-Store, C-Find
- AE Title (Application Entity Title) — PACS 등록 시 필수
- DIMSE (DICOM Message Service Elements)
- Service-Object Pair (SOP) 의 정확한 의미
- C-Echo — 연결 테스트
- C-Store — 영상 저장
- C-Find — 쿼리
참고
- Pianykh, O.S. Digital Imaging and Communications in Medicine (DICOM). Springer, 2008.
'Dev > DICOM' 카테고리의 다른 글
| [DICOM] DICOM Association — PACS 통신 디버깅이 일어나는 곳 (0) | 2026.06.10 |
|---|---|
| [DICOM] 영상을 가져오는 방법 — C-Move, C-Get, Modality Worklist (0) | 2026.06.10 |
| [DICOM] DICOM 통신의 시작 — C-Echo, C-Store, C-Find (0) | 2026.06.10 |
| [DICOM] Tag, Data Dictionary, Object Encoding — DICOM 데이터를 바이트로 푸는 법 (0) | 2026.05.27 |
| [DICOM] DICOM이란 무엇인가? — 데이터 표현(VR)까지 (1) | 2026.05.26 |
