'DICOM-医疗数位影像传输协定'

最近有一个医疗图像的比赛,医疗图像以前没有接触过,对于这种格式的数据不甚了解,做了一些调研,记录一下。

定义

医疗数位影像传输协定(DICOM,Digital Imaging and Communications in Medicine)是一组通用的标准协定,在对于医学影像的处理、储存、打印、传输上。它包含了档案格式的定义及网络通信协定。DICOM是以TCP/IP为基础的应用协定,并以TCP/IP联系各个系统。两个能接受DICOM格式的医疗仪器间,可借由DICOM格式的档案,来接收与交换影像及病人资料。—— 维基百科

简言之,DICOM就是一种医疗行业使用的一种数据存储传输标准,广泛应用于各种医疗设备,如:CT、核磁共振、超声等。

内容

协议包含编码格式,图像格式、仪器厂商、仪器序列号、数据生成时间、数据采集方式、病人性别、病人年龄等等。下面是使用PYDICOM读取数据打印的结果。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
(0008, 0005) Specific Character Set              CS: 'ISO_IR 100'
(0008, 0008) Image Type CS: ['ORIGINAL', 'PRIMARY', 'AXIAL']
(0008, 0012) Instance Creation Date DA: '20170728'
(0008, 0013) Instance Creation Time TM: '160113.752'
(0008, 0016) SOP Class UID UI: CT Image Storage
(0008, 0018) SOP Instance UID UI: *
(0008, 0020) Study Date DA: '20170728'
(0008, 0021) Series Date DA: '20170728'
(0008, 0022) Acquisition Date DA: '20170728'
(0008, 0023) Content Date DA: '20170728'
(0008, 002a) Acquisition DateTime DT: '20170728155419.080'
(0008, 0030) Study Time TM: '155226.560'
(0008, 0031) Series Time TM: '160052.584'
(0008, 0032) Acquisition Time TM: '155419'
(0008, 0033) Content Time TM: '155419.410'
(0008, 0050) Accession Number SH: '*'
(0008, 0060) Modality CS: 'CT'
(0008, 0070) Manufacturer LO: 'Philips'
(0008, 0080) Institution Name LO: '*'
(0008, 0081) Institution Address ST: '*'
(0008, 0090) Referring Physician's Name PN: '*'
(0008, 1010) Station Name SH: '*'
(0008, 1030) Study Description LO: 'CT158424'
(0008, 103e) Series Description LO: 'iDose (2)'
(0008, 1040) Institutional Department Name LO: '*'
(0008, 1080) Admitting Diagnoses Description LO: ''
(0008, 1084) Admitting Diagnoses Code Sequence 0 item(s) ----
(0008, 1090) Manufacturer's Model Name LO: '*'
(0008, 1111) Referenced Performed Procedure Step Sequence 1 item(s) ----
(0008, 1150) Referenced SOP Class UID UI: Modality Performed Procedure Step SOP Class
(0008, 1155) Referenced SOP Instance UID UI:1.3.46.670589.33.1.63636853943535791300001.5748714835418010494
---------
(0008, 1140) Referenced Image Sequence 1 item(s) ----
(0008, 1150) Referenced SOP Class UID UI: CT Image Storage
(0008, 1155) Referenced SOP Instance UID UI: 1.3.46.670589.33.1.63636853996983848400001.4836402666508773100
---------
(0008, 3010) Irradiation Event UID UI: 1.3.46.670589.33.1.63636854035098028400003.5509738905066048408
(0010, 0010) Patient's Name PN: '*'
(0010, 0020) Patient ID LO: 'a8d5f610-bd93-4446-9680-1eeb2d6e606d'
(0010, 0030) Patient's Birth Date DA: '*'
(0010, 0040) Patient's Sex CS: 'M'
(0010, 1010) Patient's Age AS: '050Y'
(0018, 0015) Body Part Examined CS: 'ABDOMEN'
(0018, 0022) Scan Options CS: 'HELIX'
(0018, 0050) Slice Thickness DS: "5"
(0018, 0060) KVP DS: "120"
(0018, 0088) Spacing Between Slices DS: "5"
(0018, 0090) Data Collection Diameter DS: "500"
(0018, 1000) Device Serial Number LO: '*'
(0018, 1020) Software Version(s) LO: '4.1'
(0018, 1030) Protocol Name LO: 'Liver C-/CTA/C+ MC /Abdomen'
(0018, 1100) Reconstruction Diameter DS: "338"
(0018, 1110) Distance Source to Detector DS: "1040"
(0018, 1111) Distance Source to Patient DS: "570"
(0018, 1120) Gantry/Detector Tilt DS: "0"
(0018, 1130) Table Height DS: "119.1"
(0018, 1150) Exposure Time IS: "470"
(0018, 1151) X-Ray Tube Current IS: "534"
(0018, 1152) Exposure IS: "251"
(0018, 1160) Filter Type SH: 'B'
(0018, 1210) Convolution Kernel SH: 'B'
(0018, 5100) Patient Position CS: 'HFS'
(0018, 9302) Acquisition Type CS: 'SPIRAL'
(0018, 9305) Revolution Time FD: 0.4
(0018, 9306) Single Collimation Width FD: 0.625
(0018, 9307) Total Collimation Width FD: 80.0
(0018, 9309) Table Speed FD: 170.4
(0018, 9310) Table Feed per Rotation FD: 109.056
(0018, 9311) Spiral Pitch Factor FD: 0.852
(0018, 9323) Exposure Modulation Type CS: '3D MODULATION'
(0018, 9324) Estimated Dose Saving FD: -3.0
(0018, 9345) CTDIvol FD: 17.04320987654321
(0020, 000d) Study Instance UID UI: adce2399-4540-41b7-8018-ee81ea48655e
(0020, 000e) Series Instance UID UI: 2d5c02e9-4a75-4e67-959d-3d705479639c
(0020, 0010) Study ID SH: '*'
(0020, 0011) Series Number IS: "201"
(0020, 0012) Acquisition Number IS: "1"
(0020, 0013) Instance Number IS: "1"
(0020, 0032) Image Position (Patient) DS: ['-161.902', '-33.1', '106.18']
(0020, 0037) Image Orientation (Patient) DS: ['1', '0', '0', '0', '1', '0']
(0020, 0052) Frame of Reference UID UI: 1.3.46.670589.33.1.63636853961048793000002.5747101679789372786
(0020, 1040) Position Reference Indicator LO: ''
(0020, 1041) Slice Location DS: "106.18"
(0020, 4000) Image Comments LT: ''
(0028, 0002) Samples per Pixel US: 1
(0028, 0004) Photometric Interpretation CS: 'MONOCHROME2'
(0028, 0010) Rows US: 512
(0028, 0011) Columns US: 512
(0028, 0030) Pixel Spacing DS: ['0.66015625', '0.66015625']
(0028, 0100) Bits Allocated US: 16
(0028, 0101) Bits Stored US: 12
(0028, 0102) High Bit US: 11
(0028, 0103) Pixel Representation US: 0
(0028, 1050) Window Center DS: ['50', '50']
(0028, 1051) Window Width DS: ['220', '220']
(0028, 1052) Rescale Intercept DS: "-1024"
(0028, 1053) Rescale Slope DS: "1"
(0040, 1001) Requested Procedure ID SH: 'CT158424'
(00e1, 0010) Private Creator LO: 'ELSCINT1'
(00e1, 1002) Private tag data SH: 'Adult'
(00e1, 1036) Private tag data CS: 'YES'
(00e1, 1040) [Image Label] SH: ''
(00e1, 1046) Private tag data OB: Array of 512 bytes
(00e1, 1050) [Acquisition Duration] DS: "2.053"
(00e1, 1063) [Patient Language] SH: 'CHINESE'
(00e1, 10c4) Private tag data DS: "1059.67504882813"
(01f1, 0010) Private Creator LO: 'ELSCINT1'
(01f1, 1001) [Acquisition Type] CS: 'SPIRAL'
(01f1, 1002) [Unknown] CS: 'STANDARD'
(01f1, 1004) [Angular Sampling Density] CS: 'NORMAL'
(01f1, 1008) [Acquisition Length] DS: "215"
(01f1, 100c) [Scanner Relative Center] DS: ['0', '-0.021']
(01f1, 100e) [Unknown] FL: 0.0
(01f1, 100f) Private tag data CS: 'IN'
(01f1, 1026) [Pitch] DS: "0.852"
(01f1, 1027) [Rotation Time] DS: "0.4"
(01f1, 1032) [Image View Convention] CS: 'RIGHT_ON_LEFT'
(01f1, 1044) [Unknown] OW: Array of 644 bytes
(01f1, 1046) [Unknown] FL: 0.625
(01f1, 1047) [Unknown] SH: '3D'
(01f1, 1049) [Unknown] DS: ''
(01f1, 104a) [Unknown] SH: 'DOM'
(01f1, 104b) [Unknown] SH: '128x0.625'
(01f1, 104d) [Unknown] SH: 'YES'
(01f1, 104e) [Unknown] SH: 'Abdomen/Pelvis'
(01f1, 1054) Private tag data IS: "22"
(01f1, 1056) Private tag data LO: '28.204652423757'
(01f7, 0010) Private Creator LO: 'ELSCINT1'
(01f7, 1014) [Unknown] OW: Array of 108 bytes
(01f7, 1019) [Unknown] OW: Array of 2160 bytes
(01f7, 1022) [Unknown] UI: 1.3.46.670589.33.1.63636854035098028400003.5509738905066048408
(01f7, 1029) [Unknown] OW: Array of 440 bytes
(01f7, 1031) [Unknown] OW: Array of 124 bytes
(01f7, 1092) Private tag data OW: Array of 890 bytes
(01f7, 1095) Private tag data OW: Array of 128 bytes
(01f7, 1097) Private tag data OW: Array of 256 bytes
(01f7, 1099) Private tag data OW: Array of 64 bytes
(01f7, 109b) Private tag data IS: "2"
(07a1, 0010) Private Creator LO: 'ELSCINT1'
(7fe0, 0010) Pixel Data OW: Array of 524288 bytes

