一、DICOM简介
DICOM即数字影像和通信标准。在医学影像信息学的发展和PACS的研究过程中,由于医疗设备生产厂商的不同,造成与各种设备有关的医学图像存储格式、传输方式千差万别,使得医学影像及其相关信息在不同系统、不同应用之间的交换受到严重阻碍。为此,美国放射学会(ACR)和全美电子厂商联合会(NEMA)认识到急需建立一种标准,以规范医学影像及其相关信息的交换, DICOM(Digitalimaging and Communications in Medicine)标准就是在这样的背景下产生的。(source from 百度百科)
二、matlab下的DICOM图片解析
infilename=‘test.dcm’;
I=dicomread(infilename); %读取图像
metadata=dicominfo(infilename); %存储信息
以上两行 使用 dicomread 来读取图像,I是一个矩阵(M*N,M、N分别为图片的行、宽);dicominfo获取图片的信息,metadata是一个结构体,在matlab下可以看到其内容如下:
metadata =
Filename: 'test.dcm'
FileModDate: '01-四月-2013 16:34:42'
FileSize: 519106
Format: 'DICOM'
FormatVersion: 3
Width: 484
Height: 484
BitDepth: 12
ColorType: 'grayscale'
FileMetaInformationGroupLength: 192
FileMetaInformationVersion: [2x1 uint8]
MediaStorageSOPClassUID: '1.2.840.10008.5.1.4.1.1.2'
MediaStorageSOPInstanceUID: '1.3.12.2.1107.5.1.4.50364.30000012110123554800000000583'
TransferSyntaxUID: '1.2.840.10008.1.2.1'
ImplementationClassUID: '1.3.12.2.1107.5.1.4'
ImplementationVersionName: 'SIEMENS_S5VB28A'
SpecificCharacterSet: 'ISO 2022 IR 13\ISO 2022 IR 87'
ImageType: 'DERIVED\SECONDARY\LOCALIZER\CSA MPR\\CSAPARALLEL\AXIAL\CT_SOM5 SPI'
SOPClassUID: '1.2.840.10008.5.1.4.1.1.2'
SOPInstanceUID: '1.3.12.2.1107.5.1.4.50364.30000012110123554800000000583'
StudyDate: '20121102'
SeriesDate: '20121102'
AcquisitionDate: '20121102'
ContentDate: '20121102'
StudyTime: '150331.921000'
SeriesTime: '173716.625000'
AcquisitionTime: '150455.664701'
ContentTime: '173716.625000'
AccessionNumber: 'CT201211010515'
Modality: 'CT'
Manufacturer: 'SIEMENS'
InstitutionName: 'Union Hospital Wu Han'
InstitutionAddress: ' Jie Fang Street
/9D40A8/
Han Kou
P.R. CHN'
ReferringPhysicianName: [1x1 struct]
StationName: 'CT10460'
StudyDescription: 'Thorax^AA_LUNG1 (Adult)'
SeriesDescription: '<MPR Range>'
OperatorName: [1x1 struct]
ManufacturerModelName: 'Sensation 16'
ReferencedImageSequence: [1x1 struct]
DerivationDescription: 'MEDCOM RESAMPLED'
PatientName: [1x1 struct]
PatientID: 'P0735733'
PatientBirthDate: '19571101'
PatientSex: 'M'
OtherPatientName: [1x1 struct]
PatientAge: '055Y'
BodyPartExamined: 'CHEST'
SliceThickness: 2
KVP: 100
DeviceSerialNumber: '50364'
SoftwareVersion: 'syngo CT 2006G'
ProtocolName: 'AA_LUNG1'
DistanceSourceToDetector: 1040
DistanceSourceToPatient: 570
GantryDetectorTilt: 0
TableHeight: 159
RotationDirection: 'CW'
FilterType: '0'
GeneratorPower: 14
FocalSpot: 0.7000
DateOfLastCalibration: '20121102'
TimeOfLastCalibration: '073827.000000'
ConvolutionKernel: 'B60s'
PatientPosition: 'HFS'
StudyInstanceUID: '1.2.840.113564.152426559686.14968.634873602640312500.477'
SeriesInstanceUID: '1.3.12.2.1107.5.1.4.50364.30000012110123554800000000672'
StudyID: 'CT20121102150123'
SeriesNumber: 602
AcquisitionNumber: 2
InstanceNumber: 31
ImagePositionPatient: [3x1 double]
ImageOrientationPatient: [6x1 double]
FrameOfReferenceUID: '1.3.12.2.1107.5.1.4.50364.30000012110123350978100003385'
PositionReferenceIndicator: ''
ImageComments: ''
SamplesPerPixel: 1
PhotometricInterpretation: 'MONOCHROME2'
Rows: 484
Columns: 484
PixelSpacing: [2x1 double]
BitsAllocated: 16
BitsStored: 12
HighBit: 11
PixelRepresentation: 0
WindowCenter: [2x1 double]
WindowWidth: [2x1 double]
RescaleIntercept: -1024
RescaleSlope: 1
WindowCenterWidthExplanation: 'WINDOW1\WINDOW2'
Private_0029_10xx_Creator: 'SIEMENS MEDCOM HEADER'
Private_0029_11xx_Creator: 'SIEMENS MEDCOM HEADER2'
Private_0029_12xx_Creator: 'SIEMENS MEDCOM OOG'
Private_0029_1031: '202.0.35898523'
Private_0029_1032: 468512
Private_0029_1033: 0
Private_0029_1034: 'DB TO DICOM'
Private_0029_1160: 'com'
Private_0029_1208: 'MEDCOM OOG 2'
Private_0029_1209: 'VD30C'
Private_0029_1210: [13808x1 uint8]
RequestAttributesSequence: [1x1 struct]
StorageMediaFileSetUID: '1.3.12.2.1107.5.1.4.50364.30050112110209591376300000001'
IconImageSequence: [1x1 struct]
OverlayRows_0: 484
OverlayColumns_0: 484
NumberOfFramesInOverlay_0: 1
OverlayDescription_0: 'Siemens MedCom Object Graphics'
OverlayType_0: 'G'
OverlayOrigin_0: [2x1 int16]
ImageFrameOrigin_0: 1
OverlayBitsAllocated_0: 1
OverlayBitPosition_0: 0
OverlayData_0: [484x484 logical]
在这里面,比较重要的是WindowCenter,WindowWidth,RescaleIntercept,RescaleSlope。WindowCenter是指窗位,WindowWidth是指窗宽,RescaleIntercept,RescaleSlope是关于像素变换的参数,我也不太理解。
1) 方法一
在网络上,找到了一种方法:
X = dicomread('test.dcm'); %读取文件
X = double(X) / double(max(X(:))); %归一化
imwrite(X, '1.BMP'); %存储为bmp
这种方法经过测试也可以执行,结果如下
可以看出,效果不是太理想,而且该方法完全没有查看原来的DICOM文件是否有多个窗位、窗宽的问题,是的DICOM的信息没有得到充分的利用。
1) 方法二
使用metadata的WindowCenter,WindowWidth,RescaleIntercept,RescaleSlope来处理数据。详细函数如下:
function status = dicom2bmp(infilename)
I=dicomread(infilename); %读取图像
metadata=dicominfo(infilename); %存储信息
lop=length(metadata.WindowCenter);%查看窗位数量
if(lop~=length(metadata.WindowWidth))%与窗位数量是否一致
error('this is an error');
end
for i=1:lop
center=metadata.WindowCenter(i)/metadata.RescaleSlope - metadata.RescaleIntercept;%处理窗位数值,这个地方的处理很关键
width=metadata.WindowWidth(i)/metadata.RescaleSlope - metadata.RescaleIntercept;%处理窗宽数值,这个地方的处理很关键
M=mat2gray(I,[center-(width/2),center+(width/2)]);%归一化
a=strcat(infilename,num2str(i));
a=strcat(a,'.bmp');%输出文件名的操作
imwrite(M,a,'bmp');%输出为文件
subplot(1,lop,i),imshow(a),title(a);%显示
End
其结果下:
可见如此的分离,可以使得器官的识别更简单。
注意:
1、dicomread函数读取DICOM函数后返回的矩阵I,是一个非负的矩阵,这和DICOM图像实际数据有所不同(DICOM的数据是在大约-1000~+1000的数值),所以要使用RescaleIntercept,RescaleSlope来将这个偏移量在center和width中抵消
2、上述的程序中
center=metadata.WindowCenter(i)/metadata.RescaleSlope - metadata.RescaleIntercept;
width=metadata.WindowWidth(i)/metadata.RescaleSlope - metadata.RescaleIntercept;
是使用RescaleIntercept,RescaleSlope来将这个偏移量在center和width中抵消,但是由于我的DICOM中RescaleSlope为1,所以上述式子在我的实验环境下是可以得到预期的图片,但是对于RescaleSlope为其它的值,上式正确与否暂时不知。
根据文献[1]的内容,实际的窗宽、窗位计算式为:
center=metadata.WindowCenter(i)*metadata.RescaleSlope +metadata.RescaleIntercept;
width=metadata.WindowWidth(i)*metadata.RescaleSlope + metadata.RescaleIntercept;
参考文献:
[1]吕晓琪, 范运洲. 基于 DICOM 标准的医学图像的显示方法研究[J]. 内蒙古科技大学学报, 2009, 28(004): 326-329.