Medical Imaging Interaction Toolkit  2018.4.99-389bf124
Medical Imaging Interaction Toolkit
mitkItkPictureWrite.cpp
Go to the documentation of this file.
1 /*============================================================================
2 
3 The Medical Imaging Interaction Toolkit (MITK)
4 
5 Copyright (c) German Cancer Research Center (DKFZ)
6 All rights reserved.
7 
8 Use of this source code is governed by a 3-clause BSD license that can be
9 found in the LICENSE file.
10 
11 ============================================================================*/
12 
13 #include <MitkLegacyIOExports.h>
14 
15 #include "mitkItkPictureWrite.h"
17 
18 #include <itkImageSeriesWriter.h>
19 #include <itkNumericSeriesFileNames.h>
20 #include <itkRescaleIntensityImageFilter.h>
21 
22 #include <itkRGBAPixel.h>
23 
25 template <class WriterType>
26 void SetOutputNames(typename WriterType::Pointer writer, const std::string &baseFileName, unsigned int numberOfImages)
27 {
28  if (numberOfImages > 1)
29  {
30  itk::NumericSeriesFileNames::Pointer numericFileNameWriter = itk::NumericSeriesFileNames::New();
31 
32  std::string finalFileName = baseFileName;
33  std::string::size_type pos = baseFileName.find_last_of(".", baseFileName.length() - 1);
34  if (pos == std::string::npos)
35  finalFileName.append(".%d.png");
36  else
37  finalFileName.insert(pos, ".%d");
38 
39  MITK_DEBUG << "Filename: " << finalFileName;
40 
41  numericFileNameWriter->SetEndIndex(numberOfImages);
42  numericFileNameWriter->SetSeriesFormat(finalFileName.c_str());
43  numericFileNameWriter->Modified();
44  writer->SetFileNames(numericFileNameWriter->GetFileNames());
45  }
46  // if the given image is an 2D-png image, do not use the numericFileNameWriter
47  // to generate the name, since it alters the fileName given as parameter
48  else
49  {
50  writer->SetFileName(baseFileName.c_str());
51  }
52 }
53 
54 template <typename TPixel, unsigned int VImageDimension>
55 void _mitkItkPictureWrite(itk::Image<TPixel, VImageDimension> *itkImage, const std::string &fileName)
56 {
57  typedef itk::Image<TPixel, VImageDimension> TImageType;
58 
59  typedef itk::Image<unsigned char, 3> UCharOutputImage3DType;
60  typedef itk::Image<unsigned short, 3> ShortOutputImage3DType;
61  typedef itk::Image<unsigned char, 2> OutputImage2D_8bitType;
62  typedef itk::Image<unsigned short, 2> OutputImage2D_16bitType;
63 
64  typedef itk::ImageSeriesWriter<UCharOutputImage3DType, OutputImage2D_8bitType> UCharWriterType;
65  typedef itk::ImageSeriesWriter<ShortOutputImage3DType, OutputImage2D_16bitType> ShortWriterType;
66 
67  typedef itk::RescaleIntensityImageFilter<TImageType, UCharOutputImage3DType> UCharRescalerFilterType;
68  typedef itk::RescaleIntensityImageFilter<TImageType, ShortOutputImage3DType> ShortRescalerFilterType;
69 
70  // get the size info
71  size_t inputTypeSize = sizeof(TPixel);
72  size_t supportedOutputMaxSize = 1; // default value 8bit
73 
74  // the PNG and TIFF formats can handle up-to 16-bit images
75  if (fileName.find(".png") != std::string::npos || fileName.find(".tif") != std::string::npos)
76  {
77  supportedOutputMaxSize = 2;
78  }
79 
80  // get the dimension info
81  unsigned int numberOfImages = 1;
82  if (itkImage->GetImageDimension() > 2)
83  numberOfImages = itkImage->GetLargestPossibleRegion().GetSize()[2];
84 
85  typename ShortRescalerFilterType::Pointer sh_rescaler = ShortRescalerFilterType::New();
86  sh_rescaler->SetInput(itkImage);
87  sh_rescaler->SetOutputMinimum(0);
88  sh_rescaler->SetOutputMaximum(65535);
89 
90  typename UCharRescalerFilterType::Pointer rescaler = UCharRescalerFilterType::New();
91  rescaler->SetInput(itkImage);
92  rescaler->SetOutputMinimum(0);
93  rescaler->SetOutputMaximum(255);
94 
95  try
96  {
97  // input is 8 bit
98  if (inputTypeSize == 1)
99  {
100  UCharWriterType::Pointer writer = UCharWriterType::New();
101  SetOutputNames<UCharWriterType>(writer, fileName, numberOfImages);
102  writer->SetInput(rescaler->GetOutput());
103  writer->Update();
104  }
105  // input pixel type is 16bit -> writer can handle 16bit images
106  else if (inputTypeSize == supportedOutputMaxSize && supportedOutputMaxSize == 2)
107  {
108  ShortWriterType::Pointer writer = ShortWriterType::New();
109  SetOutputNames<ShortWriterType>(writer, fileName, numberOfImages);
110  writer->SetInput(sh_rescaler->GetOutput());
111  writer->Update();
112  }
113  // rescaling input to maximum of supported format
114  else
115  {
116  if (supportedOutputMaxSize == 2)
117  {
118  typename ShortWriterType::Pointer writer = ShortWriterType::New();
119  SetOutputNames<ShortWriterType>(writer, fileName, numberOfImages);
120  writer->SetInput(sh_rescaler->GetOutput());
121  writer->Update();
122  }
123  else
124  {
125  typename UCharWriterType::Pointer writer = UCharWriterType::New();
126  SetOutputNames<UCharWriterType>(writer, fileName, numberOfImages);
127  writer->SetInput(rescaler->GetOutput());
128  writer->Update();
129  }
130  }
131  }
132  catch (const itk::ExceptionObject &e)
133  {
134  MITK_ERROR << "ITK Exception occured: " << e.what();
135  mitkThrow() << "Caught ITK exception while writing image with scalar type \n" << e.what();
136  }
137 }
138 
139 template <typename TPixel, unsigned int VImageDimension>
140 void _mitkItkPictureWriteComposite(itk::Image<TPixel, VImageDimension> *itkImage, const std::string &fileName)
141 {
142  typedef itk::Image<TPixel, VImageDimension> TImageType;
143  typedef itk::Image<TPixel, 2> TImageType2D;
144 
145  typedef itk::ImageSeriesWriter<TImageType, TImageType2D> WriterType;
146  typename WriterType::Pointer writer = WriterType::New();
147 
148  // get the dimension info
149  unsigned int numberOfImages = 1;
150  if (itkImage->GetImageDimension() > 2)
151  numberOfImages = itkImage->GetLargestPossibleRegion().GetSize()[2];
152 
153  // create output name(s)
154  SetOutputNames<WriterType>(writer, fileName, numberOfImages);
155 
156  writer->SetInput(itkImage);
157  try
158  {
159  writer->Update();
160  }
161  catch (const itk::ExceptionObject &e)
162  {
163  MITK_ERROR << "ITK Exception occured: " << e.what();
164  mitkThrow() << "Caught ITK exception while writing image with composite type \n" << e.what();
165  }
166 }
167 
168 #define InstantiateAccessFunction__mitkItkPictureWrite(pixelType, dim) \
169  template MITKLEGACYIO_EXPORT void _mitkItkPictureWrite(itk::Image<pixelType, dim> *, const std::string &);
170 
171 #define InstantiateAccessFunction__mitkItkPictureWriteComposite(pixelType, dim) \
172  template MITKLEGACYIO_EXPORT void _mitkItkPictureWriteComposite(itk::Image<pixelType, dim> *, const std::string &);
173 
175 
void SetOutputNames(typename WriterType::Pointer writer, const std::string &baseFileName, unsigned int numberOfImages)
InstantiateAccessFunction(_mitkItkPictureWrite) InstantiateAccessFunctionForFixedPixelType(_mitkItkPictureWriteComposite
#define MITK_ERROR
Definition: mitkLogMacros.h:20
#define MITK_ACCESSBYITK_PIXEL_TYPES_SEQ
Definition: mitkConfig.h:26
#define MITK_DEBUG
Definition: mitkLogMacros.h:22
InstantiateAccessFunctionForFixedPixelType(AccessItkImage,(float)(double)) InstantiateAccessFunctionForIntegralPixelTypes(AccessItkImage) int mitkInstantiateAccessFunctionTest(int
#define mitkThrow()
void _mitkItkPictureWriteComposite(itk::Image< TPixel, VImageDimension > *itkImage, const std::string &fileName)
ITK-Like method to be called for writing an image.
void _mitkItkPictureWrite(itk::Image< TPixel, VImageDimension > *itkImage, const std::string &fileName)
ITK-Like method to be called for writing an single-component image using the AccessByItk Macros...
#define MITK_ACCESSBYITK_COMPOSITE_PIXEL_TYPES_SEQ
Definition: mitkConfig.h:24