DICOMDIR结构分析与实现

无论是在DICOM文件还是DICOM通信中,其信息都是由许多data element(数据单元)的集合所表示,每个data element表示一个属性,如病人姓名、图像类型等等。这些data element按照Tag值从小到大依次连接,类似于数据结构的链表或者数组(SQ类型有另外的编码方式,以后会讲到),请看下图,一个data element包含四个字段Tag,VR,ValueLength,Value Field.

 

DICOMDIR 是一个可变长度 迷你 database 文件。由 group (0002, xxxx) 和 group (0004, xxxx) 为主题。描述的是一个 4 层的树状结构 (tree structure)。

1. Patient
2. Study
3. Series
4. Image

 

 

将data element的数据结构编码为字节流时受以下几个因素影响:

1.传输语法: Implicit/Explicit VR,      BIG/LITTLE Endian

2.VR

当采用implicit VR时,其编码如下,这个时候是没有VR字段的,它采用data dictionary默认的VR.

 

 

DICOMDIR结构分析与实现

DICOMDIR结构分析与实现

 

DICOMDIR结构分析与实现

DICOMDir结构的delphi实现:

  1 ///////////////////////////////////////////////////////////////////////////////

  2 //

  3 // Filename: uDICOMDIR.pas

  4 //

  5 // Summary:

  6 //    DicomStation Source With Delphi7

  7 //

  8 // Modification History:

  9 //    Date         By       Summary

 10 //    --------     -------- ---------------------------------------------

 11 //    07/24/2011   hegb     Original Creation

 12 ///////////////////////////////////////////////////////////////////////////////

 13 unit uDICOMDIR;

 14 

 15 interface

 16 

 17 uses

 18   Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,

 19   Dialogs, StdCtrls;

 20 

 21 type

 22   //Instance Class

 23   TImageItem = class(TObject)

 24     NextDirRecordOffset: LongWord; //(0004,1400)

 25     RecordInUseFlag: Word; //(0004,1410)

 26     LowerLevelDirOffset: LongWord; //(0004,1420)

 27     DirRecordType: string; //(0004,1430)

 28     ReferenceFileID: string; //(0004,1500)

 29     ReferenceTransSyntaxUID: string; //(0004,1512)

 30     InstanceNumber: string; //(0020,0013)

 31   public

 32     constructor Create;

 33     destructor Destroy; override;

 34   end;

 35 

 36   //Series Class

 37   TSeriesItem = class(TObject)

 38     NextDirRecordOffset: LongWord; //(0004,1400)

 39     RecordInUseFlag: Word; //(0004,1410)

 40     LowerLevelDirOffset: LongWord; //(0004,1420)

 41     DirRecordType: string; //(0004,1430)

 42     Modality: string; //(0008,0060)

 43     SeriesInstanceUID: string; //(0020,000E)

 44     SeriesNumber: string; //(0020,0011)

 45   private

 46     ImageList: TList; //Image for this Series

 47   public

 48     procedure AddImage(pImage: TImageItem);

 49 

 50     constructor Create;

 51     destructor Destroy; override;

 52   end;

 53 

 54   //Study Class

 55   TStudyItem = class(TObject)

 56     NextDirRecordOffset: LongWord; //(0004,1400)

 57     RecordInUseFlag: Word; //(0004,1410)

 58     LowerLevelDirOffset: LongWord; //(0004,1420)

 59     DirRecordType: string; //(0004,1430)

 60     StudyDate: string; //(0008,0020)

 61     StudyTime: string; //(0008,0030)

 62     AccessionNumber: string; //(0008, 0005) /////////(0008,0050) ===== SH

 63     StudyInstanceUID: string; //(0020,000D)

 64     StudyID: string; //(0020,0010)

 65   private

 66     SeriesList: TList; //Series for this Study

 67   public

 68     procedure AddSeries(pSeries: TSeriesItem);

 69 

 70     constructor Create;

 71     destructor Destroy; override;

 72   end;

 73 

 74   //Patient Structure

 75   TPatientItem = class(TObject)

 76     NextDirRecordOffset: LongWord; //(0004,1400)

 77     RecordInUseFlag: Word; //(0004,1410)

 78     LowerLevelDirOffset: LongWord; //(0004,1420)

 79     DirRecordType: string; //(0004,1430)

 80     PatientName: string; //(0010,0010)

 81     PatientID: string; //(0010,0020)

 82   private

 83     StudyList: TList; //Study for this Patient

 84   public

 85     procedure AddStudy(pStudy: TStudyItem);

 86 

 87     constructor Create;

 88     destructor Destroy; override;

 89   end;

 90 

 91   //DicomDir Class

 92   TDicomDir =  class(TObject)

 93     GroupLength: LongWord; //(0002,0000)

 94     FileMetaVersion: string[2];  //(0002,0001)        ====OB====

 95     MediaSOPClassUID: string;  //(0002,0002)

 96     MediaSOPInstanceUID: string;  //(0002,0003)

 97     TransferSyntaxUID: string;  //(0002,0010)

 98     ImplementClassUID: string;  //(0002,0012)

 99     ImplementVersionName: string; //(0002,0013)

