diff --git a/Modules/ToFHardware/mitkToFImageRecorder.cpp b/Modules/ToFHardware/mitkToFImageRecorder.cpp index a2db8c7f7d..74761c10d5 100644 --- a/Modules/ToFHardware/mitkToFImageRecorder.cpp +++ b/Modules/ToFHardware/mitkToFImageRecorder.cpp @@ -1,315 +1,267 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "mitkToFImageRecorder.h" -#include "mitkRealTimeClock.h" -#include "itkMultiThreader.h" +#include +#include #include #pragma GCC visibility push(default) #include #pragma GCC visibility pop namespace mitk { - ToFImageRecorder::ToFImageRecorder() +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 = 1; //lets record one frame per default + this->m_ToFImageWriter = NULL; + this->m_DistanceImageSelected = true; //lets assume a device only has depth data by default + this->m_AmplitudeImageSelected = false; + this->m_IntensityImageSelected = false; + this->m_RGBImageSelected = false; + this->m_Abort = false; + this->m_ToFCaptureWidth = 0; + this->m_ToFCaptureHeight = 0; + this->m_RGBCaptureWidth = 0; + this->m_RGBCaptureHeight = 0; + this->m_FileFormat = ".nrrd"; //lets make nrrd the default + this->m_ToFPixelNumber = 0; + this->m_RGBPixelNumber = 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()) { - this->m_ToFCameraDevice = NULL; - this->m_MultiThreader = itk::MultiThreader::New(); - this->m_AbortMutex = itk::FastMutexLock::New(); - this->m_ThreadID = 0; - this->m_NumOfFrames = 1; //lets record one frame per default - this->m_ToFImageWriter = NULL; - this->m_DistanceImageSelected = true; //lets assume a device only has depth data by default - this->m_AmplitudeImageSelected = false; - this->m_IntensityImageSelected = false; - this->m_RGBImageSelected = false; - this->m_Abort = false; - this->m_ToFCaptureWidth = 0; - this->m_ToFCaptureHeight = 0; - this->m_RGBCaptureWidth = 0; - this->m_RGBCaptureHeight = 0; - this->m_FileFormat = ".nrrd"; //lets make nrrd the default - this->m_ToFPixelNumber = 0; - this->m_RGBPixelNumber = 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; + throw std::invalid_argument("ToFCameraDevice is NULL."); + return; } - - ToFImageRecorder::~ToFImageRecorder() + if (this->m_FileFormat.compare(".csv") == 0) { - delete[] m_DistanceArray; - delete[] m_AmplitudeArray; - delete[] m_IntensityArray; - delete[] m_RGBArray; - delete[] m_SourceDataArray; + this->m_ToFImageWriter = ToFImageCsvWriter::New(); } - - void ToFImageRecorder::StopRecording() + else if(this->m_FileFormat.compare(".nrrd") == 0) + { + this->m_ToFImageWriter = ToFNrrdImageWriter::New(); + this->m_ToFImageWriter->SetExtension(m_FileFormat); + } + else { + throw std::logic_error("No file format specified!"); + } - this->m_AbortMutex->Lock(); - this->m_Abort = true; - this->m_AbortMutex->Unlock(); + this->m_RGBCaptureWidth = this->m_ToFCameraDevice->GetRGBCaptureWidth(); + this->m_RGBCaptureHeight = this->m_ToFCameraDevice->GetRGBCaptureHeight(); + this->m_RGBPixelNumber = this->m_RGBCaptureWidth * this->m_RGBCaptureHeight; - } + this->m_ToFCaptureWidth = this->m_ToFCameraDevice->GetCaptureWidth(); + this->m_ToFCaptureHeight = this->m_ToFCameraDevice->GetCaptureHeight(); + this->m_ToFPixelNumber = this->m_ToFCaptureWidth * this->m_ToFCaptureHeight; + + this->m_SourceDataSize = this->m_ToFCameraDevice->GetSourceDataSize(); - void ToFImageRecorder::StartRecording() + // allocate buffer + if(m_IntensityArray == NULL) { - 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 - { - throw std::logic_error("No file format specified!"); - } + this->m_IntensityArray = new float[m_ToFPixelNumber]; + } + if(this->m_DistanceArray == NULL) + { + this->m_DistanceArray = new float[m_ToFPixelNumber]; + } + if(this->m_AmplitudeArray == NULL) + { + this->m_AmplitudeArray = new float[m_ToFPixelNumber]; + } + if(this->m_RGBArray == NULL) + { + this->m_RGBArray = new unsigned char[m_RGBPixelNumber*3]; + } + if(this->m_SourceDataArray == NULL) + { + this->m_SourceDataArray = new char[m_SourceDataSize]; + } - this->m_RGBCaptureWidth = this->m_ToFCameraDevice->GetRGBCaptureWidth(); - this->m_RGBCaptureHeight = this->m_ToFCameraDevice->GetRGBCaptureHeight(); - this->m_RGBPixelNumber = this->m_RGBCaptureWidth * this->m_RGBCaptureHeight; + 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->SetRGBCaptureWidth(this->m_RGBCaptureWidth); + this->m_ToFImageWriter->SetRGBCaptureHeight(this->m_RGBCaptureHeight); + this->m_ToFImageWriter->SetToFCaptureWidth(this->m_ToFCaptureWidth); + this->m_ToFImageWriter->SetToFCaptureHeight(this->m_ToFCaptureHeight); + 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); +} - this->m_ToFCaptureWidth = this->m_ToFCameraDevice->GetCaptureWidth(); - this->m_ToFCaptureHeight = this->m_ToFCameraDevice->GetCaptureHeight(); - this->m_ToFPixelNumber = this->m_ToFCaptureWidth * this->m_ToFCaptureHeight; +void ToFImageRecorder::WaitForThreadBeingTerminated() +{ + this->m_MultiThreader->TerminateThread(this->m_ThreadID); +} - this->m_SourceDataSize = this->m_ToFCameraDevice->GetSourceDataSize(); +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) + { - // allocate buffer - if(m_IntensityArray == NULL) - { - this->m_IntensityArray = new float[m_ToFPixelNumber]; - } - if(this->m_DistanceArray == NULL) - { - this->m_DistanceArray = new float[m_ToFPixelNumber]; - } - if(this->m_AmplitudeArray == NULL) - { - this->m_AmplitudeArray = new float[m_ToFPixelNumber]; - } - if(this->m_RGBArray == NULL) - { - this->m_RGBArray = new unsigned char[m_RGBPixelNumber*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->SetRGBCaptureWidth(this->m_RGBCaptureWidth); - this->m_ToFImageWriter->SetRGBCaptureHeight(this->m_RGBCaptureHeight); - //this->m_ToFImageWriter->SetToFCaptureHeight(this->m_ToFCaptureHeight); - this->m_ToFImageWriter->SetToFCaptureWidth(this->m_ToFCaptureWidth); - this->m_ToFImageWriter->SetToFCaptureHeight(this->m_ToFCaptureHeight); - 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); - - ToFCameraDevice::Pointer toFCameraDevice = this->GetCameraDevice(); + 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; - this->m_AbortMutex->Lock(); - abort = this->m_Abort; - this->m_AbortMutex->Unlock(); - + toFImageRecorder->m_AbortMutex->Lock(); + abort = toFImageRecorder->m_Abort; + toFImageRecorder->m_AbortMutex->Unlock(); while ( !abort ) { - if ( ((this->m_RecordMode == ToFImageRecorder::PerFrames) && (numOfFramesRecorded < this->m_NumOfFrames)) || - (this->m_RecordMode == ToFImageRecorder::Infinite) ) + if ( ((toFImageRecorder->m_RecordMode == ToFImageRecorder::PerFrames) && (numOfFramesRecorded < toFImageRecorder->m_NumOfFrames)) || + (toFImageRecorder->m_RecordMode == ToFImageRecorder::Infinite) ) { - toFCameraDevice->GetAllImages(this->m_DistanceArray, this->m_AmplitudeArray, - this->m_IntensityArray, this->m_SourceDataArray, requiredImageSequence, this->m_ImageSequence, this->m_RGBArray ); + toFCameraDevice->GetAllImages(toFImageRecorder->m_DistanceArray, toFImageRecorder->m_AmplitudeArray, + toFImageRecorder->m_IntensityArray, toFImageRecorder->m_SourceDataArray, requiredImageSequence, toFImageRecorder->m_ImageSequence, toFImageRecorder->m_RGBArray ); - if (this->m_ImageSequence >= requiredImageSequence) + if (toFImageRecorder->m_ImageSequence >= requiredImageSequence) { - if (this->m_ImageSequence > requiredImageSequence) + if (toFImageRecorder->m_ImageSequence > requiredImageSequence) { - MITK_INFO << "Problem! required: " << requiredImageSequence << " captured: " << this->m_ImageSequence; + MITK_INFO << "Problem! required: " << requiredImageSequence << " captured: " << toFImageRecorder->m_ImageSequence; } - requiredImageSequence = this->m_ImageSequence + 1; - this->m_ToFImageWriter->Add( this->m_DistanceArray, - this->m_AmplitudeArray, this->m_IntensityArray, this->m_RGBArray ); + requiredImageSequence = toFImageRecorder->m_ImageSequence + 1; + toFImageRecorder->m_ToFImageWriter->Add( toFImageRecorder->m_DistanceArray, + 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; + } } - this->m_AbortMutex->Lock(); - abort = this->m_Abort; - this->m_AbortMutex->Unlock(); + toFImageRecorder->m_AbortMutex->Lock(); + abort = toFImageRecorder->m_Abort; + toFImageRecorder->m_AbortMutex->Unlock(); } else { abort = true; } } // end of while loop - this->InvokeEvent(itk::AbortEvent()); - - this->m_ToFImageWriter->Close(); - } - - void ToFImageRecorder::WaitForThreadBeingTerminated() - { - this->m_MultiThreader->TerminateThread(this->m_ThreadID); - } - - 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) - { + toFImageRecorder->InvokeEvent(itk::AbortEvent()); - 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 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_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; + toFImageRecorder->m_ToFImageWriter->Close(); } + return ITK_THREAD_RETURN_VALUE; +} - void ToFImageRecorder::SetCameraDevice(ToFCameraDevice* aToFCameraDevice) - { - this->m_ToFCameraDevice = aToFCameraDevice; - } +void ToFImageRecorder::SetCameraDevice(ToFCameraDevice* aToFCameraDevice) +{ + this->m_ToFCameraDevice = aToFCameraDevice; +} - ToFCameraDevice* ToFImageRecorder::GetCameraDevice() - { - return this->m_ToFCameraDevice; - } +ToFCameraDevice* ToFImageRecorder::GetCameraDevice() +{ + return this->m_ToFCameraDevice; +} - ToFImageWriter::ToFImageType ToFImageRecorder::GetToFImageType() - { - return this->m_ToFImageType; - } +ToFImageWriter::ToFImageType ToFImageRecorder::GetToFImageType() +{ + return this->m_ToFImageType; +} - void ToFImageRecorder::SetToFImageType(ToFImageWriter::ToFImageType toFImageType) - { - this->m_ToFImageType = toFImageType; - } +void ToFImageRecorder::SetToFImageType(ToFImageWriter::ToFImageType toFImageType) +{ + this->m_ToFImageType = toFImageType; +} - ToFImageRecorder::RecordMode ToFImageRecorder::GetRecordMode() - { - return this->m_RecordMode; - } +ToFImageRecorder::RecordMode ToFImageRecorder::GetRecordMode() +{ + return this->m_RecordMode; +} - void ToFImageRecorder::SetRecordMode(ToFImageRecorder::RecordMode recordMode) - { - this->m_RecordMode = recordMode; - } +void ToFImageRecorder::SetRecordMode(ToFImageRecorder::RecordMode recordMode) +{ + this->m_RecordMode = recordMode; +} } diff --git a/Modules/ToFHardware/mitkToFImageRecorder.h b/Modules/ToFHardware/mitkToFImageRecorder.h index 27da67012d..3efd126acf 100644 --- a/Modules/ToFHardware/mitkToFImageRecorder.h +++ b/Modules/ToFHardware/mitkToFImageRecorder.h @@ -1,176 +1,180 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ -#ifndef __mitkToFImageRecorder_h -#define __mitkToFImageRecorder_h +#ifndef mitkToFImageRecorder_h +#define mitkToFImageRecorder_h -#include -#include "mitkCommon.h" +#include "MitkToFHardwareExports.h" +#include #include "mitkToFCameraDevice.h" #include "mitkToFImageCsvWriter.h" #include "mitkToFNrrdImageWriter.h" -#include "itkObject.h" -#include "itkObjectFactory.h" -#include "itkFastMutexLock.h" -#include "itkCommand.h" +#include +#include +#include +#include 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 + * Recording can be performed either frame-based or continuously. + * + * @warning It is currently not guaranteed that all acquired images are recorded, since the recording + * is done in a newly spawned thread. However, in practise only very few images are lost. See bug #12997 + * for more details. * * @ingroup ToFHardware */ - class MITK_TOFHARDWARE_EXPORT ToFImageRecorder : public itk::Object - { - public: - - ToFImageRecorder(); - - ~ToFImageRecorder(); - - mitkClassMacro( ToFImageRecorder , itk::Object ); - - itkFactorylessNewMacro(Self) - itkCloneMacro(Self) - - itkGetMacro( DistanceImageFileName, std::string ); - itkGetMacro( AmplitudeImageFileName, std::string ); - itkGetMacro( IntensityImageFileName, std::string ); - itkGetMacro( RGBImageFileName, std::string ); - itkGetMacro( ToFCaptureWidth, int ); - itkGetMacro( ToFCaptureHeight, int ); - itkGetMacro( RGBCaptureWidth, int ); - itkGetMacro( RGBCaptureHeight, 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 }; - /*! +class MITK_TOFHARDWARE_EXPORT ToFImageRecorder : public itk::Object +{ +public: + + ToFImageRecorder(); + + ~ToFImageRecorder(); + + mitkClassMacro( ToFImageRecorder , itk::Object ); + + itkFactorylessNewMacro(Self) + itkCloneMacro(Self) + + itkGetMacro( DistanceImageFileName, std::string ); + itkGetMacro( AmplitudeImageFileName, std::string ); + itkGetMacro( IntensityImageFileName, std::string ); + itkGetMacro( RGBImageFileName, std::string ); + itkGetMacro( ToFCaptureWidth, int ); + itkGetMacro( ToFCaptureHeight, int ); + itkGetMacro( RGBCaptureWidth, int ); + itkGetMacro( RGBCaptureHeight, 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(); - /*! + 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); - /*! + void SetRecordMode(ToFImageRecorder::RecordMode recordMode); + /*! \brief Set the device used for acquiring ToF images \param aToFCameraDevice ToF camera device used. */ - void SetCameraDevice(ToFCameraDevice* aToFCameraDevice); - /*! + void SetCameraDevice(ToFCameraDevice* aToFCameraDevice); + /*! \brief Get the device used for acquiring ToF images \return ToF camera device used. */ - ToFCameraDevice* GetCameraDevice(); - /*! + ToFCameraDevice* GetCameraDevice(); + /*! \brief Get the type of image to be recorded \return ToF image type: ToFImageType3D (0) or ToFImageType2DPlusT (1) */ - ToFImageWriter::ToFImageType GetToFImageType(); - /*! + 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); - /*! + 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(); - /*! + void StartRecording(); + /*! \brief Stops the recording by setting the m_Abort flag to false */ - void StopRecording(); - /*! + void StopRecording(); + /*! \brief Wait until thread is terinated */ - void WaitForThreadBeingTerminated(); + void WaitForThreadBeingTerminated(); - protected: +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_ToFCaptureWidth; ///< width (x-dimension) of the images to record. - int m_ToFCaptureHeight; ///< height (y-dimension) of the images to record. - int m_ToFPixelNumber; ///< number of pixels (widht*height) of the images to record - int m_RGBCaptureWidth; ///< width (x-dimension) of the images to record. - int m_RGBCaptureHeight; ///< height (y-dimension) of the images to record. - int m_RGBPixelNumber; ///< 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: - - }; + static ITK_THREAD_RETURN_TYPE RecordData(void* pInfoStruct); + + // data acquisition + ToFCameraDevice::Pointer m_ToFCameraDevice; ///< ToFCameraDevice used for acquiring the images + int m_ToFCaptureWidth; ///< width (x-dimension) of the images to record. + int m_ToFCaptureHeight; ///< height (y-dimension) of the images to record. + int m_ToFPixelNumber; ///< number of pixels (widht*height) of the images to record + int m_RGBCaptureWidth; ///< width (x-dimension) of the images to record. + int m_RGBCaptureHeight; ///< height (y-dimension) of the images to record. + int m_RGBPixelNumber; ///< 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 +#endif //mitkToFImageRecorder_h