File: DicomImageReadPrintTags.cxx

package info (click to toggle)
insighttoolkit4 4.13.3withdata-dfsg1-4
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 489,260 kB
  • sloc: cpp: 557,342; ansic: 146,850; fortran: 34,788; python: 16,572; sh: 2,187; lisp: 2,070; tcl: 993; java: 362; perl: 200; makefile: 129; csh: 81; pascal: 69; xml: 19; ruby: 10
file content (375 lines) | stat: -rw-r--r-- 11,856 bytes parent folder | download | duplicates (5)
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
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
/*=========================================================================
 *
 *  Copyright Insight Software Consortium
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0.txt
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 *=========================================================================*/

//  Software Guide : BeginLatex
//
//  It is often valuable to be able to query the entries from the header of a
//  DICOM file. This can be used for consistency checking, or simply for
//  verifying that we have the correct dataset in our hands.  This example
//  illustrates how to read a DICOM file and then print out most of the DICOM
//  header information. The binary fields of the DICOM header are skipped.
//
//  \index{DICOM!Header}
//  \index{DICOM!Tags}
//  \index{DICOM!Printing Tags}
//  \index{DICOM!Dictionary}
//  \index{DICOM!GDCM}
//  \index{GDCM!Dictionary}
//
//  Software Guide : EndLatex

// Software Guide : BeginLatex
//
// The headers of the main classes involved in this example are specified
// below. They include the image file reader, the GDCMImageIO object, the
// MetaDataDictionary and its entry element, the MetaDataObject.
//
// \index{MetaDataDictionary!header}
// \index{MetaDataObject!header}
// \index{GDCMImageIO!header}
//
// Software Guide : EndLatex

// Software Guide : BeginCodeSnippet
#include "itkImageFileReader.h"
#include "itkGDCMImageIO.h"
#include "itkMetaDataObject.h"
// Software Guide : EndCodeSnippet

#include "gdcmGlobal.h"

// Software Guide : BeginLatex
// Software Guide : EndLatex