具体内容并不关心,只看看那些可能会用到,比如病人性别、年龄。

读取显示

使用pydicom

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#-*-coding:utf-8-*-
import cv2
import numpy
import pydicom as dicom
from matplotlib import pyplot as plt

data_dir = 'demo'

dcm = dicom.read_file("demo/1.dcm")
dcm.image = dcm.pixel_array * dcm.RescaleSlope + dcm.RescaleIntercept

slices = []
slices.append(dcm)
img = slices[ int(len(slices)/2) ].image.copy()
ret,img = cv2.threshold(img, 90,3071, cv2.THRESH_BINARY)
img = numpy.uint8(img)

im2, contours, _ = cv2.findContours(img,cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE)
mask = numpy.zeros(img.shape, numpy.uint8)
for contour in contours:
cv2.fillPoly(mask, [contour], 255)
img[(mask > 0)] = 255

kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(2,2))
img = cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel)

img2 = slices[ int(len(slices)/2) ].image.copy()
img2[(img == 0)] = -2000

plt.figure(figsize=(12, 12))
plt.subplot(131)
plt.imshow(slices[int(len(slices) / 2)].image, 'gray')
plt.title('Original')
plt.subplot(132)
plt.imshow(img, 'gray')
plt.title('Mask')
plt.subplot(133)
plt.imshow(img2, 'gray')
plt.title('Result')
plt.show()

kZ63bF.png

参考-1
参考-2