100     FilesetID: string; //(0004,1130)

101     RootDirFistRecord: LongWord; //(0004,1200)

102     RootDirLastRecord: LongWord; //(0004,1202)

103     FileSetConsFlag: Word;   //(0004,1212)

104     DirRecordSequence: LongWord; //(0004,1220)     ====SQ====

105     SOPClassUID: string; //(0008, 0016)

106   private

107     PatientList: TList; //Patient for DICOMDIR

108   public

109     procedure AddPatient(pPatient: TPatientItem);

110     procedure ClearPatient;

111 

112     function WriteDicomDir(FilePath: string): Boolean;

113     constructor Create;

114     destructor Destroy; override;

115   end;

116 

117 function GetEvenStr(const str: string): string;

118 

119 var

120   g_pDICOMDIR: TDicomDir;

121 

122 implementation

123 

124 const

125   GroupTagLen = 2;   //Group Number -- 2bytes

126   ElementTagLen = 2; //Element Number -- 2bytes

127 //  VR2 = 2;           //Explicit VR时,如果VR = OB,OW,OF,SQ,UT,UN时,VR占用2字节

128 //  VR4 = 4;           //Explicit VR时,如果VR <> OB,OW,OF,SQ,UT,UN时,VR占用4字节

129 //  VR_Len2 = 2;       //Explicit VR时,如果VR = OB,OW,OF,SQ,UT,UN时,Value Length占用2字节

130 //  VR_Len4 = 4;       //Explicit VR时,如果VR <> OB,OW,OF,SQ,UT,UN时,Value Length占用4字节

131 

132 var

133   DICOM_signature: array[0..131] of byte =

134     (

135        0, 0, 0 , 0, 0, 0, 0 , 0, 0, 0, 0 , 0, 0, 0, 0 , 0,

136        0, 0, 0 , 0, 0, 0, 0 , 0, 0, 0, 0 , 0, 0, 0, 0 , 0,

137        0, 0, 0 , 0, 0, 0, 0 , 0, 0, 0, 0 , 0, 0, 0, 0 , 0,

138        0, 0, 0 , 0, 0, 0, 0 , 0, 0, 0, 0 , 0, 0, 0, 0 , 0,

139        0, 0, 0 , 0, 0, 0, 0 , 0, 0, 0, 0 , 0, 0, 0, 0 , 0,

140        0, 0, 0 , 0, 0, 0, 0 , 0, 0, 0, 0 , 0, 0, 0, 0 , 0,

141        0, 0, 0 , 0, 0, 0, 0 , 0, 0, 0, 0 , 0, 0, 0, 0 , 0,

142        0, 0, 0 , 0, 0, 0, 0 , 0, 0, 0, 0 , 0, 0, 0, 0 , 0,

143        68, 73, 67 , 77

144     );

145 

146   VR_Reserved: array[0..1] of Byte = (0, 0); 

147 

148   ItemBegin_Group: Word = $FFFE;

149   ItemBegin_Element: Word = $E000;

150   ItemEnd_Group: Word = $FFFE;

151   ItemEnd_Element: Word = $E00D;

152   ItemEnd_Sequence: Word = $E0DD;

153 

154   ItemBegin_Value: LongWord = $FFFFFFFF;

155   ItemEnd_Value: LongWord = $00000000;

156 

157   iOffSet: LongWord = 0; 

158 

159 procedure WriteDicomDir;

160 begin

161 end;

162 

163 function SwapLong(Value: Cardinal): Cardinal;

164 asm

165   BSWAP EAX

166 end;

167 

168 function GetEvenStr(const str: string): string;

169 begin

170   if Length(str) mod 2 <> 0 then

171     Result := str + Char(0)

172   else

173     Result := str;

174 end;

 

你可能感兴趣的:(DICOM)