diff --git a/Modules/ToFHardware/mitkToFImageCsvWriter.cpp b/Modules/ToFHardware/mitkToFImageCsvWriter.cpp index 1c957084bd..8ae2eecdd6 100644 --- a/Modules/ToFHardware/mitkToFImageCsvWriter.cpp +++ b/Modules/ToFHardware/mitkToFImageCsvWriter.cpp @@ -1,126 +1,126 @@ /*========================================================================= 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 namespace mitk { ToFImageCsvWriter::ToFImageCsvWriter(): ToFImageWriter(), m_DistanceOutfile(NULL), m_AmplitudeOutfile(NULL), m_IntensityOutfile(NULL) { this->m_Extension = std::string(".csv"); } ToFImageCsvWriter::~ToFImageCsvWriter() { } void ToFImageCsvWriter::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->OpenCsvFile(&(this->m_DistanceOutfile), this->m_DistanceImageFileName); } if (this->m_AmplitudeImageSelected) { this->OpenCsvFile(&(this->m_AmplitudeOutfile), this->m_AmplitudeImageFileName); } if (this->m_IntensityImageSelected) { this->OpenCsvFile(&(this->m_IntensityOutfile), this->m_IntensityImageFileName); } this->m_NumOfFrames = 0; } void ToFImageCsvWriter::Close() { if (this->m_DistanceImageSelected) { this->CloseCsvFile(this->m_DistanceOutfile); } if (this->m_AmplitudeImageSelected) { this->CloseCsvFile(this->m_AmplitudeOutfile); } if (this->m_IntensityImageSelected) { this->CloseCsvFile(this->m_IntensityOutfile); } } - void ToFImageCsvWriter::Add(float* distanceFloatData, float* amplitudeFloatData, float* intensityFloatData) + void ToFImageCsvWriter::Add(float* distanceFloatData, float* amplitudeFloatData, float* intensityFloatData, unsigned char* rgbData) { if (this->m_DistanceImageSelected) { this->WriteCsvFile(this->m_DistanceOutfile, distanceFloatData); } if (this->m_AmplitudeImageSelected) { this->WriteCsvFile(this->m_AmplitudeOutfile, amplitudeFloatData); } if (this->m_IntensityImageSelected) { this->WriteCsvFile(this->m_IntensityOutfile, intensityFloatData); } this->m_NumOfFrames++; } void ToFImageCsvWriter::WriteCsvFile(FILE* outfile, float* floatData) { for(int i=0; im_PixelNumber; i++) { if (this->m_NumOfFrames==0 && i==0) { fprintf(outfile, "%f", floatData[i]); } else { fprintf(outfile, ",%f", floatData[i]); } } } void ToFImageCsvWriter::OpenCsvFile(FILE** outfile, std::string outfileName) { (*outfile) = fopen( outfileName.c_str(), "w+" ); if( !outfile ) { MITK_ERROR << "Error opening outfile: " << outfileName; throw std::logic_error("Error opening outfile."); return; } } void ToFImageCsvWriter::CloseCsvFile(FILE* outfile) { if (this->m_NumOfFrames == 0) { fclose(outfile); throw std::logic_error("File is empty."); return; } fclose(outfile); } } diff --git a/Modules/ToFHardware/mitkToFImageCsvWriter.h b/Modules/ToFHardware/mitkToFImageCsvWriter.h index 5b6fd29484..d9ed5be8d2 100644 --- a/Modules/ToFHardware/mitkToFImageCsvWriter.h +++ b/Modules/ToFHardware/mitkToFImageCsvWriter.h @@ -1,90 +1,90 @@ /*========================================================================= 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 __mitkToFImageCsvWriter_h #define __mitkToFImageCsvWriter_h #include "mitkToFImageWriter.h" #include "mitkToFHardwareExports.h" namespace mitk { /** * @brief CSV writer class for ToF image data * * This writer class allows streaming of ToF data into a CSV file. * Writer can simultaneously save "distance", "intensity" and "amplitude" image data. * Output files are written as 1D CSV data stream. * * @ingroup ToFHardware */ class MITK_TOFHARDWARE_EXPORT ToFImageCsvWriter : public ToFImageWriter { public: /*! \brief standard ctor */ ToFImageCsvWriter(); /*! \brief standard ~ctor */ ~ToFImageCsvWriter(); mitkClassMacro( ToFImageCsvWriter , ToFImageWriter ); itkNewMacro( Self ); /*! \brief Checks for file extensions and opens the output files */ void Open(); /*! \brief Closes the output files */ void Close(); /*! \brief Pushes the image data to the output files \param data from distance, amplitude and intensity images as float values */ - void Add(float* distanceFloatData, float* amplitudeFloatData, float* intensityFloatData); + void Add(float* distanceFloatData, float* amplitudeFloatData, float* intensityFloatData, unsigned char* rgbData=0); protected: Image::Pointer m_MitkImage; ///< mitk image used for pic header creation FILE* m_DistanceOutfile; ///< file for distance image FILE* m_AmplitudeOutfile; ///< file for amplitude image FILE* m_IntensityOutfile; ///< file for intensity image - + FILE* m_RGBOutfile; ///< file for RGB image private: /*! \brief opens CSV output file \param output file, name of the output file */ void OpenCsvFile(FILE** outfile, std::string outfileName); /*! \brief closes CSV output file \param output file */ void CloseCsvFile(FILE* outfile); /*! \brief writes the data to the CSV output file \param output file, data array of float values */ void WriteCsvFile(FILE* outfile, float* floatData); }; } //END mitk namespace #endif // __mitkToFImageCsvWriter_h diff --git a/Modules/ToFHardware/mitkToFImageRecorder.cpp b/Modules/ToFHardware/mitkToFImageRecorder.cpp index 9327ed4e83..e5feded76b 100644 --- a/Modules/ToFHardware/mitkToFImageRecorder.cpp +++ b/Modules/ToFHardware/mitkToFImageRecorder.cpp @@ -1,255 +1,259 @@ /*========================================================================= 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 "mitkToFImageRecorder.h" #include "mitkRealTimeClock.h" #include "itkMultiThreader.h" #include #pragma GCC visibility push(default) #include #pragma GCC visibility pop namespace mitk { ToFImageRecorder::ToFImageRecorder() { this->m_ToFCameraDevice = NULL; this->m_MultiThreader = itk::MultiThreader::New(); this->m_AbortMutex = itk::FastMutexLock::New(); this->m_ThreadID = 0; this->m_NumOfFrames = 0; this->m_ToFImageWriter = NULL; this->m_DistanceImageSelected = true; this->m_AmplitudeImageSelected = true; this->m_IntensityImageSelected = true; + this->m_RGBImageSelected = true; this->m_Abort = true; this->m_CaptureWidth = 0; this->m_CaptureHeight = 0; this->m_FileFormat = ""; this->m_PixelNumber = 0; this->m_SourceDataSize = 0; this->m_ToFImageType = ToFImageWriter::ToFImageType3D; this->m_RecordMode = ToFImageRecorder::PerFrames; this->m_DistanceImageFileName = ""; this->m_AmplitudeImageFileName = ""; this->m_IntensityImageFileName = ""; + this->m_RGBImageFileName = ""; this->m_ImageSequence = 0; this->m_DistanceArray = NULL; this->m_AmplitudeArray = NULL; this->m_IntensityArray = NULL; this->m_RGBArray = NULL; this->m_SourceDataArray = NULL; } ToFImageRecorder::~ToFImageRecorder() { delete[] m_DistanceArray; delete[] m_AmplitudeArray; delete[] m_IntensityArray; delete[] m_RGBArray; delete[] m_SourceDataArray; } void ToFImageRecorder::StopRecording() { this->m_AbortMutex->Lock(); this->m_Abort = true; this->m_AbortMutex->Unlock(); } void ToFImageRecorder::StartRecording() { if (this->m_ToFCameraDevice.IsNull()) { throw std::invalid_argument("ToFCameraDevice is NULL."); return; } if (this->m_FileFormat.compare(".csv") == 0) { this->m_ToFImageWriter = ToFImageCsvWriter::New(); } else if(this->m_FileFormat.compare(".nrrd") == 0) { this->m_ToFImageWriter = ToFNrrdImageWriter::New(); this->m_ToFImageWriter->SetExtension(m_FileFormat); } else if(this->m_FileFormat.compare(".pic") == 0) { this->m_ToFImageWriter = ToFPicImageWriter::New(); this->m_ToFImageWriter->SetExtension(m_FileFormat); } else { throw std::logic_error("No file format specified!"); } this->m_CaptureWidth = this->m_ToFCameraDevice->GetCaptureWidth(); this->m_CaptureHeight = this->m_ToFCameraDevice->GetCaptureHeight(); this->m_PixelNumber = this->m_CaptureWidth * this->m_CaptureHeight; this->m_SourceDataSize = this->m_ToFCameraDevice->GetSourceDataSize(); // allocate buffer if(m_IntensityArray == NULL) { this->m_IntensityArray = new float[m_PixelNumber]; } if(this->m_DistanceArray == NULL) { this->m_DistanceArray = new float[m_PixelNumber]; } if(this->m_AmplitudeArray == NULL) { this->m_AmplitudeArray = new float[m_PixelNumber]; } if(this->m_RGBArray == NULL) { this->m_RGBArray = new unsigned char[m_PixelNumber*3]; } if(this->m_SourceDataArray == NULL) { this->m_SourceDataArray = new char[m_SourceDataSize]; } this->m_ToFImageWriter->SetDistanceImageFileName(this->m_DistanceImageFileName); this->m_ToFImageWriter->SetAmplitudeImageFileName(this->m_AmplitudeImageFileName); this->m_ToFImageWriter->SetIntensityImageFileName(this->m_IntensityImageFileName); + this->m_ToFImageWriter->SetRGBImageFileName(this->m_RGBImageFileName); this->m_ToFImageWriter->SetCaptureWidth(this->m_CaptureWidth); this->m_ToFImageWriter->SetCaptureHeight(this->m_CaptureHeight); this->m_ToFImageWriter->SetToFImageType(this->m_ToFImageType); this->m_ToFImageWriter->SetDistanceImageSelected(this->m_DistanceImageSelected); this->m_ToFImageWriter->SetAmplitudeImageSelected(this->m_AmplitudeImageSelected); this->m_ToFImageWriter->SetIntensityImageSelected(this->m_IntensityImageSelected); + this->m_ToFImageWriter->SetRGBImageSelected(this->m_RGBImageSelected); this->m_ToFImageWriter->Open(); this->m_AbortMutex->Lock(); this->m_Abort = false; this->m_AbortMutex->Unlock(); this->m_ThreadID = this->m_MultiThreader->SpawnThread(this->RecordData, this); } ITK_THREAD_RETURN_TYPE ToFImageRecorder::RecordData(void* pInfoStruct) { struct itk::MultiThreader::ThreadInfoStruct * pInfo = (struct itk::MultiThreader::ThreadInfoStruct*)pInfoStruct; if (pInfo == NULL) { return ITK_THREAD_RETURN_VALUE; } if (pInfo->UserData == NULL) { return ITK_THREAD_RETURN_VALUE; } ToFImageRecorder* toFImageRecorder = (ToFImageRecorder*)pInfo->UserData; if (toFImageRecorder!=NULL) { ToFCameraDevice::Pointer toFCameraDevice = toFImageRecorder->GetCameraDevice(); mitk::RealTimeClock::Pointer realTimeClock; realTimeClock = mitk::RealTimeClock::New(); int n = 100; double t1 = 0; double t2 = 0; t1 = realTimeClock->GetCurrentStamp(); bool overflow = false; bool printStatus = false; int requiredImageSequence = 0; int numOfFramesRecorded = 0; bool abort = false; toFImageRecorder->m_AbortMutex->Lock(); abort = toFImageRecorder->m_Abort; toFImageRecorder->m_AbortMutex->Unlock(); while ( !abort ) { if ( ((toFImageRecorder->m_RecordMode == ToFImageRecorder::PerFrames) && (numOfFramesRecorded < toFImageRecorder->m_NumOfFrames)) || (toFImageRecorder->m_RecordMode == ToFImageRecorder::Infinite) ) { toFCameraDevice->GetAllImages(toFImageRecorder->m_DistanceArray, toFImageRecorder->m_AmplitudeArray, toFImageRecorder->m_IntensityArray, toFImageRecorder->m_SourceDataArray, requiredImageSequence, toFImageRecorder->m_ImageSequence, toFImageRecorder->m_RGBArray ); if (toFImageRecorder->m_ImageSequence >= requiredImageSequence) { if (toFImageRecorder->m_ImageSequence > requiredImageSequence) { MITK_INFO << "Problem! required: " << requiredImageSequence << " captured: " << toFImageRecorder->m_ImageSequence; } requiredImageSequence = toFImageRecorder->m_ImageSequence + 1; toFImageRecorder->m_ToFImageWriter->Add( toFImageRecorder->m_DistanceArray, - toFImageRecorder->m_AmplitudeArray, toFImageRecorder->m_IntensityArray ); + toFImageRecorder->m_AmplitudeArray, toFImageRecorder->m_IntensityArray, toFImageRecorder->m_RGBArray ); numOfFramesRecorded++; if (numOfFramesRecorded % n == 0) { printStatus = true; } if (printStatus) { t2 = realTimeClock->GetCurrentStamp() - t1; MITK_INFO << " Framerate (fps): " << n / (t2/1000) << " Sequence: " << toFImageRecorder->m_ImageSequence; t1 = realTimeClock->GetCurrentStamp(); printStatus = false; } } toFImageRecorder->m_AbortMutex->Lock(); abort = toFImageRecorder->m_Abort; toFImageRecorder->m_AbortMutex->Unlock(); } else { abort = true; } } // end of while loop toFImageRecorder->InvokeEvent(itk::AbortEvent()); toFImageRecorder->m_ToFImageWriter->Close(); } return ITK_THREAD_RETURN_VALUE; } void ToFImageRecorder::SetCameraDevice(ToFCameraDevice* aToFCameraDevice) { this->m_ToFCameraDevice = aToFCameraDevice; } ToFCameraDevice* ToFImageRecorder::GetCameraDevice() { return this->m_ToFCameraDevice; } ToFImageWriter::ToFImageType ToFImageRecorder::GetToFImageType() { return this->m_ToFImageType; } void ToFImageRecorder::SetToFImageType(ToFImageWriter::ToFImageType toFImageType) { this->m_ToFImageType = toFImageType; } ToFImageRecorder::RecordMode ToFImageRecorder::GetRecordMode() { return this->m_RecordMode; } void ToFImageRecorder::SetRecordMode(ToFImageRecorder::RecordMode recordMode) { this->m_RecordMode = recordMode; } } diff --git a/Modules/ToFHardware/mitkToFImageRecorder.h b/Modules/ToFHardware/mitkToFImageRecorder.h index 18983ffa0a..d03404774e 100644 --- a/Modules/ToFHardware/mitkToFImageRecorder.h +++ b/Modules/ToFHardware/mitkToFImageRecorder.h @@ -1,163 +1,169 @@ /*========================================================================= 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 __mitkToFImageRecorder_h #define __mitkToFImageRecorder_h #include "mitkToFHardwareExports.h" #include "mitkCommon.h" #include "mitkToFCameraDevice.h" #include "mitkToFPicImageWriter.h" #include "mitkToFImageCsvWriter.h" #include "mitkToFNrrdImageWriter.h" #include "itkObject.h" #include "itkObjectFactory.h" #include "itkFastMutexLock.h" #include "itkCommand.h" namespace mitk { /** * @brief Recorder class for ToF images * * This class represents a recorder for ToF data. A ToFCameraDevice is used to acquire the data. The acquired images * are then added to a ToFImageWriter that performs the actual writing. * * Recording can be performed either frame-based or continuously * * @ingroup ToFHardware */ class MITK_TOFHARDWARE_EXPORT ToFImageRecorder : public itk::Object { public: ToFImageRecorder(); ~ToFImageRecorder(); mitkClassMacro( ToFImageRecorder , itk::Object ); itkNewMacro( Self ); itkGetMacro( DistanceImageFileName, std::string ); itkGetMacro( AmplitudeImageFileName, std::string ); itkGetMacro( IntensityImageFileName, std::string ); + itkGetMacro( RGBImageFileName, std::string ); itkGetMacro( CaptureWidth, int ); itkGetMacro( CaptureHeight, int ); itkGetMacro( DistanceImageSelected, bool ); itkGetMacro( AmplitudeImageSelected, bool ); itkGetMacro( IntensityImageSelected, bool ); + itkGetMacro( RGBImageSelected, bool ); itkGetMacro( NumOfFrames, int ); itkGetMacro( FileFormat, std::string ); itkSetMacro( DistanceImageFileName, std::string ); itkSetMacro( AmplitudeImageFileName, std::string ); itkSetMacro( IntensityImageFileName, std::string ); + itkSetMacro(RGBImageFileName, std::string ); itkSetMacro( DistanceImageSelected, bool ); itkSetMacro( AmplitudeImageSelected, bool ); itkSetMacro( IntensityImageSelected, bool ); + itkSetMacro( RGBImageSelected, bool ); itkSetMacro( NumOfFrames, int ); itkSetMacro( FileFormat, std::string ); enum RecordMode{ PerFrames, Infinite }; /*! \brief Returns the currently set RecordMode \return record mode: PerFrames ("Record specified number of frames"), Infinite ("Record until abort is required") */ ToFImageRecorder::RecordMode GetRecordMode(); /*! \brief Set the RecordMode \param recordMode: PerFrames ("Record specified number of frames"), Infinite ("Record until abort is required") */ void SetRecordMode(ToFImageRecorder::RecordMode recordMode); /*! \brief Set the device used for acquiring ToF images \param aToFCameraDevice ToF camera device used. */ void SetCameraDevice(ToFCameraDevice* aToFCameraDevice); /*! \brief Get the device used for acquiring ToF images \return ToF camera device used. */ ToFCameraDevice* GetCameraDevice(); /*! \brief Get the type of image to be recorded \return ToF image type: ToFImageType3D (0) or ToFImageType2DPlusT (1) */ ToFImageWriter::ToFImageType GetToFImageType(); /*! \brief Set the type of image to be recorded \param toFImageType type of the ToF image: ToFImageType3D (0) or ToFImageType2DPlusT (1) */ void SetToFImageType(ToFImageWriter::ToFImageType toFImageType); /*! \brief Starts the recording by spawning a Thread which streams the data to a file. Aborting of the record process is controlled by the m_Abort flag */ void StartRecording(); /*! \brief Stops the recording by setting the m_Abort flag to false */ void StopRecording(); protected: /*! \brief Thread method acquiring data via the ToFCameraDevice and recording it to file via the ToFImageWriter */ static ITK_THREAD_RETURN_TYPE RecordData(void* pInfoStruct); // data acquisition ToFCameraDevice::Pointer m_ToFCameraDevice; ///< ToFCameraDevice used for acquiring the 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_SourceDataSize; ///< size of the source data provided by the device int m_ImageSequence; ///< number of images currently acquired float* m_IntensityArray; ///< array holding the intensity data float* m_DistanceArray; ///< array holding the distance data float* m_AmplitudeArray; ///< array holding the amplitude data unsigned char* m_RGBArray; ///< array holding the RGB data if available (e.g. for Kinect) char* m_SourceDataArray; ///< array holding the source data // data writing ToFImageWriter::Pointer m_ToFImageWriter; ///< image writer writing the acquired images to a file 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_RGBImageFileName; ///< file name for saving the rgb image + int m_NumOfFrames; ///< number of frames to be recorded by this recorder ToFImageWriter::ToFImageType m_ToFImageType; ///< type of image to be recorded: ToFImageType3D (0) or ToFImageType2DPlusT (1) ToFImageRecorder::RecordMode m_RecordMode; ///< mode of recording the images: specified number of frames (PerFrames) or infinite (Infinite) std::string m_FileFormat; ///< file format for saving images. If .csv is chosen, ToFImageCsvWriter is used 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 + bool m_RGBImageSelected; ///< flag indicating if rgb image should be recorded // threading itk::MultiThreader::Pointer m_MultiThreader; ///< member for thread-handling (ITK-based) int m_ThreadID; ///< ID of the thread recording the data itk::FastMutexLock::Pointer m_AbortMutex; ///< mutex for thread-safe data access of abort flag bool m_Abort; ///< flag controlling the abort mechanism of the recording procedure. For thread-safety only use in combination with m_AbortMutex private: }; } //END mitk namespace #endif diff --git a/Modules/ToFHardware/mitkToFImageWriter.cpp b/Modules/ToFHardware/mitkToFImageWriter.cpp index 4e29815588..5ebc8878ee 100644 --- a/Modules/ToFHardware/mitkToFImageWriter.cpp +++ b/Modules/ToFHardware/mitkToFImageWriter.cpp @@ -1,67 +1,67 @@ /*========================================================================= 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 // itk includes #include "itksys/SystemTools.hxx" namespace mitk { ToFImageWriter::ToFImageWriter():m_Extension(".nrrd"), - m_DistanceImageFileName(), m_AmplitudeImageFileName(), m_IntensityImageFileName(), + m_DistanceImageFileName(), m_AmplitudeImageFileName(), m_IntensityImageFileName(), m_RGBImageFileName(), m_NumOfFrames(0), m_DistanceImageSelected(true), m_AmplitudeImageSelected(true), - m_IntensityImageSelected(true),m_CaptureWidth(200),m_CaptureHeight(200), + m_IntensityImageSelected(true), m_RGBImageSelected(true), m_CaptureWidth(200),m_CaptureHeight(200), m_PixelNumber(0), m_ImageSizeInBytes(0), m_ToFImageType(ToFImageWriter::ToFImageType3D) { } ToFImageWriter::~ToFImageWriter() { } void ToFImageWriter::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) { MITK_ERROR << "Wrong file extension! The default extension is " << this->m_Extension.c_str() << ", currently the requested file extension is " << extension.c_str() <<"!"; 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( found == std::string::npos) { fileName.append(this->m_Extension); } } ToFImageWriter::ToFImageType ToFImageWriter::GetToFImageType() { return this->m_ToFImageType; } void ToFImageWriter::SetToFImageType(ToFImageWriter::ToFImageType toFImageType) { this->m_ToFImageType = toFImageType; } } // end namespace mitk diff --git a/Modules/ToFHardware/mitkToFImageWriter.h b/Modules/ToFHardware/mitkToFImageWriter.h index 7d5ecd039b..16caf4931c 100644 --- a/Modules/ToFHardware/mitkToFImageWriter.h +++ b/Modules/ToFHardware/mitkToFImageWriter.h @@ -1,124 +1,130 @@ /*========================================================================= 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 __mitkToFImageWriter_h #define __mitkToFImageWriter_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 ToFImageWriter : public itk::Object { public: ToFImageWriter(); ~ToFImageWriter(); mitkClassMacro( ToFImageWriter , itk::Object ); itkNewMacro( Self ); itkGetMacro( DistanceImageFileName, std::string ); itkGetMacro( AmplitudeImageFileName, std::string ); itkGetMacro( IntensityImageFileName, std::string ); + itkGetMacro( RGBImageFileName, std::string ); itkGetMacro( Extension, std::string ); itkGetMacro( CaptureWidth, int ); itkGetMacro( CaptureHeight, int ); itkGetMacro( DistanceImageSelected, bool ); itkGetMacro( AmplitudeImageSelected, bool ); itkGetMacro( IntensityImageSelected, bool ); + itkGetMacro( RGBImageSelected, bool ); itkSetMacro( DistanceImageFileName, std::string ); itkSetMacro( AmplitudeImageFileName, std::string ); itkSetMacro( IntensityImageFileName, std::string ); + itkSetMacro( RGBImageFileName, std::string ); itkSetMacro( Extension, std::string ); itkSetMacro( CaptureWidth, int ); itkSetMacro( CaptureHeight, int ); itkSetMacro( DistanceImageSelected, bool ); itkSetMacro( AmplitudeImageSelected, bool ); itkSetMacro( IntensityImageSelected, bool ); + itkSetMacro( RGBImageSelected, bool ); enum ToFImageType{ ToFImageType3D, ToFImageType2DPlusT }; /*! \brief Get the type of image to be written \return ToF image type: ToFImageType3D (0) or ToFImageType2DPlusT (1) */ ToFImageWriter::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(ToFImageWriter::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){}; + virtual void Add(float* distanceFloatData, float* amplitudeFloatData, float* intensityFloatData, unsigned char* rgbData=0){}; protected: /*! \brief Checks file name if file extension exists. If not an error message is returned */ void CheckForFileExtension(std::string& fileName); // member variables 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_RGBImageFileName; ///< file name for saving the RGB 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. ToFImageWriter::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 + bool m_RGBImageSelected; ///< flag indicating if RGB image should be recorded private: }; } //END mitk namespace #endif // __mitkToFImageWriter_h diff --git a/Modules/ToFHardware/mitkToFNrrdImageWriter.cpp b/Modules/ToFHardware/mitkToFNrrdImageWriter.cpp index 77a64786ad..18460b19ba 100644 --- a/Modules/ToFHardware/mitkToFNrrdImageWriter.cpp +++ b/Modules/ToFHardware/mitkToFNrrdImageWriter.cpp @@ -1,208 +1,220 @@ /*========================================================================= 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. =========================================================================*/ // mitk includes #include // itk includes #include "itksys/SystemTools.hxx" #include "itkNrrdImageIO.h" namespace mitk { ToFNrrdImageWriter::ToFNrrdImageWriter(): ToFImageWriter(), m_DistanceOutfile(), m_AmplitudeOutfile(), m_IntensityOutfile() { m_Extension = std::string(".nrrd"); } ToFNrrdImageWriter::~ToFNrrdImageWriter() { } void ToFNrrdImageWriter::Open() { this->CheckForFileExtension(this->m_DistanceImageFileName); this->CheckForFileExtension(this->m_AmplitudeImageFileName); this->CheckForFileExtension(this->m_IntensityImageFileName); + this->CheckForFileExtension(this->m_RGBImageFileName); 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); } + if (this->m_RGBImageSelected) + { + this->OpenStreamFile(this->m_RGBOutfile, this->m_RGBImageFileName); + } 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); } + if (this->m_RGBImageSelected) + { + this->CloseStreamFile(this->m_RGBOutfile, this->m_RGBImageFileName); + } } - void ToFNrrdImageWriter::Add(float* distanceFloatData, float* amplitudeFloatData, float* intensityFloatData) + void ToFNrrdImageWriter::Add(float* distanceFloatData, float* amplitudeFloatData, float* intensityFloatData, unsigned char* rgbData) { 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); } + if (this->m_RGBImageSelected) + { + this->m_RGBOutfile.write(( unsigned char* )rgbData, this->m_ImageSizeInBytes); + } this->m_NumOfFrames++; } void ToFNrrdImageWriter::OpenStreamFile( std::ofstream &outfile, std::string outfileName ) { outfile.open(outfileName.c_str(), std::ofstream::binary); if(!outfile.is_open()) { 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; } // flush the last data to the file and convert the stream data to nrrd file outfile.flush(); this->ConvertStreamToNrrdFormat( fileName ); outfile.close(); } void ToFNrrdImageWriter::ConvertStreamToNrrdFormat( 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!"); } mitk::PixelType FloatType = MakeScalarPixelType(); imageTemplate->Initialize( FloatType,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; i < dimension; i++) { nrrdWriter->SetDimensions(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; j < dimension; j++) { axisDirection[j] = direction[j]/spacing[i]; } nrrdWriter->SetDirection( 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); std::ifstream stream(fileName.c_str(), std::ifstream::binary); unsigned int size = this->m_PixelNumber * this->m_NumOfFrames; unsigned int sizeInBytes = size * sizeof(float); float* data = new float[size]; stream.read((char*)data, sizeInBytes); nrrdWriter->Write(data); stream.close(); delete[] data; delete[] dimensions; delete[] floatData; } } // end namespace mitk diff --git a/Modules/ToFHardware/mitkToFNrrdImageWriter.h b/Modules/ToFHardware/mitkToFNrrdImageWriter.h index 0bd7411770..b8be6d46c0 100644 --- a/Modules/ToFHardware/mitkToFNrrdImageWriter.h +++ b/Modules/ToFHardware/mitkToFNrrdImageWriter.h @@ -1,81 +1,82 @@ /*========================================================================= 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 "mitkToFImageWriter.h" #include namespace mitk { /** * @brief Writer class for ToF nrrd images * * This writer class allows streaming of ToF data into a nrrd file. This class uses the itkNrrdImageIO class * 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 ToFImageWriter { public: mitkClassMacro( ToFNrrdImageWriter , ToFImageWriter ); itkNewMacro( Self ); /*! \brief Open file(s) for writing */ void Open(); /*! \brief Close file(s) add .pic header and write */ void Close(); /*! \brief Add new data to file. */ - void Add(float* distanceFloatData, float* amplitudeFloatData, float* intensityFloatData); + void Add(float* distanceFloatData, float* amplitudeFloatData, float* intensityFloatData, unsigned char* rgbData=0); protected: std::ofstream m_DistanceOutfile; ///< file for distance image std::ofstream m_AmplitudeOutfile; ///< file for amplitude image std::ofstream m_IntensityOutfile; ///< file for intensity image + std::ofstream m_RGBOutfile; ///< 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 Write image information to the NrrdFile. */ void ConvertStreamToNrrdFormat( std::string fileName ); }; } //END mitk namespace #endif // __mitkToFNrrdImageWriter_h diff --git a/Modules/ToFHardware/mitkToFPicImageWriter.cpp b/Modules/ToFHardware/mitkToFPicImageWriter.cpp index ff11a0dcb1..6d67ddd37b 100644 --- a/Modules/ToFHardware/mitkToFPicImageWriter.cpp +++ b/Modules/ToFHardware/mitkToFPicImageWriter.cpp @@ -1,205 +1,205 @@ /*========================================================================= 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 // deprecated support of mitkIpPic #include // itk includes #include "itksys/SystemTools.hxx" extern "C" { size_t _mitkIpPicFWrite( const void *ptr, size_t size, size_t nitems, mitkIpPicFile_t stream); } namespace mitk { ToFPicImageWriter::ToFPicImageWriter(): ToFImageWriter(), m_DistanceOutfile(NULL), m_AmplitudeOutfile(NULL), m_IntensityOutfile(NULL) { m_Extension = std::string(".pic"); } ToFPicImageWriter::~ToFPicImageWriter() { } void ToFPicImageWriter::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); float* floatData = new float[this->m_PixelNumber]; for(int i=0; im_PixelNumber; i++) { floatData[i] = i + 0.0; } this->m_MitkImage = Image::New(); unsigned int dimensions[4]; dimensions[0] = this->m_CaptureWidth; dimensions[1] = this->m_CaptureHeight; mitk::PixelType FloatType = MakeScalarPixelType(); if (this->m_ToFImageType == ToFImageWriter::ToFImageType2DPlusT) { dimensions[2] = 1; dimensions[3] = 2; this->m_MitkImage->Initialize( FloatType, 4, dimensions, 1); } else { dimensions[2] = 2; dimensions[3] = 1; this->m_MitkImage->Initialize( FloatType, 3, dimensions, 1); } this->m_MitkImage->SetSlice(floatData, 0, 0, 0); mitkIpPicDescriptor* pic = mitkIpPicNew(); CastToIpPicDescriptor( this->m_MitkImage, pic); if (this->m_DistanceImageSelected) { this->OpenPicFile(&(this->m_DistanceOutfile), this->m_DistanceImageFileName); this->WritePicFileHeader(this->m_DistanceOutfile, pic); } if (this->m_AmplitudeImageSelected) { this->OpenPicFile(&(this->m_AmplitudeOutfile), this->m_AmplitudeImageFileName); this->WritePicFileHeader(this->m_AmplitudeOutfile, pic); } if (this->m_IntensityImageSelected) { this->OpenPicFile(&(this->m_IntensityOutfile), this->m_IntensityImageFileName); this->WritePicFileHeader(this->m_IntensityOutfile, pic); } this->m_NumOfFrames = 0; delete[] floatData; } void ToFPicImageWriter::Close() { if (this->m_DistanceImageSelected) { this->ClosePicFile(this->m_DistanceOutfile); } if (this->m_AmplitudeImageSelected) { this->ClosePicFile(this->m_AmplitudeOutfile); } if (this->m_IntensityImageSelected) { this->ClosePicFile(this->m_IntensityOutfile); } } - void ToFPicImageWriter::Add(float* distanceFloatData, float* amplitudeFloatData, float* intensityFloatData) + void ToFPicImageWriter::Add(float* distanceFloatData, float* amplitudeFloatData, float* intensityFloatData, unsigned char* rgbData) { if (this->m_DistanceImageSelected) { fwrite( distanceFloatData, this->m_ImageSizeInBytes, 1, this->m_DistanceOutfile ); } if (this->m_AmplitudeImageSelected) { fwrite( amplitudeFloatData, this->m_ImageSizeInBytes, 1, this->m_AmplitudeOutfile ); } if (this->m_IntensityImageSelected) { fwrite( intensityFloatData, this->m_ImageSizeInBytes, 1, this->m_IntensityOutfile ); } this->m_NumOfFrames++; } void ToFPicImageWriter::OpenPicFile(FILE** outfile,std::string outfileName) { (*outfile) = fopen( outfileName.c_str(), "w+b" ); if( !outfile ) // if fopen_s was not successful! { MITK_ERROR << "Error opening outfile: " << outfileName; throw std::logic_error("Error opening outfile."); return; } } void ToFPicImageWriter::ClosePicFile(FILE* outfile) { if (this->m_NumOfFrames == 0) { fclose(outfile); throw std::logic_error("File is empty."); return; } this->ReplacePicFileHeader(outfile); fclose(outfile); } void ToFPicImageWriter::ReplacePicFileHeader(FILE* outfile) { mitkIpPicDescriptor* pic = mitkIpPicNew(); CastToIpPicDescriptor( this->m_MitkImage, pic); if (this->m_ToFImageType == ToFImageWriter::ToFImageType2DPlusT) { pic->dim = 4; pic->n[2] = 1; pic->n[3] = this->m_NumOfFrames; } else { pic->dim = 3; pic->n[2] = this->m_NumOfFrames; pic->n[3] = 1; } fseek ( outfile, 0, SEEK_SET ); this->WritePicFileHeader( outfile, pic ); } void ToFPicImageWriter::WritePicFileHeader(FILE* outfile, mitkIpPicDescriptor* pic) { mitkIpUInt4_t len; mitkIpUInt4_t tagsLen; tagsLen = _mitkIpPicTagsSize( pic->info->tags_head ); len = tagsLen + 3 * sizeof(mitkIpUInt4_t) + pic->dim * sizeof(mitkIpUInt4_t); /* write oufile */ if( mitkIpPicEncryptionType(pic) == ' ' ) mitkIpPicFWrite( mitkIpPicVERSION, 1, sizeof(mitkIpPicTag_t), outfile ); else mitkIpPicFWrite( pic->info->version, 1, sizeof(mitkIpPicTag_t), outfile ); mitkIpPicFWriteLE( &len, sizeof(mitkIpUInt4_t), 1, outfile ); mitkIpPicFWriteLE( &(pic->type), sizeof(mitkIpUInt4_t), 1, outfile ); mitkIpPicFWriteLE( &(pic->bpe), sizeof(mitkIpUInt4_t), 1, outfile ); mitkIpPicFWriteLE( &(pic->dim), sizeof(mitkIpUInt4_t), 1, outfile ); mitkIpPicFWriteLE( pic->n, sizeof(mitkIpUInt4_t), pic->dim, outfile ); _mitkIpPicWriteTags( pic->info->tags_head, outfile, mitkIpPicEncryptionType(pic) ); pic->info->pixel_start_in_file = ftell( outfile ); } } // end namespace mitk diff --git a/Modules/ToFHardware/mitkToFPicImageWriter.h b/Modules/ToFHardware/mitkToFPicImageWriter.h index 47a94175b4..a12140ccb5 100644 --- a/Modules/ToFHardware/mitkToFPicImageWriter.h +++ b/Modules/ToFHardware/mitkToFPicImageWriter.h @@ -1,91 +1,91 @@ /*========================================================================= 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 __mitkToFPicImageWriter_h #define __mitkToFPicImageWriter_h #include "mitkToFHardwareExports.h" #include "mitkToFImageWriter.h" #include 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 ToFPicImageWriter : public ToFImageWriter { public: ToFPicImageWriter(); ~ToFPicImageWriter(); mitkClassMacro( ToFPicImageWriter , ToFImageWriter ); itkNewMacro( Self ); /*! \brief Open file(s) for writing */ void Open(); /*! \brief Close file(s) add .pic header and write */ void Close(); /*! \brief Add new data to file. */ - void Add(float* distanceFloatData, float* amplitudeFloatData, float* intensityFloatData); + void Add(float* distanceFloatData, float* amplitudeFloatData, float* intensityFloatData, unsigned char* rgbData=0); protected: Image::Pointer m_MitkImage; ///< mitk image used for pic header creation FILE* m_DistanceOutfile; ///< file for distance image FILE* m_AmplitudeOutfile; ///< file for amplitude image FILE* m_IntensityOutfile; ///< file for intensity image private: /*! \brief Open file by filename to gain write access to it. */ void OpenPicFile(FILE** outfile, std::string outfileName); /*! \brief Close file after work on it is finished. */ void ClosePicFile(FILE* outfile); /*! \brief Replace current PicFileHeader information. */ void ReplacePicFileHeader(FILE* outfile); /*! \brief Write image information to the PicFileHeader. */ void WritePicFileHeader(FILE* outfile, mitkIpPicDescriptor* pic); }; } //END mitk namespace #endif // __mitkToFPicImageWriter_h diff --git a/Modules/ToFUI/Qmitk/QmitkToFRecorderWidget.cpp b/Modules/ToFUI/Qmitk/QmitkToFRecorderWidget.cpp index b463a59c0b..faed4a8db5 100644 --- a/Modules/ToFUI/Qmitk/QmitkToFRecorderWidget.cpp +++ b/Modules/ToFUI/Qmitk/QmitkToFRecorderWidget.cpp @@ -1,398 +1,411 @@ /*========================================================================= Program: Medical Imaging & Interaction Toolkit Module: $RCSfile$ Language: C++ Date: $Date: 2009-05-20 13:35:09 +0200 (Mi, 20 Mai 2009) $ Version: $Revision: 17332 $ 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. =========================================================================*/ #define _USE_MATH_DEFINES #include "QmitkToFRecorderWidget.h" //QT headers #include #include #include #include #include #include //mitk headers #include //itk headers #pragma GCC visibility push(default) #include #pragma GCC visibility pop #include struct QFileDialogArgs; class QFileDialogPrivate; const std::string QmitkToFRecorderWidget::VIEW_ID = "org.mitk.views.qmitktofrecorderwidget"; QmitkToFRecorderWidget::QmitkToFRecorderWidget(QWidget* parent, Qt::WindowFlags f): QWidget(parent, f) { this->m_ToFImageRecorder = NULL; this->m_ToFImageGrabber = NULL; this->m_RecordMode = mitk::ToFImageRecorder::PerFrames; this-> m_Controls = NULL; CreateQtPartControl(this); } QmitkToFRecorderWidget::~QmitkToFRecorderWidget() { } void QmitkToFRecorderWidget::CreateQtPartControl(QWidget *parent) { if (!m_Controls) { // create GUI widgets this->m_Controls = new Ui::QmitkToFRecorderWidgetControls; this->m_Controls->setupUi(parent); this->CreateConnections(); } } void QmitkToFRecorderWidget::CreateConnections() { if ( m_Controls ) { connect( (QObject*)(m_Controls->m_PlayButton), SIGNAL(clicked()),(QObject*) this, SLOT(OnPlay()) ); connect( (QObject*)(m_Controls->m_StopButton), SIGNAL(clicked()),(QObject*) this, SLOT(OnStop()) ); connect( (QObject*)(m_Controls->m_StartRecordingButton), SIGNAL(clicked()),(QObject*) this, SLOT(OnStartRecorder()) ); connect( (QObject*)(m_Controls->m_RecordModeComboBox), SIGNAL(currentIndexChanged(int)),(QObject*) this, SLOT(OnChangeRecordModeComboBox(int)) ); connect(this, SIGNAL(RecordingStopped()), this, SLOT(OnRecordingStopped()), Qt::BlockingQueuedConnection); } } void QmitkToFRecorderWidget::SetParameter(mitk::ToFImageGrabber* toFImageGrabber, mitk::ToFImageRecorder* toFImageRecorder) { this->m_ToFImageGrabber = toFImageGrabber; this->m_ToFImageRecorder = toFImageRecorder; this->m_StopRecordingCommand = CommandType::New(); this->m_StopRecordingCommand->SetCallbackFunction(this, &QmitkToFRecorderWidget::StopRecordingCallback); this->m_ToFImageRecorder->RemoveAllObservers(); this->m_ToFImageRecorder->AddObserver(itk::AbortEvent(), this->m_StopRecordingCommand); m_Controls->m_PlayButton->setChecked(false); m_Controls->m_PlayButton->setEnabled(true); m_Controls->m_StartRecordingButton->setChecked(false); m_Controls->m_RecorderGroupBox->setEnabled(true); } void QmitkToFRecorderWidget::StopRecordingCallback() { emit RecordingStopped(); } void QmitkToFRecorderWidget::ResetGUIToInitial() { m_Controls->m_PlayButton->setChecked(false); m_Controls->m_PlayButton->setEnabled(true); m_Controls->m_RecorderGroupBox->setEnabled(false); } void QmitkToFRecorderWidget::OnRecordingStopped() { m_Controls->m_StartRecordingButton->setChecked(false); m_Controls->m_RecorderGroupBox->setEnabled(true); } void QmitkToFRecorderWidget::OnStop() { StopCamera(); StopRecorder(); ResetGUIToInitial(); emit ToFCameraStopped(); } void QmitkToFRecorderWidget::OnPlay() { m_Controls->m_PlayButton->setChecked(true); m_Controls->m_PlayButton->setEnabled(false); m_Controls->m_RecorderGroupBox->setEnabled(true); this->repaint(); StartCamera(); emit ToFCameraStarted(); } void QmitkToFRecorderWidget::StartCamera() { bool ok = false; if (!m_ToFImageGrabber->IsCameraActive()) { m_ToFImageGrabber->StartCamera(); } } void QmitkToFRecorderWidget::StopCamera() { if( m_ToFImageGrabber.IsNotNull() ) m_ToFImageGrabber->StopCamera(); } void QmitkToFRecorderWidget::StopRecorder() { if( m_ToFImageRecorder.IsNotNull() ) { this->m_ToFImageRecorder->StopRecording(); } } void QmitkToFRecorderWidget::OnStartRecorder() { m_Controls->m_StartRecordingButton->setChecked(true); m_Controls->m_RecorderGroupBox->setEnabled(false); this->repaint(); int numOfFrames = m_Controls->m_NumOfFramesSpinBox->value(); try { bool fileOK = true; bool distanceImageSelected = true; bool amplitudeImageSelected = true; bool intensityImageSelected = true; + bool rgbImageSelected = true; bool rawDataSelected = false; QString tmpFileName(""); QString selectedFilter(""); QString imageFileName(""); mitk::ToFImageWriter::ToFImageType tofImageType; tmpFileName = QmitkToFRecorderWidget::getSaveFileName(tofImageType, - distanceImageSelected, amplitudeImageSelected, intensityImageSelected, rawDataSelected, + distanceImageSelected, amplitudeImageSelected, intensityImageSelected, rgbImageSelected, rawDataSelected, NULL, "Save Image To...", imageFileName, "NRRD Images (*.nrrd);;PIC Images - deprecated (*.pic);;Text (*.csv)", &selectedFilter); if (tmpFileName.isEmpty()) { fileOK = false; } else { imageFileName = tmpFileName; } if (fileOK) { std::string dir = itksys::SystemTools::GetFilenamePath( imageFileName.toStdString() ); std::string baseFilename = itksys::SystemTools::GetFilenameWithoutLastExtension( imageFileName.toStdString() ); std::string extension = itksys::SystemTools::GetFilenameLastExtension( imageFileName.toStdString() ); int integrationTime = this->m_ToFImageGrabber->GetIntegrationTime(); int modulationFreq = this->m_ToFImageGrabber->GetModulationFrequency(); QString integrationTimeStr; integrationTimeStr.setNum(integrationTime); QString modulationFreqStr; modulationFreqStr.setNum(modulationFreq); QString numOfFramesStr(""); if (this->m_RecordMode == mitk::ToFImageRecorder::PerFrames) { numOfFramesStr.setNum(numOfFrames); } std::string distImageFileName = prepareFilename(dir, baseFilename, modulationFreqStr.toStdString(), integrationTimeStr.toStdString(), numOfFramesStr.toStdString(), extension, "_DistanceImage"); MITK_INFO << "Save distance data to: " << distImageFileName; std::string amplImageFileName = prepareFilename(dir, baseFilename, modulationFreqStr.toStdString(), integrationTimeStr.toStdString(), numOfFramesStr.toStdString(), extension, "_AmplitudeImage"); MITK_INFO << "Save amplitude data to: " << amplImageFileName; - std::string intenImageFileName = prepareFilename(dir, baseFilename, modulationFreqStr.toStdString(), + std::string intenImageFileName = prepareFilename(dir, baseFilename, modulationFreqStr.toStdString(), integrationTimeStr.toStdString(), numOfFramesStr.toStdString(), extension, "_IntensityImage"); MITK_INFO << "Save intensity data to: " << intenImageFileName; + std::string rgbImageFileName = prepareFilename(dir, baseFilename, modulationFreqStr.toStdString(), + integrationTimeStr.toStdString(), numOfFramesStr.toStdString(), extension, "_RGBImage"); + MITK_INFO << "Save intensity data to: " << rgbImageFileName; + if (selectedFilter.compare("Text (*.csv)") == 0) { this->m_ToFImageRecorder->SetFileFormat(".csv"); } else if (selectedFilter.compare("PIC Images - deprecated (*.pic)") == 0) { //default this->m_ToFImageRecorder->SetFileFormat(".pic"); QMessageBox::warning(NULL, "Deprecated File Format!", "Please note that *.pic file format is deprecated and not longer supported! The suggested file format for images is *.nrrd!"); } else if (selectedFilter.compare("NRRD Images (*.nrrd)") == 0) { this->m_ToFImageRecorder->SetFileFormat(".nrrd"); } else { QMessageBox::warning(NULL, "Unsupported file format!", "Please specify one of the supported file formats *.nrrd, *.csv!"); return; } numOfFrames = m_Controls->m_NumOfFramesSpinBox->value(); this->m_ToFImageRecorder->SetDistanceImageFileName(distImageFileName); this->m_ToFImageRecorder->SetAmplitudeImageFileName(amplImageFileName); this->m_ToFImageRecorder->SetIntensityImageFileName(intenImageFileName); + this->m_ToFImageRecorder->SetRGBImageFileName(rgbImageFileName); this->m_ToFImageRecorder->SetToFImageType(tofImageType); this->m_ToFImageRecorder->SetDistanceImageSelected(distanceImageSelected); this->m_ToFImageRecorder->SetAmplitudeImageSelected(amplitudeImageSelected); this->m_ToFImageRecorder->SetIntensityImageSelected(intensityImageSelected); + this->m_ToFImageRecorder->SetRGBImageSelected(rgbImageSelected); this->m_ToFImageRecorder->SetRecordMode(this->m_RecordMode); this->m_ToFImageRecorder->SetNumOfFrames(numOfFrames); emit RecordingStarted(); this->m_ToFImageRecorder->StartRecording(); } else { this->OnRecordingStopped(); } } catch(std::exception& e) { QMessageBox::critical(NULL, "Error", QString(e.what())); this->OnRecordingStopped(); } } QString QmitkToFRecorderWidget::getSaveFileName(mitk::ToFImageWriter::ToFImageType& tofImageType, bool& distanceImageSelected, bool& amplitudeImageSelected, bool& intensityImageSelected, + bool& rgbImageSelected, bool& rawDataSelected, QWidget *parent, const QString &caption, const QString &dir, const QString &filter, QString *selectedFilter, QFileDialog::Options options ) { QString selectedFileName = ""; QComboBox* combo = new QComboBox; combo->addItem("3D"); combo->addItem("2D + t"); QHBoxLayout* checkBoxGroup = new QHBoxLayout(); QCheckBox* distanceImageCheckBox = new QCheckBox; distanceImageCheckBox->setText("Distance image"); distanceImageCheckBox->setChecked(true); QCheckBox* amplitudeImageCheckBox = new QCheckBox; amplitudeImageCheckBox->setText("Amplitude image"); amplitudeImageCheckBox->setChecked(true); QCheckBox* intensityImageCheckBox = new QCheckBox; intensityImageCheckBox->setText("Intensity image"); intensityImageCheckBox->setChecked(true); + QCheckBox* rgbImageCheckBox = new QCheckBox; + rgbImageCheckBox->setText("RGB image"); + rgbImageCheckBox->setChecked(true); QCheckBox* rawDataCheckBox = new QCheckBox; rawDataCheckBox->setText("Raw data"); rawDataCheckBox->setChecked(false); rawDataCheckBox->setEnabled(false); checkBoxGroup->addWidget(distanceImageCheckBox); checkBoxGroup->addWidget(amplitudeImageCheckBox); checkBoxGroup->addWidget(intensityImageCheckBox); + checkBoxGroup->addWidget(rgbImageCheckBox); checkBoxGroup->addWidget(rawDataCheckBox); QFileDialog* fileDialog = new QFileDialog(parent, caption, dir, filter); QLayout* layout = fileDialog->layout(); QGridLayout* gridbox = qobject_cast(layout); if (gridbox) { gridbox->addWidget(new QLabel("ToF-Image type:")); gridbox->addWidget(combo); int lastRow = gridbox->rowCount(); gridbox->addLayout(checkBoxGroup, lastRow, 0, 1, -1); } fileDialog->setLayout(gridbox); fileDialog->setAcceptMode(QFileDialog::AcceptSave); if (selectedFilter) { fileDialog->selectNameFilter(*selectedFilter); } if (fileDialog->exec() == QDialog::Accepted) { if (selectedFilter) { *selectedFilter = fileDialog->selectedFilter(); } if (combo->currentIndex() == 0) { tofImageType = mitk::ToFImageWriter::ToFImageType3D; } else { tofImageType = mitk::ToFImageWriter::ToFImageType2DPlusT; } distanceImageSelected = distanceImageCheckBox->isChecked(); amplitudeImageSelected = amplitudeImageCheckBox->isChecked(); intensityImageSelected = intensityImageCheckBox->isChecked(); + rgbImageSelected = rgbImageCheckBox->isChecked(); rawDataSelected = rawDataCheckBox->isChecked(); selectedFileName = fileDialog->selectedFiles().value(0); } delete fileDialog; return selectedFileName; } std::string QmitkToFRecorderWidget::prepareFilename(std::string dir, std::string baseFilename, std::string modulationFreq, std::string integrationTime, std::string numOfFrames, std::string extension, std::string imageType) { std::string filenName(""); filenName.append(dir); filenName.append("/"); filenName.append(baseFilename); filenName.append("_MF"); filenName.append(modulationFreq); filenName.append("_IT"); filenName.append(integrationTime); filenName.append("_"); filenName.append(numOfFrames); filenName.append("Images"); filenName.append(imageType); filenName.append(extension); return filenName; } void QmitkToFRecorderWidget::OnChangeRecordModeComboBox(int index) { if (index == 0) { this->m_RecordMode = mitk::ToFImageRecorder::PerFrames; m_Controls->m_NumOfFramesSpinBox->setEnabled(true); } else { this->m_RecordMode = mitk::ToFImageRecorder::Infinite; m_Controls->m_NumOfFramesSpinBox->setEnabled(false); } } diff --git a/Modules/ToFUI/Qmitk/QmitkToFRecorderWidget.h b/Modules/ToFUI/Qmitk/QmitkToFRecorderWidget.h index 213a1f5d32..eca3f58f3e 100644 --- a/Modules/ToFUI/Qmitk/QmitkToFRecorderWidget.h +++ b/Modules/ToFUI/Qmitk/QmitkToFRecorderWidget.h @@ -1,190 +1,191 @@ /*========================================================================= Program: Medical Imaging & Interaction Toolkit Module: $RCSfile$ Language: C++ Date: $Date: 2009-05-20 13:35:09 +0200 (Mi, 20 Mai 2009) $ Version: $Revision: 17332 $ 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 _QMITKTOFRECORDERWIDGET_H_INCLUDED #define _QMITKTOFRECORDERWIDGET_H_INCLUDED #include #include //QT headers #include #include #include #include //itk headers #include "itkCommand.h" //mitk headers #include #include class QmitkStdMultiWidget; struct QFileDialogArgs; class QFileIconProvider; class QFileDialogPrivate; /** * @brief Widget allowing to play / record ToF data * * @ingroup ToFUI */ class mitkTOFUI_EXPORT QmitkToFRecorderWidget :public QWidget { //this is needed for all Qt objects that should have a MOC object (everything that derives from QObject) Q_OBJECT public: static const std::string VIEW_ID; QmitkToFRecorderWidget(QWidget* p = 0, Qt::WindowFlags f1 = 0); virtual ~QmitkToFRecorderWidget(); /* @brief This method is part of the widget an needs not to be called seperately. */ virtual void CreateQtPartControl(QWidget *parent); /* @brief This method is part of the widget an needs not to be called seperately. (Creation of the connections of main and control widget.)*/ virtual void CreateConnections(); /*! \brief Set the parameters used for this widget \param ToFImageGrabber image grabber providing images from a ToF device \param tofImageRecorder image recorder allowing to record ToF images */ void SetParameter(mitk::ToFImageGrabber* ToFImageGrabber, mitk::ToFImageRecorder* toFImageRecorder); /*! \brief resets the GUI elements to the initial state. Play button: enabled, Stop button: disabled, Recording box: disabled */ void ResetGUIToInitial(); signals: /*! \brief signal emitted when "Play" button is pressed */ void ToFCameraStarted(); /*! \brief signal emitted when "Stop" button is pressed */ void ToFCameraStopped(); /*! \brief signal emitted when recording is started */ void RecordingStarted(); /*! \brief signal emitted AbortEvent() in ToFImageRecorder is observed */ void RecordingStopped(); public slots: /*! \brief slot invoking to start the camera. Calls StartCamera() and emits ToFCameraStarted signal */ void OnPlay(); /*! \brief slot invoking to stop the camera and the recorder. Calls StopCamera() and StopRecorder and emits ToFCameraStarted signal. Resets GUI to initial state. */ void OnStop(); /*! \brief slot invoking to start the recording After letting the user chose a file location for the record, m_ImageRecorder->StartRecording() is inoved. */ void OnStartRecorder(); /*! \brief slot resetting the GUI elements of the recording box */ void OnRecordingStopped(); /*! \brief slot activating/deactivating "number of frames" spin box dependent on recording mode (PerFrame / Infinite) */ void OnChangeRecordModeComboBox(int index); protected: /*! \brief starts the camera by calling ToFImageGrabber::StartCamera() */ void StartCamera(); /*! \brief stops the camera by calling ToFImageGrabber::StopCamera() */ void StopCamera(); /*! \brief stops the recording by calling ToFImageRecorder::StopRecording() */ void StopRecorder(); /*! \brief emits RecordingStopped signal. */ void StopRecordingCallback(); /*! \brief adapted version of QFileDialog::getSaveFileName() The user is now asked to choose which images he wants to save (Distance and/or Intensity and/or Amplitude image) and which type the saved image should have (3D, 2D+t). */ static QString getSaveFileName(mitk::ToFImageWriter::ToFImageType& tofImageType, bool& distanceImageSelected, bool& amplitudeImageSelected, bool& intensityImageSelected, + bool& rgbImageSelected, bool& rawDataSelected, QWidget *parent = 0, const QString &caption = QString(), const QString &dir = QString(), const QString &filter = QString(), QString *selectedFilter = 0, QFileDialog::Options options = 0 ); /*! \brief method creating a filename from the given information \param dir directory to save the file \param baseFilename base file name entered by the user \param modulationFreq modulation frequency of the camera \param integrationTime integration time of the camera \param numOfFrames number of frames recorded \param extension file extension \param imageType type of image (DistanceImage, IntensityImage, AmplitudeImage) \return dir+"/"+baseFilename+"_MF"+modulationFreq+"_IT"+integrationTime+"_"+numOfFrames+"Images"+imageType+extension */ std::string prepareFilename(std::string dir, std::string baseFilename, std::string modulationFreq, std::string integrationTime, std::string numOfFrames, std::string extension, std::string imageType); Ui::QmitkToFRecorderWidgetControls* m_Controls; ///< member holding the UI elements of this widget mitk::ToFImageGrabber::Pointer m_ToFImageGrabber; ///< member holding the ToFImageGrabber for acquiring ToF images mitk::ToFImageRecorder::Pointer m_ToFImageRecorder; ///< member holding the recorder for ToF images mitk::ToFImageRecorder::RecordMode m_RecordMode; ///< member holding the RecordMode of the recorder (PerFrame / Infinite) typedef itk::SimpleMemberCommand CommandType; CommandType::Pointer m_StopRecordingCommand; ///< itkCommand for abort of recording private: }; #endif // _QMITKTOFRECORDERWIDGET_H_INCLUDED