diff --git a/Modules/ToFHardware/Testing/files.cmake b/Modules/ToFHardware/Testing/files.cmake index 3ce7f37e36..0998283555 100644 --- a/Modules/ToFHardware/Testing/files.cmake +++ b/Modules/ToFHardware/Testing/files.cmake @@ -1,24 +1,25 @@ SET(MODULE_TESTS mitkToFCameraMITKPlayerControllerTest.cpp mitkToFCameraMITKPlayerDeviceTest.cpp mitkToFCameraPMDCamBoardControllerTest.cpp mitkToFCameraPMDCamBoardDeviceTest.cpp mitkToFCameraPMDCamCubeControllerTest.cpp mitkToFCameraPMDCamCubeDeviceTest.cpp mitkToFCameraPMDControllerTest.cpp mitkToFCameraPMDDeviceTest.cpp mitkToFCameraPMDMITKPlayerControllerTest.cpp mitkToFCameraPMDMITKPlayerDeviceTest.cpp mitkToFCameraPMDO3ControllerTest.cpp mitkToFCameraPMDO3DeviceTest.cpp mitkToFCameraPMDPlayerControllerTest.cpp mitkToFCameraPMDPlayerDeviceTest.cpp mitkToFImageCsvWriterTest.cpp mitkToFImageGrabberTest.cpp mitkToFImageGrabberCreatorTest.cpp mitkToFImageRecorderTest.cpp mitkToFImageRecorderFilterTest.cpp mitkToFImageWriterTest.cpp + mitkToFNrrdImageWriterTest.cpp mitkToFOpenCVImageGrabberTest.cpp ) diff --git a/Modules/ToFHardware/Testing/mitkToFNrrdImageWriterTest.cpp b/Modules/ToFHardware/Testing/mitkToFNrrdImageWriterTest.cpp new file mode 100644 index 0000000000..1b9cb6a2dd --- /dev/null +++ b/Modules/ToFHardware/Testing/mitkToFNrrdImageWriterTest.cpp @@ -0,0 +1,148 @@ +/*========================================================================= + +Program: Medical Imaging & Interaction Toolkit +Module: $RCSfile$ +Language: C++ +Date: $Date: 2010-05-27 16:06:53 +0200 (Do, 27 Mai 2010) $ +Version: $Revision: $ + +Copyright (c) German Cancer Research Center, Division of Medical and +Biological Informatics. All rights reserved. +See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. + +This software is distributed WITHOUT ANY WARRANTY; without even +the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the above copyright notices for more information. + +=========================================================================*/ + +#include +#include +#include +#include +//#include +//#include + +/**Documentation + * test for the class "ToFImageWriter". + */ +int mitkToFNrrdImageWriterTest(int /* argc */, char* /*argv*/[]) +{ + MITK_TEST_BEGIN("ToFNrrdImageWriter"); + + //run the test with some unusual parameters + unsigned int dimX = 255; + unsigned int dimY = 188; + unsigned int pixelNumber = dimX*dimY; + unsigned int numOfFrames = 1; //or numberOfSlices + + //create 3 images filled with random values + mitk::Image::Pointer distanceImage = mitk::ImageGenerator::GenerateRandomImage(dimX, dimY, numOfFrames,0, 1.0f, 1.0f); + mitk::Image::Pointer amplitudeImage = mitk::ImageGenerator::GenerateRandomImage(dimX, dimY, numOfFrames,0, 1.0f, 1.0f); + mitk::Image::Pointer intensityImage = mitk::ImageGenerator::GenerateRandomImage(dimX, dimY, numOfFrames,0, 1.0f, 1.0f); + + mitk::ToFNrrdImageWriter::Pointer tofWriter = mitk::ToFNrrdImageWriter::New(); + + //file names on the disc + std::string distanceImageFileName("E:/distImg.nrrd"); + std::string amplitudeImageFileName("E:/amplImg.nrrd"); + std::string intensityImageFileName("E:/intImg.nrrd"); + + tofWriter->SetDistanceImageFileName(distanceImageFileName); + tofWriter->SetAmplitudeImageFileName(amplitudeImageFileName); + tofWriter->SetIntensityImageFileName(intensityImageFileName); + + MITK_TEST_CONDITION_REQUIRED(distanceImageFileName==tofWriter->GetDistanceImageFileName(), "Testing set/get distance image file name"); + MITK_TEST_CONDITION_REQUIRED(amplitudeImageFileName==tofWriter->GetAmplitudeImageFileName(), "Testing set/get amplitude image file name"); + MITK_TEST_CONDITION_REQUIRED(intensityImageFileName==tofWriter->GetIntensityImageFileName(), "Testing set/get intensity image file name"); + + tofWriter->SetCaptureWidth(dimX); + tofWriter->SetCaptureHeight(dimY); + + MITK_TEST_CONDITION_REQUIRED(dimX==tofWriter->GetCaptureWidth(), "Testing set/get CaptureWidth"); + MITK_TEST_CONDITION_REQUIRED(dimY==tofWriter->GetCaptureHeight(), "Testing set/get CaptureHeight"); + + tofWriter->SetToFImageType(mitk::ToFNrrdImageWriter::ToFImageType2DPlusT); + + MITK_TEST_CONDITION_REQUIRED(mitk::ToFNrrdImageWriter::ToFImageType2DPlusT==tofWriter->GetToFImageType(), "Testing set/get ToFImageType"); + + tofWriter->SetToFImageType(mitk::ToFNrrdImageWriter::ToFImageType3D); + + //buffer for each slice + float* distanceArray; + float* amplitudeArray; + float* intensityArray; + + float* distanceArrayRead; + float* amplitudeArrayRead; + float* intensityArrayRead; + + tofWriter->Open(); //open file/stream + //Note: the slices are written out reverse order, because the ToFImageWriter has to write them out immediately. + //A PicFileWriter would write them out vice versa and the PicFileWriter reads the slices vice versa. + for(unsigned int i = numOfFrames; i > 0 ; i--) + { //write values to file/stream + //The slice index is "i-1", because "for(unsigned int i = numOfFrames-1; i >= 0 ; i--)" does not work for some reason + distanceArray = (float*)distanceImage->GetSliceData(i-1, 0, 0)->GetData(); + amplitudeArray = (float*)amplitudeImage->GetSliceData(i-1, 0, 0)->GetData(); + intensityArray = (float*)intensityImage->GetSliceData(i-1, 0, 0)->GetData(); + + //write (or add) the three slices to the file + tofWriter->Add(distanceArray, amplitudeArray, intensityArray); + } + + tofWriter->Close(); //close file + + + //read in the three images from disc +// mitk::PicFileReader::Pointer fileReader = mitk::PicFileReader::New(); +// fileReader->SetFileName(distanceImageFileName); +// fileReader->Update(); +// mitk::Image::Pointer distanceImageRead = fileReader->GetOutput(); +// +// fileReader = mitk::PicFileReader::New(); +// fileReader->SetFileName(amplitudeImageFileName); +// fileReader->Update(); +// mitk::Image::Pointer amplitudeImageRead = fileReader->GetOutput(); +// +// fileReader = mitk::PicFileReader::New(); +// fileReader->SetFileName(intensityImageFileName); +// fileReader->Update(); +// mitk::Image::Pointer intensityImageRead = fileReader->GetOutput(); +// +// bool readingCorrect = true; +// // for all frames... +// for(unsigned int j=0; jGetSliceData(j, 0, 0)->GetData(); +// amplitudeArray = (float*)amplitudeImage->GetSliceData(j, 0, 0)->GetData(); +// intensityArray = (float*)intensityImage->GetSliceData(j, 0, 0)->GetData(); +// +// //data read from disc +// distanceArrayRead = (float*)distanceImageRead->GetSliceData(j, 0, 0)->GetData(); +// amplitudeArrayRead = (float*)amplitudeImageRead->GetSliceData(j, 0, 0)->GetData(); +// intensityArrayRead = (float*)intensityImageRead->GetSliceData(j, 0, 0)->GetData(); +// +// //for all pixels +//for(unsigned int i=0; i +#include +#include +#include + +// itk includes +#include "itksys/SystemTools.hxx" +#include "itkNrrdImageIO.h" + +//extern "C" +//{ +//size_t _mitkIpPicFWrite( const void *ptr, size_t size, size_t nitems, mitkIpPicFile_t stream); +//} + +namespace mitk +{ + ToFNrrdImageWriter::ToFNrrdImageWriter():m_Extension(".nrrd"), + m_DistanceOutfile(), m_AmplitudeOutfile(), m_IntensityOutfile(), + m_NumOfFrames(0), m_DistanceImageSelected(true), m_AmplitudeImageSelected(true), m_IntensityImageSelected(true), + m_CaptureWidth(200), m_CaptureHeight(200), m_PixelNumber(0), m_ImageSizeInBytes(0), + m_ToFImageType(ToFNrrdImageWriter::ToFImageType3D) + { + } + + ToFNrrdImageWriter::~ToFNrrdImageWriter() + { + } + + void ToFNrrdImageWriter::Open() + { + this->CheckForFileExtension(this->m_DistanceImageFileName); + this->CheckForFileExtension(this->m_AmplitudeImageFileName); + this->CheckForFileExtension(this->m_IntensityImageFileName); + + this->m_PixelNumber = this->m_CaptureWidth * this->m_CaptureHeight; + this->m_ImageSizeInBytes = this->m_PixelNumber * sizeof(float); + + if (this->m_DistanceImageSelected) + { + this->OpenStreamFile(this->m_DistanceOutfile, this->m_DistanceImageFileName); + } + if (this->m_AmplitudeImageSelected) + { + this->OpenStreamFile(this->m_AmplitudeOutfile, this->m_AmplitudeImageFileName); + } + if (this->m_IntensityImageSelected) + { + this->OpenStreamFile(this->m_IntensityOutfile, this->m_IntensityImageFileName); + } + this->m_NumOfFrames = 0; + } + + void ToFNrrdImageWriter::Close() + { + if (this->m_DistanceImageSelected) + { + this->CloseStreamFile(this->m_DistanceOutfile, this->m_DistanceImageFileName); + } + if (this->m_AmplitudeImageSelected) + { + this->CloseStreamFile(this->m_AmplitudeOutfile, this->m_AmplitudeImageFileName); + } + if (this->m_IntensityImageSelected) + { + this->CloseStreamFile(this->m_IntensityOutfile, this->m_IntensityImageFileName); + } + } + + void ToFNrrdImageWriter::CheckForFileExtension(std::string& fileName) + { + std::string baseFilename = itksys::SystemTools::GetFilenameWithoutLastExtension( fileName ); + std::string extension = itksys::SystemTools::GetFilenameLastExtension( fileName ); + + if( extension.length() != 0 && extension != this->m_Extension) + { + this->m_Extension = extension; + } + + size_t found = fileName.find( this->m_Extension ); // !!! HAS to be at the very end of the filename (not somewhere in the middle) + if( fileName.length() > 3 && found != fileName.length() - this->m_Extension.length() ) + { + fileName.append(this->m_Extension); + } + } + void ToFNrrdImageWriter::Add(float* distanceFloatData, float* amplitudeFloatData, float* intensityFloatData) + { + if (this->m_DistanceImageSelected) + { + this->m_DistanceOutfile->write(( char* ) distanceFloatData, this->m_ImageSizeInBytes); + } + if (this->m_AmplitudeImageSelected) + { + this->m_AmplitudeOutfile->write(( char* )amplitudeFloatData, this->m_ImageSizeInBytes); + } + if (this->m_IntensityImageSelected) + { + this->m_IntensityOutfile->write(( char* )intensityFloatData, this->m_ImageSizeInBytes); + } + this->m_NumOfFrames++; + } + + void ToFNrrdImageWriter::OpenStreamFile( std::ofstream* &outfile, std::string outfileName ) + { + outfile = new std::ofstream(outfileName.c_str()); + if(! outfile) + { + MITK_ERROR << "Error opening outfile: " << outfileName; + throw std::logic_error("Error opening outfile."); + return; + } + } + + void ToFNrrdImageWriter::CloseStreamFile( std::ofstream* &outfile, std::string fileName ) + { + if (this->m_NumOfFrames == 0) + { + outfile->close(); + throw std::logic_error("File is empty."); + return; + } + // TODO set data to itk::NrrdImageIO and write it to file! + this->ConvertStreamToNrrdFormat(outfile, fileName); + + outfile->close(); + } + + void ToFNrrdImageWriter::ConvertStreamToNrrdFormat(std::ofstream* outfile, std::string fileName) + { + float* floatData = new float[this->m_PixelNumber]; + for(int i=0; im_PixelNumber; i++) + { + floatData[i] = i + 0.0; + } + + Image::Pointer imageTemplate = Image::New(); + + int dimension ; + unsigned int* dimensions; + if(m_ToFImageType == ToFImageType2DPlusT) + { + dimension = 4; + dimensions = new unsigned int[dimension]; + dimensions[0] = this->m_CaptureWidth; + dimensions[1] = this->m_CaptureHeight; + dimensions[2] = 1; + dimensions[3] = this->m_NumOfFrames; + } + else if( m_ToFImageType == ToFImageType3D) + { + dimension = 3; + dimensions = new unsigned int[dimension]; + dimensions[0] = this->m_CaptureWidth; + dimensions[1] = this->m_CaptureHeight; + dimensions[2] = this->m_NumOfFrames; + } + else + { + throw std::logic_error("No image type set, please choose between 2D+t and 3D!"); + } + + imageTemplate->Initialize( PixelType(typeid(float)),dimension, dimensions, 1); + imageTemplate->SetSlice(floatData, 0, 0, 0); + + + itk::NrrdImageIO::Pointer nrrdWriter = itk::NrrdImageIO::New(); + nrrdWriter->SetNumberOfDimensions(dimension); + nrrdWriter->SetPixelTypeInfo(*(imageTemplate->GetPixelType().GetTypeId())); + if(imageTemplate->GetPixelType().GetNumberOfComponents() > 1) + { + nrrdWriter->SetNumberOfComponents(imageTemplate->GetPixelType().GetNumberOfComponents()); + } + + itk::ImageIORegion ioRegion( dimension ); + mitk::Vector3D spacing = imageTemplate->GetGeometry()->GetSpacing(); + mitk::Point3D origin = imageTemplate->GetGeometry()->GetOrigin(); + + for(unsigned int i=0; iSetDimensions(i,dimensions[i]); + nrrdWriter->SetSpacing(i,spacing[i]); + nrrdWriter->SetOrigin(i,origin[i]); + + mitk::Vector3D direction; + direction.Set_vnl_vector(imageTemplate->GetGeometry()->GetIndexToWorldTransform()->GetMatrix().GetVnlMatrix().get_column(i)); + vnl_vector< double > axisDirection(dimension); + + for(unsigned int j=0; jSetDirection( i, axisDirection ); + + ioRegion.SetSize(i, imageTemplate->GetLargestPossibleRegion().GetSize(i) ); + ioRegion.SetIndex(i, imageTemplate->GetLargestPossibleRegion().GetIndex(i) ); + } + + nrrdWriter->SetIORegion(ioRegion); + nrrdWriter->SetFileName(fileName); + nrrdWriter->SetUseStreamedWriting(true); + + const void * data = (void*) outfile; + nrrdWriter->Write(data); + + delete[] dimensions; + delete[] floatData; + + } + + ToFNrrdImageWriter::ToFImageType ToFNrrdImageWriter::GetToFImageType() + { + return this->m_ToFImageType; + } + + void ToFNrrdImageWriter::SetToFImageType(ToFNrrdImageWriter::ToFImageType toFImageType) + { + this->m_ToFImageType = toFImageType; + } + +} // end namespace mitk diff --git a/Modules/ToFHardware/mitkToFNrrdImageWriter.h b/Modules/ToFHardware/mitkToFNrrdImageWriter.h new file mode 100644 index 0000000000..7dd51b6953 --- /dev/null +++ b/Modules/ToFHardware/mitkToFNrrdImageWriter.h @@ -0,0 +1,146 @@ +/*========================================================================= + +Program: Medical Imaging & Interaction Toolkit +Module: $RCSfile$ +Language: C++ +Date: $Date: 2010-05-27 16:06:53 +0200 (Do, 27 Mai 2010) $ +Version: $Revision: $ + +Copyright (c) German Cancer Research Center, Division of Medical and +Biological Informatics. All rights reserved. +See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. + +This software is distributed WITHOUT ANY WARRANTY; without even +the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the above copyright notices for more information. + +=========================================================================*/ +#ifndef __mitkToFNrrdImageWriter_h +#define __mitkToFNrrdImageWriter_h + +#include "mitkToFHardwareExports.h" +#include "mitkCommon.h" +#include "mitkToFImageGrabber.h" + +#include "itkObject.h" +#include "itkObjectFactory.h" + +namespace mitk +{ + /** + * @brief Writer class for ToF images + * + * This writer class allows streaming of ToF data into a file. The .pic file format is used for writing the data. + * Image information is included in the header of the pic file. + * Writer can simultaneously save "distance", "intensity" and "amplitude" image. + * Images can be written as 3D volume (ToFImageType::ToFImageType3D) or temporal image stack (ToFImageType::ToFImageType2DPlusT) + * + * @ingroup ToFHardware + */ + class MITK_TOFHARDWARE_EXPORT ToFNrrdImageWriter : public itk::Object + { + public: + mitkClassMacro( ToFNrrdImageWriter , itk::Object ); + itkNewMacro( Self ); + + itkGetMacro( DistanceImageFileName, std::string ); + itkGetMacro( AmplitudeImageFileName, std::string ); + itkGetMacro( IntensityImageFileName, std::string ); + itkGetMacro( Extension, std::string ); + itkGetMacro( CaptureWidth, int ); + itkGetMacro( CaptureHeight, int ); + itkGetMacro( DistanceImageSelected, bool ); + itkGetMacro( AmplitudeImageSelected, bool ); + itkGetMacro( IntensityImageSelected, bool ); + + itkSetMacro( DistanceImageFileName, std::string ); + itkSetMacro( AmplitudeImageFileName, std::string ); + itkSetMacro( IntensityImageFileName, std::string ); + itkSetMacro( Extension, std::string ); + itkSetMacro( CaptureWidth, int ); + itkSetMacro( CaptureHeight, int ); + itkSetMacro( DistanceImageSelected, bool ); + itkSetMacro( AmplitudeImageSelected, bool ); + itkSetMacro( IntensityImageSelected, bool ); + + enum ToFImageType{ ToFImageType3D, ToFImageType2DPlusT }; + /*! + \brief Get the type of image to be written + \return ToF image type: ToFImageType3D (0) or ToFImageType2DPlusT (1) + */ + ToFNrrdImageWriter::ToFImageType GetToFImageType(); + /*! + \brief Set the type of image to be written + \param toFImageType type of the ToF image: ToFImageType3D (0) or ToFImageType2DPlusT (1) + */ + void SetToFImageType(ToFNrrdImageWriter::ToFImageType toFImageType); + /*! + \brief Open file(s) for writing + */ + virtual void Open(); + /*! + \brief Close file(s) add .pic header and write + */ + virtual void Close(); + /*! + \brief Add new data to file. + */ + virtual void Add(float* distanceFloatData, float* amplitudeFloatData, float* intensityFloatData); + + protected: + + /*! + \brief Checks file name if file extension exists. If not .pic is added to fileName + \param fileName file name to be checked + */ + void CheckForFileExtension(std::string& fileName); + + std::string m_DistanceImageFileName; ///< file name for saving the distance image + std::string m_AmplitudeImageFileName; ///< file name for saving the amplitude image + std::string m_IntensityImageFileName; ///< file name for saving the intensity image + std::string m_Extension; ///< file extension used for saving images + + int m_CaptureWidth; ///< width (x-dimension) of the images to record. + int m_CaptureHeight; ///< height (y-dimension) of the images to record. + int m_PixelNumber; ///< number of pixels (widht*height) of the images to record + int m_ImageSizeInBytes; ///< size of the image to save in bytes + int m_NumOfFrames; ///< number of frames written to the image. Used for pic header. + ToFNrrdImageWriter::ToFImageType m_ToFImageType; ///< type of image to be recorded: ToFImageType3D (0) or ToFImageType2DPlusT (1) + + bool m_DistanceImageSelected; ///< flag indicating if distance image should be recorded + bool m_AmplitudeImageSelected; ///< flag indicating if amplitude image should be recorded + bool m_IntensityImageSelected; ///< flag indicating if intensity image should be recorded + + //Image::Pointer m_MitkImage; ///< mitk image used for pic header creation + std::ofstream* m_DistanceOutfile; ///< file for distance image + std::ofstream* m_AmplitudeOutfile; ///< file for amplitude image + std::ofstream* m_IntensityOutfile; ///< file for intensity image + + + private: + + ToFNrrdImageWriter(); + ~ToFNrrdImageWriter(); + + /*! + \brief Open file by filename to gain write access to it. + */ + void OpenStreamFile(std::ofstream* &outfile, std::string outfileName); + /*! + \brief Close file after work on it is finished. + */ + void CloseStreamFile(std::ofstream* &outfile, std::string fileName); + /*! + \brief Replace current PicFileHeader information. + */ + void ReplacePicFileHeader(FILE* outfile); + /*! + \brief Write image information to the PicFileHeader. + */ + //void WritePicFileHeader(FILE* outfile, mitkIpPicDescriptor* pic); + + //void ConvertStreamToNrrdFormat(std::ofstream* outfile); + void ConvertStreamToNrrdFormat(std::ofstream* outfile, std::string fileName); + }; +} //END mitk namespace +#endif // __mitkToFNrrdImageWriter_h