Medical Imaging Interaction Toolkit  2016.11.0
Medical Imaging Interaction Toolkit
mitkToFNrrdImageWriter.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,
6 Division of Medical and Biological Informatics.
7 All rights reserved.
8 
9 This software is distributed WITHOUT ANY WARRANTY; without
10 even the implied warranty of MERCHANTABILITY or FITNESS FOR
11 A PARTICULAR PURPOSE.
12 
13 See LICENSE.txt or http://www.mitk.org for details.
14 
15 ===================================================================*/
16 // mitk includes
17 #include <mitkToFNrrdImageWriter.h>
18 
19 // itk includes
20 #include "itksys/SystemTools.hxx"
21 #include "itkNrrdImageIO.h"
22 
23 namespace mitk
24 {
25  ToFNrrdImageWriter::ToFNrrdImageWriter(): ToFImageWriter(),
26  m_DistanceOutfile(), m_AmplitudeOutfile(), m_IntensityOutfile()
27  {
28  m_Extension = std::string(".nrrd");
29  }
30 
31  ToFNrrdImageWriter::~ToFNrrdImageWriter()
32  {
33  }
34 
36  {
41 
43  this->m_ToFImageSizeInBytes = this->m_ToFPixelNumber * sizeof(float);
44 
46  this->m_RGBImageSizeInBytes = this->m_RGBPixelNumber * sizeof(unsigned char) * 3;
47 
48  if (this->m_DistanceImageSelected)
49  {
50  this->OpenStreamFile( this->m_DistanceOutfile, this->m_DistanceImageFileName);
51  }
52  if (this->m_AmplitudeImageSelected)
53  {
54  this->OpenStreamFile(this->m_AmplitudeOutfile, this->m_AmplitudeImageFileName);
55  }
56  if (this->m_IntensityImageSelected)
57  {
58  this->OpenStreamFile(this->m_IntensityOutfile, this->m_IntensityImageFileName);
59  }
60  if (this->m_RGBImageSelected)
61  {
62  this->OpenStreamFile(this->m_RGBOutfile, this->m_RGBImageFileName);
63  }
64  this->m_NumOfFrames = 0;
65  }
66 
68  {
69  if (this->m_DistanceImageSelected)
70  {
71  this->CloseStreamFile(this->m_DistanceOutfile, this->m_DistanceImageFileName);
72  }
73  if (this->m_AmplitudeImageSelected)
74  {
75  this->CloseStreamFile(this->m_AmplitudeOutfile, this->m_AmplitudeImageFileName);
76  }
77  if (this->m_IntensityImageSelected)
78  {
79  this->CloseStreamFile(this->m_IntensityOutfile, this->m_IntensityImageFileName);
80  }
81  if (this->m_RGBImageSelected)
82  {
83  this->CloseStreamFile(this->m_RGBOutfile, this->m_RGBImageFileName);
84  }
85  }
86 
87  void ToFNrrdImageWriter::Add(float* distanceFloatData, float* amplitudeFloatData, float* intensityFloatData, unsigned char* rgbData)
88  {
89  if (this->m_DistanceImageSelected)
90  {
91  this->m_DistanceOutfile.write( (char*) distanceFloatData, this->m_ToFImageSizeInBytes);
92  }
93  if (this->m_AmplitudeImageSelected)
94  {
95  this->m_AmplitudeOutfile.write( (char*)amplitudeFloatData, this->m_ToFImageSizeInBytes);
96  }
97  if (this->m_IntensityImageSelected)
98  {
99  this->m_IntensityOutfile.write(( char* )intensityFloatData, this->m_ToFImageSizeInBytes);
100  }
101  if (this->m_RGBImageSelected)
102  {
103  this->m_RGBOutfile.write(( char* )rgbData, this->m_RGBImageSizeInBytes);
104  }
105  this->m_NumOfFrames++;
106  }
107 
108  void ToFNrrdImageWriter::OpenStreamFile( std::ofstream &outfile, std::string outfileName )
109  {
110  outfile.open(outfileName.c_str(), std::ofstream::binary);
111  if(!outfile.is_open())
112  {
113  MITK_ERROR << "Error opening outfile: " << outfileName;
114  throw std::logic_error("Error opening outfile.");
115  return;
116  }
117  }
118 
119  void ToFNrrdImageWriter::CloseStreamFile( std::ofstream &outfile, std::string fileName )
120  {
121  if (this->m_NumOfFrames == 0)
122  {
123  outfile.close();
124  throw std::logic_error("File is empty.");
125  return;
126  }
127 
128  // flush the last data to the file and convert the stream data to nrrd file
129  outfile.flush();
130  this->ConvertStreamToNrrdFormat( fileName );
131  outfile.close();
132  }
133 
134  void ToFNrrdImageWriter::ConvertStreamToNrrdFormat( std::string fileName )
135  {
136  int CaptureWidth = 0;
137  int CaptureHeight = 0;
138  int PixelNumber = 0;
139  int ImageSizeInBytes = 0;
140  if (fileName==this->m_RGBImageFileName)
141  {
142  CaptureWidth = this->m_RGBCaptureWidth;
143  CaptureHeight = this->m_RGBCaptureHeight;
144  PixelNumber = this->m_RGBPixelNumber;
145  ImageSizeInBytes = this->m_RGBImageSizeInBytes;
146  } else
147  {
148  CaptureWidth = this->m_ToFCaptureWidth;
149  CaptureHeight = this->m_ToFCaptureHeight;
150  PixelNumber = this->m_ToFPixelNumber;
151  ImageSizeInBytes = this->m_ToFImageSizeInBytes;
152  }
153  Image::Pointer imageTemplate = Image::New();
154  int dimension ;
155  unsigned int* dimensions;
157  {
158  dimension = 4;
159  dimensions = new unsigned int[dimension];
160  dimensions[0] = CaptureWidth;
161  dimensions[1] = CaptureHeight;
162  dimensions[2] = 1;
163  dimensions[3] = this->m_NumOfFrames;
164  }
165  else if( m_ToFImageType == ToFImageType3D)
166  {
167  dimension = 3;
168  dimensions = new unsigned int[dimension];
169  dimensions[0] = CaptureWidth;
170  dimensions[1] = CaptureHeight;
171  dimensions[2] = this->m_NumOfFrames;
172  }
173  else
174  {
175  throw std::logic_error("No image type set, please choose between 2D+t and 3D!");
176  }
177  float* floatData;
178  unsigned char* rgbData;
179  if (fileName==this->m_RGBImageFileName)
180  {
181  rgbData = new unsigned char[PixelNumber*3];
182  for(int i=0; i<PixelNumber*3; i++)
183  {
184  rgbData[i] = i + 0.0;
185  }
186  mitk::PixelType RGBType = MakePixelType<unsigned char, itk::RGBPixel<unsigned char>, 3>();
187  imageTemplate->Initialize( RGBType,dimension, dimensions, 1);
188  imageTemplate->SetSlice(rgbData, 0, 0, 0);
189  }
190  else
191  {
192  floatData = new float[PixelNumber];
193  for(int i=0; i<PixelNumber; i++)
194  {
195  floatData[i] = i + 0.0;
196  }
197  mitk::PixelType FloatType = MakeScalarPixelType<float>();
198  imageTemplate->Initialize( FloatType,dimension, dimensions, 1);
199  imageTemplate->SetSlice(floatData, 0, 0, 0);
200  }
201 
203  nrrdWriter->SetNumberOfDimensions(dimension);
204  nrrdWriter->SetPixelType( imageTemplate->GetPixelType().GetPixelType());
205  nrrdWriter->SetComponentType( (itk::ImageIOBase::IOComponentType) imageTemplate->GetPixelType().GetComponentType());
206  if(imageTemplate->GetPixelType().GetNumberOfComponents() > 1)
207  {
208  nrrdWriter->SetNumberOfComponents(imageTemplate->GetPixelType().GetNumberOfComponents());
209  }
210 
211  itk::ImageIORegion ioRegion( dimension );
212  mitk::Vector3D spacing = imageTemplate->GetGeometry()->GetSpacing();
213  mitk::Point3D origin = imageTemplate->GetGeometry()->GetOrigin();
214 
215  for(unsigned int i = 0; i < dimension; i++)
216  {
217  nrrdWriter->SetDimensions(i,dimensions[i]);
218  nrrdWriter->SetSpacing(i,spacing[i]);
219  nrrdWriter->SetOrigin(i,origin[i]);
220 
221  mitk::Vector3D direction;
222  direction.Set_vnl_vector(imageTemplate->GetGeometry()->GetIndexToWorldTransform()->GetMatrix().GetVnlMatrix().get_column(i));
223  vnl_vector< double > axisDirection(dimension);
224 
225  for(unsigned int j = 0; j < dimension; j++)
226  {
227  axisDirection[j] = direction[j]/spacing[i];
228  }
229  nrrdWriter->SetDirection( i, axisDirection );
230 
231  ioRegion.SetSize(i, imageTemplate->GetLargestPossibleRegion().GetSize(i) );
232  ioRegion.SetIndex(i, imageTemplate->GetLargestPossibleRegion().GetIndex(i) );
233  }
234 
235  nrrdWriter->SetIORegion(ioRegion);
236  nrrdWriter->SetFileName(fileName);
237  nrrdWriter->SetUseStreamedWriting(true);
238 
239  std::ifstream stream(fileName.c_str(), std::ifstream::binary);
240  if (fileName==m_RGBImageFileName)
241  {
242  unsigned int size = PixelNumber*3 * this->m_NumOfFrames;
243  unsigned int sizeInBytes = size * sizeof(unsigned char);
244  unsigned char* data = new unsigned char[size];
245  stream.read((char*)data, sizeInBytes);
246  nrrdWriter->Write(data);
247  stream.close();
248  delete[] data;
249  }
250  else
251  {
252  unsigned int size = PixelNumber * this->m_NumOfFrames;
253  unsigned int sizeInBytes = size * sizeof(float);
254  float* data = new float[size];
255  stream.read((char*)data, sizeInBytes);
256  try
257  {
258  nrrdWriter->Write(data);
259  }
260  catch (itk::ExceptionObject* e)
261  {
262  MITK_ERROR<< e->what();
263  return;
264  }
265 
266  stream.close();
267  delete[] data;
268  }
269 
270  delete[] dimensions;
271  if (fileName==m_RGBImageFileName)
272  {
273  delete[] rgbData;
274  }
275  else
276  {
277  delete[] floatData;
278  }
279  }
280 
281 } // end namespace mitk
itk::SmartPointer< Self > Pointer
std::ofstream m_RGBOutfile
file for intensity image
int m_RGBImageSizeInBytes
size of the image to save in bytes
bool m_AmplitudeImageSelected
flag indicating if amplitude image should be recorded
int m_NumOfFrames
number of frames written to the image. Used for pic header.
bool m_IntensityImageSelected
flag indicating if intensity image should be recorded
void CheckForFileExtension(std::string &fileName)
Checks file name if file extension exists. If not an error message is returned.
#define MITK_ERROR
Definition: mitkLogMacros.h:24
bool m_DistanceImageSelected
flag indicating if distance image should be recorded
itk::SmartPointer< Self > Pointer
Definition: mitkImage.h:88
DataCollection - Class to facilitate loading/accessing structured data.
void Add(float *distanceFloatData, float *amplitudeFloatData, float *intensityFloatData, unsigned char *rgbData=0) override
Add new data to file.
int m_RGBPixelNumber
number of pixels (widht*height) of the images to record
int m_ToFCaptureWidth
width (x-dimension) of the images to record.
int m_ToFCaptureHeight
height (y-dimension) of the images to record.
int m_RGBCaptureHeight
height (y-dimension) of the images to record.
std::string m_IntensityImageFileName
file name for saving the intensity image
bool m_RGBImageSelected
flag indicating if RGB image should be recorded
std::string m_AmplitudeImageFileName
file name for saving the amplitude image
int m_ToFPixelNumber
number of pixels (widht*height) of the images to record
std::string m_Extension
file extension used for saving images
std::string m_DistanceImageFileName
file name for saving the distance image
std::ofstream m_DistanceOutfile
file for distance image
std::ofstream m_IntensityOutfile
file for intensity image
static Pointer New()
std::ofstream m_AmplitudeOutfile
file for amplitude image
int m_ToFImageSizeInBytes
size of the image to save in bytes
std::string m_RGBImageFileName
file name for saving the RGB image
ToFImageWriter::ToFImageType m_ToFImageType
type of image to be recorded: ToFImageType3D (0) or ToFImageType2DPlusT (1)
int m_RGBCaptureWidth
width (x-dimension) of the images to record.
void Close() override
Close file(s) add .pic header and write.
Class for defining the data type of pixels.
Definition: mitkPixelType.h:55
void Open() override
Open file(s) for writing.
static itkEventMacro(BoundingShapeInteractionEvent, itk::AnyEvent) class MITKBOUNDINGSHAPE_EXPORT BoundingShapeInteractor Pointer New()
Basic interaction methods for mitk::GeometryData.