Medical Imaging Interaction Toolkit  2016.11.0
Medical Imaging Interaction Toolkit
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
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.