int main( int argc, char* argv[] )
{
  if( argc < 2 )
    {
    std::cerr << "Usage: " << argv[0] << " DicomFile [user defined dict]" << std::endl;
    return EXIT_FAILURE;
    }

  // Software Guide : BeginLatex
  //
  //  We instantiate the type to be used for storing the image once it is read
  //  into memory.
  //
  // Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  typedef signed short       PixelType;
  const unsigned int         Dimension = 2;

  typedef itk::Image< PixelType, Dimension >      ImageType;
  // Software Guide : EndCodeSnippet


  if( argc == 3 )
    {
    // Specify a path where XML dicts can be found (Part 3/4 & 6)
    gdcm::Global::GetInstance().Prepend( itksys::SystemTools::GetFilenamePath(argv[2]).c_str() );
    // Load them !
    gdcm::Global::GetInstance().LoadResourcesFiles();
    }

  // Software Guide : BeginLatex
  //
  // Using the image type as a template parameter we instantiate the type of the
  // image file reader and construct one instance of it.
  //
  // Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  typedef itk::ImageFileReader< ImageType >     ReaderType;

  ReaderType::Pointer reader = ReaderType::New();
  // Software Guide : EndCodeSnippet

  // Software Guide : BeginLatex
  //
  // The GDCM image IO type is declared and used for constructing one image IO
  // object.
  //
  // Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  typedef itk::GDCMImageIO       ImageIOType;
  ImageIOType::Pointer dicomIO = ImageIOType::New();
  // Software Guide : EndCodeSnippet

  // Software Guide : BeginLatex
  //
  // We pass to the reader the filename of the image to be read and connect the
  // ImageIO object to it too.
  //
  // Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  reader->SetFileName( argv[1] );
  reader->SetImageIO( dicomIO );
  // Software Guide : EndCodeSnippet

  // Software Guide : BeginLatex
  //
  // The reading process is triggered with a call to the \code{Update()} method.
  // This call should be placed inside a \code{try/catch} block because its
  // execution may result in exceptions being thrown.
  //
  // Software Guide : EndLatex

  try
    {
    // Software Guide : BeginCodeSnippet
    reader->Update();
    // Software Guide : EndCodeSnippet
    }
  catch (itk::ExceptionObject &ex)
    {
    std::cout << ex << std::endl;
    return EXIT_FAILURE;
    }

  // Software Guide : BeginLatex
  //
  // Now that the image has been read, we obtain the MetaDataDictionary from
  // the ImageIO object using the \code{GetMetaDataDictionary()} method.
  //
  // \index{MetaDataDictionary}
  // \index{GetMetaDataDictionary()!ImageIOBase}
  // \index{ImageIOBase!GetMetaDataDictionary()}
  //
  // Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  typedef itk::MetaDataDictionary   DictionaryType;

  const  DictionaryType & dictionary = dicomIO->GetMetaDataDictionary();
  // Software Guide : EndCodeSnippet

  // Software Guide : BeginLatex
  //
  // Since we are interested only in the DICOM tags that can be expressed in
  // strings, we declare a MetaDataObject suitable for managing strings.
  //
  // Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  typedef itk::MetaDataObject< std::string > MetaDataStringType;
  // Software Guide : EndCodeSnippet

  // Software Guide : BeginLatex
  //
  // We instantiate the iterators that will make possible to walk through all the
  // entries of the MetaDataDictionary.
  //
  // Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  DictionaryType::ConstIterator itr = dictionary.Begin();
  DictionaryType::ConstIterator end = dictionary.End();
  // Software Guide : EndCodeSnippet

  //  Software Guide : BeginLatex
  //
  // For each one of the entries in the dictionary, we check first if its element
  // can be converted to a string, a \code{dynamic\_cast} is used for this purpose.
  //
  //  Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  while( itr != end )
    {
    itk::MetaDataObjectBase::Pointer  entry = itr->second;

    MetaDataStringType::Pointer entryvalue =
      dynamic_cast<MetaDataStringType *>( entry.GetPointer() );
    // Software Guide : EndCodeSnippet


    // Software Guide : BeginLatex
    //
    // For those entries that can be converted, we take their DICOM tag and pass
    // it to the \code{GetLabelFromTag()} method of the GDCMImageIO class. This
    // method checks the DICOM dictionary and returns the string label
    // associated with the tag that we are providing in the \code{tagkey}
    // variable. If the label is found, it is returned in \code{labelId}
    // variable. The method itself returns false if the tagkey is not found in
    // the dictionary.  For example "$0010|0010$" in \code{tagkey} becomes
    // "Patient's Name" in \code{labelId}.
    //
    // Software Guide : EndLatex

    // Software Guide : BeginCodeSnippet
    if( entryvalue )
      {
      std::string tagkey   = itr->first;
      std::string labelId;
      bool found =  itk::GDCMImageIO::GetLabelFromTag( tagkey, labelId );
      // Software Guide : EndCodeSnippet

      // Software Guide : BeginLatex
      //
      // The actual value of the dictionary entry is obtained as a string with the
      // \code{GetMetaDataObjectValue()} method.
      //
      // \index{MetaDataObject!GetMetaDataObjectValue()}
      //
      // Software Guide : EndLatex

      // Software Guide : BeginCodeSnippet
      std::string tagvalue = entryvalue->GetMetaDataObjectValue();
      // Software Guide : EndCodeSnippet

      // Software Guide : BeginLatex
      //
      // At this point we can print out an entry by concatenating the DICOM Name or
      // label, the numeric tag and its actual value.
      //
      // Software Guide : EndLatex

      // Software Guide : BeginCodeSnippet
      if( found )
        {
        std::cout << "(" << tagkey << ") " << labelId;
        std::cout << " = " << tagvalue.c_str() << std::endl;
        }
      // Software Guide : EndCodeSnippet
      else
        {
        std::cout << "(" << tagkey <<  ") " << "Unknown";
        std::cout << " = " << tagvalue.c_str() << std::endl;
        }
      }

    // Software Guide : BeginLatex
    //
    // Finally we just close the loop that will walk through all the Dictionary
    // entries.
    //
    // Software Guide : EndLatex

    // Software Guide : BeginCodeSnippet
    ++itr;
    }
  // Software Guide : EndCodeSnippet

  //  Software Guide : BeginLatex
  //
  //  It is also possible to read a specific tag. In that case the string of the
  //  entry can be used for querying the MetaDataDictionary.
  //
  //  Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  std::string entryId = "0010|0010";
    DictionaryType::ConstIterator tagItr = dictionary.Find( entryId );
  // Software Guide : EndCodeSnippet
  // Software Guide : BeginLatex
  //
  // If the entry is actually found in the Dictionary, then we can attempt to
  // convert it to a string entry by using a \code{dynamic\_cast}.
  //
  // Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  if( tagItr != end )
    {
    MetaDataStringType::ConstPointer entryvalue =
     dynamic_cast<const MetaDataStringType *>(
                                 tagItr->second.GetPointer() );
    // Software Guide : EndCodeSnippet


    // Software Guide : BeginLatex
    //
    // If the dynamic cast succeeds, then we can print out the values of the label,
    // the tag and the actual value.
    //
    // Software Guide : EndLatex

    // Software Guide : BeginCodeSnippet
    if( entryvalue )
      {
      std::string tagvalue = entryvalue->GetMetaDataObjectValue();
      std::cout << "Patient's Name (" << entryId <<  ") ";
      std::cout << " is: " << tagvalue.c_str() << std::endl;
      }
    // Software Guide : EndCodeSnippet
    }

  // Software Guide : BeginLatex
  //
  //  Another way to read a specific tag is to use the encapsulation above
  //  MetaDataDictionary. Note that this is stricly equivalent to the above
  //  code.
  //
  // Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  std::string tagkey = "0008|1050";
  std::string labelId;
  if( itk::GDCMImageIO::GetLabelFromTag( tagkey, labelId ) )
    {
    std::string value;
    std::cout << labelId << " (" << tagkey << "): ";
    if( dicomIO->GetValueFromTag(tagkey, value) )
      {
      std::cout << value;
      }
    else
      {
      std::cout << "(No Value Found in File)";
      }
    std::cout << std::endl;
    }
  else
    {
    std::cerr << "Trying to access inexistant DICOM tag." << std::endl;
    }
  // Software Guide : EndCodeSnippet


  // Software Guide : BeginLatex
  //
  // For a full description of the DICOM dictionary please look at the file.
  //
  // \code{Insight/Utilities/gdcm/Dicts/dicomV3.dic}
  //
  // Software Guide : EndLatex

  //  Software Guide : BeginLatex
  //
  // The following piece of code will print out the proper pixel type /
  // component for instantiating an \doxygen{ImageFileReader} that can properly
  // import the printed DICOM file.
  //
  //  Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  itk::ImageIOBase::IOPixelType pixelType
                                       = reader->GetImageIO()->GetPixelType();
  itk::ImageIOBase::IOComponentType componentType
                                   = reader->GetImageIO()->GetComponentType();
  std::cout << "PixelType: " << reader->GetImageIO()
                               ->GetPixelTypeAsString(pixelType) << std::endl;
  std::cout << "Component Type: " << reader->GetImageIO()
                       ->GetComponentTypeAsString(componentType) << std::endl;
  // Software Guide : EndCodeSnippet

  return EXIT_SUCCESS;
}