diff --git a/Modules/Bundles/org.mitk.gui.qt.toftutorial/src/internal/QmitkToFTutorialView.cpp b/Modules/Bundles/org.mitk.gui.qt.toftutorial/src/internal/QmitkToFTutorialView.cpp index b7db784681..53003d3d27 100644 --- a/Modules/Bundles/org.mitk.gui.qt.toftutorial/src/internal/QmitkToFTutorialView.cpp +++ b/Modules/Bundles/org.mitk.gui.qt.toftutorial/src/internal/QmitkToFTutorialView.cpp @@ -1,193 +1,200 @@ /*========================================================================= Program: Medical Imaging & Interaction Toolkit Language: C++ Date: $Date$ 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. =========================================================================*/ // Blueberry #include #include // Qmitk #include "QmitkToFTutorialView.h" #include "QmitkStdMultiWidget.h" // Qt #include // mitk includes #include // class holding the intrinsic parameters of the according camera #include // MITK-ToF related includes #include // configuration file holding e.g. plugin paths or path to test file directory #include // filter from module ToFProcessing that calculates a surface from the given range image #include // creator class that provides pre-configured ToFCameraDevices #include // allows access to images provided by the ToF camera const std::string QmitkToFTutorialView::VIEW_ID = "org.mitk.views.toftutorial"; QmitkToFTutorialView::QmitkToFTutorialView() : QmitkFunctionality() , m_Controls( 0 ) , m_MultiWidget( NULL ) { } QmitkToFTutorialView::~QmitkToFTutorialView() { } void QmitkToFTutorialView::CreateQtPartControl( QWidget *parent ) { // build up qt view, unless already done if ( !m_Controls ) { // create GUI widgets from the Qt Designer's .ui file m_Controls = new Ui::QmitkToFTutorialViewControls; m_Controls->setupUi( parent ); connect( m_Controls->step1Button, SIGNAL(clicked()), this, SLOT(OnStep1()) ); connect( m_Controls->step2Button, SIGNAL(clicked()), this, SLOT(OnStep2()) ); } } void QmitkToFTutorialView::StdMultiWidgetAvailable (QmitkStdMultiWidget &stdMultiWidget) { m_MultiWidget = &stdMultiWidget; } void QmitkToFTutorialView::StdMultiWidgetNotAvailable() { m_MultiWidget = NULL; } void QmitkToFTutorialView::OnStep1() { // clean up data storage RemoveAllNodesFromDataStorage(); // use ToFImageGrabber to create instance of ToFImageGrabber that holds a ToFCameraMITKPlayerDevice for playing ToF data mitk::ToFImageGrabber::Pointer tofImageGrabber = mitk::ToFImageGrabberCreator::GetInstance()->GetMITKPlayerImageGrabber(); // set paths to test data std::string distanceFileName = MITK_TOF_DATA_DIR; distanceFileName.append("/PMDCamCube2_MF0_IT0_20Images_DistanceImage.pic"); std::string amplitudeFileName = MITK_TOF_DATA_DIR; amplitudeFileName.append("/PMDCamCube2_MF0_IT0_20Images_AmplitudeImage.pic"); std::string intensityFileName = MITK_TOF_DATA_DIR; intensityFileName.append("/PMDCamCube2_MF0_IT0_20Images_IntensityImage.pic"); // set file name property in image grabber. This will be propagated to the corresponding device and controller class tofImageGrabber->SetProperty("DistanceImageFileName",mitk::StringProperty::New(distanceFileName)); tofImageGrabber->SetProperty("AmplitudeImageFileName",mitk::StringProperty::New(amplitudeFileName)); tofImageGrabber->SetProperty("IntensityImageFileName",mitk::StringProperty::New(intensityFileName)); // connect to device if (tofImageGrabber->ConnectCamera()) { //// start camera (internally starts thread that continuously grabs images from the camera) tofImageGrabber->StartCamera(); // update image grabber which itself represents the source of a MITK filter pipeline tofImageGrabber->Update(); // grab distance image mitk::Image::Pointer distanceImage = tofImageGrabber->GetOutput(0); // grab amplitude image mitk::Image::Pointer amplitudeImage = tofImageGrabber->GetOutput(1); // grab intensity image mitk::Image::Pointer intensityImage = tofImageGrabber->GetOutput(2); //add distance image to data storage mitk::DataNode::Pointer distanceNode = mitk::DataNode::New(); distanceNode->SetName("Distance Image"); distanceNode->SetData(distanceImage); this->GetDefaultDataStorage()->Add(distanceNode); //add amplitude image to data storage mitk::DataNode::Pointer amplitudeNode = mitk::DataNode::New(); amplitudeNode->SetName("Amplitude Image"); amplitudeNode->SetData(amplitudeImage); this->GetDefaultDataStorage()->Add(amplitudeNode); //add intensity image to data storage mitk::DataNode::Pointer intensityNode = mitk::DataNode::New(); intensityNode->SetName("Intensity Image"); intensityNode->SetData(intensityImage); this->GetDefaultDataStorage()->Add(intensityNode); // stop camera (terminate internally used thread) tofImageGrabber->StopCamera(); - // disconnect from camera + //// disconnect from camera tofImageGrabber->DisconnectCamera(); // adjust views to new data in DataStorage mitk::RenderingManager::GetInstance()->InitializeViews(distanceImage->GetGeometry()); } else { MITK_ERROR<<"Connection to ToF camera could not be established"; } } void QmitkToFTutorialView::OnStep2() { // Check if distance image is available mitk::DataNode::Pointer distanceNode = this->GetDefaultDataStorage()->GetNamedNode("Distance Image"); if (distanceNode.IsNotNull()) { // get distance image from node and check if node contains image mitk::Image::Pointer distanceImage = dynamic_cast(distanceNode->GetData()); if (distanceImage.IsNotNull()) { // create object of CameraIntrinsics that holds intrinsic parameters of the ToF camera mitk::CameraIntrinsics::Pointer cameraIntrinsics = mitk::CameraIntrinsics::New(); - // change focal length and use defaults for other parameters such as inter pixel distance or principal point - cameraIntrinsics->SetFocalLength(13.3,13.3); + // set focal length in pixel + cameraIntrinsics->SetFocalLength(295.8,296.1); + // set principal point in pixel + cameraIntrinsics->SetPrincipalPoint(113.2,97.1); // set up filter for surface calculation mitk::ToFDistanceImageToSurfaceFilter::Pointer surfaceFilter = mitk::ToFDistanceImageToSurfaceFilter::New(); // apply intrinsic parameters to filter surfaceFilter->SetCameraIntrinsics(cameraIntrinsics); + // set distance between pixels on chip in mm (in this example squared pixel) + mitk::ToFProcessingCommon::ToFPoint2D interPixelDistance; + interPixelDistance[0] = 0.045; + interPixelDistance[1] = 0.045; + surfaceFilter->SetInterPixelDistance(interPixelDistance); // set distance image as input surfaceFilter->SetInput(distanceImage); // update the filter surfaceFilter->Update(); // get surface from filter mitk::Surface::Pointer surface = surfaceFilter->GetOutput(); // add surface to data storage mitk::DataNode::Pointer surfaceNode = mitk::DataNode::New(); surfaceNode->SetName("ToF surface"); surfaceNode->SetData(surface); this->GetDefaultDataStorage()->Add(surfaceNode); // adjust views to new data in DataStorage mitk::RenderingManager::GetInstance()->InitializeViews(surface->GetGeometry()); mitk::RenderingManager::GetInstance()->InitializeViews(surface->GetGeometry()); } else { QMessageBox::warning(NULL,"ToF Tutorial","Node 'Distance Image' contains no image"); } } else { QMessageBox::warning(NULL,"ToF Tutorial","Perform Step 1 first to acquire a distance image"); } } void QmitkToFTutorialView::RemoveAllNodesFromDataStorage() { mitk::DataStorage::SetOfObjects::ConstPointer allNodes = this->GetDefaultDataStorage()->GetAll(); this->GetDefaultDataStorage()->Remove(allNodes); } diff --git a/Modules/ToFHardware/mitkToFCameraDevice.cpp b/Modules/ToFHardware/mitkToFCameraDevice.cpp index 5c11df0b8f..4fe8068c55 100644 --- a/Modules/ToFHardware/mitkToFCameraDevice.cpp +++ b/Modules/ToFHardware/mitkToFCameraDevice.cpp @@ -1,106 +1,136 @@ /*========================================================================= 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 "mitkToFCameraDevice.h" namespace mitk { ToFCameraDevice::ToFCameraDevice():m_CaptureWidth(204),m_CaptureHeight(204),m_PixelNumber(41616),m_SourceDataSize(0),m_CameraActive(false), m_ThreadID(0),m_CameraConnected(false),m_MaxBufferSize(100),m_BufferSize(1),m_CurrentPos(-1),m_FreePos(0),m_ImageSequence(0) { this->m_AmplitudeArray = NULL; this->m_IntensityArray = NULL; this->m_DistanceArray = NULL; this->m_PropertyList = mitk::PropertyList::New(); this->m_MultiThreader = itk::MultiThreader::New(); this->m_ImageMutex = itk::FastMutexLock::New(); this->m_CameraActiveMutex = itk::FastMutexLock::New(); } ToFCameraDevice::~ToFCameraDevice() { + CleanupPixelArrays(); } void ToFCameraDevice::SetBoolProperty( const char* propertyKey, bool boolValue ) { SetProperty(propertyKey, mitk::BoolProperty::New(boolValue)); } void ToFCameraDevice::SetIntProperty( const char* propertyKey, int intValue ) { SetProperty(propertyKey, mitk::IntProperty::New(intValue)); } void ToFCameraDevice::SetFloatProperty( const char* propertyKey, float floatValue ) { SetProperty(propertyKey, mitk::FloatProperty::New(floatValue)); } void ToFCameraDevice::SetStringProperty( const char* propertyKey, const char* stringValue ) { SetProperty(propertyKey, mitk::StringProperty::New(stringValue)); } void ToFCameraDevice::SetProperty( const char *propertyKey, BaseProperty* propertyValue ) { this->m_PropertyList->SetProperty(propertyKey, propertyValue); } BaseProperty* ToFCameraDevice::GetProperty(const char *propertyKey) { return this->m_PropertyList->GetProperty(propertyKey); } bool ToFCameraDevice::GetBoolProperty(BaseProperty* propertyValue, bool& boolValue) { mitk::BoolProperty::Pointer boolprop = dynamic_cast(propertyValue); if(boolprop.IsNull()) return false; boolValue = boolprop->GetValue(); return true; } bool ToFCameraDevice::GetStringProperty(BaseProperty* propertyValue, std::string& string) { mitk::StringProperty::Pointer stringProp = dynamic_cast(propertyValue); if(stringProp.IsNull()) { return false; } else { string = stringProp->GetValue(); return true; } } bool ToFCameraDevice::GetIntProperty(BaseProperty* propertyValue, int& integer) { mitk::IntProperty::Pointer intProp = dynamic_cast(propertyValue); if(intProp.IsNull()) { return false; } else { integer = intProp->GetValue(); return true; } } + + void ToFCameraDevice::CleanupPixelArrays() + { + if (m_IntensityArray) + { + delete [] m_IntensityArray; + } + if (m_DistanceArray) + { + delete [] m_DistanceArray; + } + if (m_AmplitudeArray) + { + delete [] m_AmplitudeArray; + } + } + + void ToFCameraDevice::AllocatePixelArrays() + { + // free memory if it was already allocated + CleanupPixelArrays(); + // allocate buffer + this->m_IntensityArray = new float[this->m_PixelNumber]; + for(int i=0; im_PixelNumber; i++) {this->m_IntensityArray[i]=0.0;} + this->m_DistanceArray = new float[this->m_PixelNumber]; + for(int i=0; im_PixelNumber; i++) {this->m_DistanceArray[i]=0.0;} + this->m_AmplitudeArray = new float[this->m_PixelNumber]; + for(int i=0; im_PixelNumber; i++) {this->m_AmplitudeArray[i]=0.0;} + } } diff --git a/Modules/ToFHardware/mitkToFCameraDevice.h b/Modules/ToFHardware/mitkToFCameraDevice.h index 233345fc18..cb447e2910 100644 --- a/Modules/ToFHardware/mitkToFCameraDevice.h +++ b/Modules/ToFHardware/mitkToFCameraDevice.h @@ -1,208 +1,217 @@ /*========================================================================= 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 __mitkToFCameraDevice_h #define __mitkToFCameraDevice_h #include "mitkToFHardwareExports.h" #include "mitkCommon.h" #include "mitkStringProperty.h" #include "mitkProperties.h" #include "mitkPropertyList.h" #include "itkObject.h" #include "itkObjectFactory.h" #include "itkMultiThreader.h" #include "itkFastMutexLock.h" namespace mitk { /** * @brief Virtual interface and base class for all Time-of-Flight devices. * * @ingroup ToFHardware */ class MITK_TOFHARDWARE_EXPORT ToFCameraDevice : public itk::Object { public: mitkClassMacro(ToFCameraDevice, itk::Object); /*! \brief opens a connection to the ToF camera */ virtual bool ConnectCamera() = 0; /*! \brief closes the connection to the camera */ virtual bool DisconnectCamera() = 0; /*! \brief starts the continuous updating of the camera. A separate thread updates the source data, the main thread processes the source data and creates images and coordinates */ virtual void StartCamera() = 0; /*! \brief stops the continuous updating of the camera */ virtual void StopCamera() = 0; /*! \brief returns true if the camera is connected and started */ virtual bool IsCameraActive() = 0; /*! \brief updates the camera for image acquisition */ virtual void UpdateCamera() = 0; /*! \brief gets the amplitude data from the ToF camera as the strength of the active illumination of every pixel These values can be used to determine the quality of the distance values. The higher the amplitude value, the higher the accuracy of the according distance value \param imageSequence the actually captured image sequence number \param amplitudeArray contains the returned amplitude data as an array. */ virtual void GetAmplitudes(float* amplitudeArray, int& imageSequence) = 0; /*! \brief gets the intensity data from the ToF camera as a greyscale image \param intensityArray contains the returned intensities data as an array. \param imageSequence the actually captured image sequence number */ virtual void GetIntensities(float* intensityArray, int& imageSequence) = 0; /*! \brief gets the distance data from the ToF camera measuring the distance between the camera and the different object points in millimeters \param distanceArray contains the returned distances data as an array. \param imageSequence the actually captured image sequence number */ virtual void GetDistances(float* distanceArray, int& imageSequence) = 0; /*! \brief gets the 3 images (distance, amplitude, intensity) from the ToF camera. Caution! The user is responsible for allocating and deleting the images. \param distanceArray contains the returned distance data as an array. \param amplitudeArray contains the returned amplitude data as an array. \param intensityArray contains the returned intensity data as an array. \param sourceDataArray contains the complete source data from the camera device. \param requiredImageSequence the required image sequence number \param capturedImageSequence the actually captured image sequence number */ virtual void GetAllImages(float* distanceArray, float* amplitudeArray, float* intensityArray, char* sourceDataArray, int requiredImageSequence, int& capturedImageSequence) = 0; // TODO: Buffer size currently set to 1. Once Buffer handling is working correctly, method may be reactivated // /*! // \brief pure virtual method resetting the buffer using the specified bufferSize. Has to be implemented by sub-classes // \param bufferSize buffer size the buffer should be reset to // */ // virtual void ResetBuffer(int bufferSize) = 0; //TODO add/correct documentation for requiredImageSequence and capturedImageSequence in the GetAllImages, GetDistances, GetIntensities and GetAmplitudes methods. /*! \brief get the currently set capture width \return capture width */ itkGetMacro(CaptureWidth, int); /*! \brief get the currently set capture height \return capture height */ itkGetMacro(CaptureHeight, int); /*! \brief get the currently set source data size \return source data size */ itkGetMacro(SourceDataSize, int); /*! \brief get the currently set buffer size \return buffer size */ itkGetMacro(BufferSize, int); /*! \brief get the currently set max buffer size \return max buffer size */ itkGetMacro(MaxBufferSize, int); /*! \brief set a bool property in the property list */ void SetBoolProperty( const char* propertyKey, bool boolValue ); /*! \brief set an int property in the property list */ void SetIntProperty( const char* propertyKey, int intValue ); /*! \brief set a float property in the property list */ void SetFloatProperty( const char* propertyKey, float floatValue ); /*! \brief set a string property in the property list */ void SetStringProperty( const char* propertyKey, const char* stringValue ); /*! \brief set a BaseProperty property in the property list */ virtual void SetProperty( const char *propertyKey, BaseProperty* propertyValue ); /*! \brief get a BaseProperty from the property list */ virtual BaseProperty* GetProperty( const char *propertyKey ); /*! \brief get a bool from the property list */ static bool GetBoolProperty(BaseProperty* propertyValue, bool& boolValue); /*! \brief get a string from the property list */ static bool GetStringProperty(BaseProperty* propertyValue, std::string& string); /*! \brief get an int from the property list */ static bool GetIntProperty(BaseProperty* propertyValue, int& integer); protected: ToFCameraDevice(); ~ToFCameraDevice(); + /*! + \brief method for allocating memory for pixel arrays m_IntensityArray, m_DistanceArray and m_AmplitudeArray + */ + virtual void AllocatePixelArrays(); + /*! + \brief method for cleanup memory allocated for pixel arrays m_IntensityArray, m_DistanceArray and m_AmplitudeArray + */ + virtual void CleanupPixelArrays(); + float* m_IntensityArray; ///< float array holding the intensity image float* m_DistanceArray; ///< float array holding the distance image float* m_AmplitudeArray; ///< float array holding the amplitude image int m_BufferSize; ///< buffer size of the image buffer needed for loss-less acquisition of range data int m_MaxBufferSize; ///< maximal buffer size needed for initialization of data arrays. Default value is 100. int m_CurrentPos; ///< current position in the buffer which will be retrieved by the Get methods int m_FreePos; ///< current position in the buffer which will be filled with data acquired from the hardware int m_CaptureWidth; ///< width of the range image (x dimension) int m_CaptureHeight; ///< height of the range image (y dimension) int m_PixelNumber; ///< number of pixels in the range image (m_CaptureWidth*m_CaptureHeight) int m_SourceDataSize; ///< size of the PMD source data itk::MultiThreader::Pointer m_MultiThreader; ///< itk::MultiThreader used for thread handling itk::FastMutexLock::Pointer m_ImageMutex; ///< mutex for images provided by the range camera itk::FastMutexLock::Pointer m_CameraActiveMutex; ///< mutex for the cameraActive flag int m_ThreadID; ///< ID of the started thread bool m_CameraActive; ///< flag indicating if the camera is currently active or not. Caution: thread safe access only! bool m_CameraConnected; ///< flag indicating if the camera is successfully connected or not. Caution: thread safe access only! int m_ImageSequence; ///< counter for acquired images PropertyList::Pointer m_PropertyList; ///< a list of the corresponding properties private: }; } //END mitk namespace #endif diff --git a/Modules/ToFHardware/mitkToFCameraMITKPlayerDevice.cpp b/Modules/ToFHardware/mitkToFCameraMITKPlayerDevice.cpp index 760a077256..5462df4087 100644 --- a/Modules/ToFHardware/mitkToFCameraMITKPlayerDevice.cpp +++ b/Modules/ToFHardware/mitkToFCameraMITKPlayerDevice.cpp @@ -1,362 +1,370 @@ /*========================================================================= 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 "mitkToFCameraMITKPlayerDevice.h" #include "mitkToFCameraMITKPlayerController.h" #include "mitkRealTimeClock.h" #include "itkMultiThreader.h" #include namespace mitk { - ToFCameraMITKPlayerDevice::ToFCameraMITKPlayerDevice() + ToFCameraMITKPlayerDevice::ToFCameraMITKPlayerDevice() : + m_DistanceDataBuffer(NULL), m_IntensityDataBuffer(NULL), m_AmplitudeDataBuffer(NULL) { m_Controller = ToFCameraMITKPlayerController::New(); } ToFCameraMITKPlayerDevice::~ToFCameraMITKPlayerDevice() { DisconnectCamera(); + CleanUpDataBuffers(); } bool ToFCameraMITKPlayerDevice::ConnectCamera() { bool ok = m_Controller->OpenCameraConnection(); if (ok) { this->m_CaptureWidth = m_Controller->GetCaptureWidth(); this->m_CaptureHeight = m_Controller->GetCaptureHeight(); this->m_PixelNumber = this->m_CaptureWidth * this->m_CaptureHeight; - // allocate buffer - this->m_IntensityArray = new float[this->m_PixelNumber]; - for(int i=0; im_PixelNumber; i++) {this->m_IntensityArray[i]=0.0;} - this->m_DistanceArray = new float[this->m_PixelNumber]; - for(int i=0; im_PixelNumber; i++) {this->m_DistanceArray[i]=0.0;} - this->m_AmplitudeArray = new float[this->m_PixelNumber]; - for(int i=0; im_PixelNumber; i++) {this->m_AmplitudeArray[i]=0.0;} - - this->m_DistanceDataBuffer = new float*[this->m_MaxBufferSize]; - for(int i=0; im_MaxBufferSize; i++) - { - this->m_DistanceDataBuffer[i] = new float[this->m_PixelNumber]; - } - this->m_AmplitudeDataBuffer = new float*[this->m_MaxBufferSize]; - for(int i=0; im_MaxBufferSize; i++) - { - this->m_AmplitudeDataBuffer[i] = new float[this->m_PixelNumber]; - } - this->m_IntensityDataBuffer = new float*[this->m_MaxBufferSize]; - for(int i=0; im_MaxBufferSize; i++) - { - this->m_IntensityDataBuffer[i] = new float[this->m_PixelNumber]; - } + AllocatePixelArrays(); + AllocateDataBuffers(); m_CameraConnected = true; } return ok; } bool ToFCameraMITKPlayerDevice::DisconnectCamera() { bool ok = m_Controller->CloseCameraConnection(); - - // free buffer if camera was connected - if (m_CameraConnected) + if (ok) { - delete [] m_IntensityArray; - delete [] m_DistanceArray; - delete [] m_AmplitudeArray; - - for(int i=0; im_MaxBufferSize; i++) - { - delete[] this->m_DistanceDataBuffer[i]; - } - delete[] this->m_DistanceDataBuffer; - for(int i=0; im_MaxBufferSize; i++) - { - delete[] this->m_AmplitudeDataBuffer[i]; - } - delete[] this->m_AmplitudeDataBuffer; - for(int i=0; im_MaxBufferSize; i++) - { - delete[] this->m_IntensityDataBuffer[i]; - } - delete[] this->m_IntensityDataBuffer; - m_CameraConnected = false; } return ok; } void ToFCameraMITKPlayerDevice::StartCamera() { if (m_CameraConnected) { // get the first image this->m_Controller->UpdateCamera(); this->m_ImageMutex->Lock(); this->m_Controller->GetDistances(this->m_DistanceDataBuffer[this->m_FreePos]); this->m_Controller->GetAmplitudes(this->m_AmplitudeDataBuffer[this->m_FreePos]); this->m_Controller->GetIntensities(this->m_IntensityDataBuffer[this->m_FreePos]); this->m_FreePos = (this->m_FreePos+1) % this->m_BufferSize; this->m_CurrentPos = (this->m_CurrentPos+1) % this->m_BufferSize; this->m_ImageSequence++; this->m_ImageMutex->Unlock(); this->m_CameraActiveMutex->Lock(); this->m_CameraActive = true; this->m_CameraActiveMutex->Unlock(); this->m_ThreadID = this->m_MultiThreader->SpawnThread(this->Acquire, this); // wait a little to make sure that the thread is started itksys::SystemTools::Delay(10); } else { MITK_INFO<<"Camera not connected"; } } void ToFCameraMITKPlayerDevice::StopCamera() { m_CameraActiveMutex->Lock(); m_CameraActive = false; m_CameraActiveMutex->Unlock(); itksys::SystemTools::Delay(100); if (m_MultiThreader.IsNotNull()) { m_MultiThreader->TerminateThread(m_ThreadID); } // wait a little to make sure that the thread is terminated itksys::SystemTools::Delay(100); } bool ToFCameraMITKPlayerDevice::IsCameraActive() { m_CameraActiveMutex->Lock(); bool ok = m_CameraActive; m_CameraActiveMutex->Unlock(); return ok; } void ToFCameraMITKPlayerDevice::UpdateCamera() { m_Controller->UpdateCamera(); } ITK_THREAD_RETURN_TYPE ToFCameraMITKPlayerDevice::Acquire(void* pInfoStruct) { /* extract this pointer from Thread Info structure */ 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; } ToFCameraMITKPlayerDevice* toFCameraDevice = (ToFCameraMITKPlayerDevice*)pInfo->UserData; if (toFCameraDevice!=NULL) { mitk::RealTimeClock::Pointer realTimeClock; realTimeClock = mitk::RealTimeClock::New(); int n = 100; double t1, t2; t1 = realTimeClock->GetCurrentStamp(); bool overflow = false; bool printStatus = false; while (toFCameraDevice->IsCameraActive()) { // update the ToF camera toFCameraDevice->UpdateCamera(); // get image data from controller and write it to the according buffer toFCameraDevice->m_Controller->GetDistances(toFCameraDevice->m_DistanceDataBuffer[toFCameraDevice->m_FreePos]); toFCameraDevice->m_Controller->GetAmplitudes(toFCameraDevice->m_AmplitudeDataBuffer[toFCameraDevice->m_FreePos]); toFCameraDevice->m_Controller->GetIntensities(toFCameraDevice->m_IntensityDataBuffer[toFCameraDevice->m_FreePos]); toFCameraDevice->Modified(); /*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! TODO Buffer Handling currently only works for buffer size 1 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/ toFCameraDevice->m_ImageMutex->Lock(); toFCameraDevice->m_FreePos = (toFCameraDevice->m_FreePos+1) % toFCameraDevice->m_BufferSize; toFCameraDevice->m_CurrentPos = (toFCameraDevice->m_CurrentPos+1) % toFCameraDevice->m_BufferSize; toFCameraDevice->m_ImageSequence++; if (toFCameraDevice->m_FreePos == toFCameraDevice->m_CurrentPos) { // buffer overflow //MITK_INFO << "Buffer overflow!! "; //toFCameraDevice->m_CurrentPos = (toFCameraDevice->m_CurrentPos+1) % toFCameraDevice->m_BufferSize; //toFCameraDevice->m_ImageSequence++; overflow = true; } if (toFCameraDevice->m_ImageSequence % n == 0) { printStatus = true; } toFCameraDevice->m_ImageMutex->Unlock(); if (overflow) { //itksys::SystemTools::Delay(10); overflow = false; } /*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! END TODO Buffer Handling currently only works for buffer size 1 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/ // print current framerate if (printStatus) { t2 = realTimeClock->GetCurrentStamp() - t1; MITK_INFO << " Framerate (fps): " << n / (t2/1000) << " Sequence: " << toFCameraDevice->m_ImageSequence; t1 = realTimeClock->GetCurrentStamp(); printStatus = false; } } // end of while loop } return ITK_THREAD_RETURN_VALUE; } // TODO: Buffer size currently set to 1. Once Buffer handling is working correctly, method may be reactivated // void ToFCameraMITKPlayerDevice::ResetBuffer(int bufferSize) // { // this->m_BufferSize = bufferSize; // this->m_CurrentPos = -1; // this->m_FreePos = 0; // } void ToFCameraMITKPlayerDevice::GetAmplitudes(float* amplitudeArray, int& imageSequence) { m_ImageMutex->Lock(); /*!!!!!!!!!!!!!!!!!!!!!! TODO Buffer handling??? !!!!!!!!!!!!!!!!!!!!!!!!*/ // write amplitude image data to float array for (int i=0; im_PixelNumber; i++) { amplitudeArray[i] = this->m_AmplitudeDataBuffer[this->m_CurrentPos][i]; } imageSequence = this->m_ImageSequence; m_ImageMutex->Unlock(); } void ToFCameraMITKPlayerDevice::GetIntensities(float* intensityArray, int& imageSequence) { m_ImageMutex->Lock(); /*!!!!!!!!!!!!!!!!!!!!!! TODO Buffer handling??? !!!!!!!!!!!!!!!!!!!!!!!!*/ // write intensity image data to float array for (int i=0; im_PixelNumber; i++) { intensityArray[i] = this->m_IntensityDataBuffer[this->m_CurrentPos][i]; } imageSequence = this->m_ImageSequence; m_ImageMutex->Unlock(); } void ToFCameraMITKPlayerDevice::GetDistances(float* distanceArray, int& imageSequence) { m_ImageMutex->Lock(); /*!!!!!!!!!!!!!!!!!!!!!! TODO Buffer handling??? !!!!!!!!!!!!!!!!!!!!!!!!*/ // write distance image data to float array for (int i=0; im_PixelNumber; i++) { distanceArray[i] = this->m_DistanceDataBuffer[this->m_CurrentPos][i]; } imageSequence = this->m_ImageSequence; m_ImageMutex->Unlock(); } void ToFCameraMITKPlayerDevice::GetAllImages(float* distanceArray, float* amplitudeArray, float* intensityArray, char* sourceDataArray, int requiredImageSequence, int& capturedImageSequence) { /*!!!!!!!!!!!!!!!!!!!!!! TODO Document this method! !!!!!!!!!!!!!!!!!!!!!!!!*/ m_ImageMutex->Lock(); //check for empty buffer if (this->m_ImageSequence < 0) { // buffer empty MITK_INFO << "Buffer empty!! "; capturedImageSequence = this->m_ImageSequence; m_ImageMutex->Unlock(); return; } // determine position of image in buffer int pos = 0; if ((requiredImageSequence < 0) || (requiredImageSequence > this->m_ImageSequence)) { capturedImageSequence = this->m_ImageSequence; pos = this->m_CurrentPos; } else if (requiredImageSequence <= this->m_ImageSequence - this->m_BufferSize) { capturedImageSequence = (this->m_ImageSequence - this->m_BufferSize) + 1; pos = (this->m_CurrentPos + 1) % this->m_BufferSize; } else // (requiredImageSequence > this->m_ImageSequence - this->m_BufferSize) && (requiredImageSequence <= this->m_ImageSequence) { capturedImageSequence = requiredImageSequence; pos = (this->m_CurrentPos + (10-(this->m_ImageSequence - requiredImageSequence))) % this->m_BufferSize; } // write image data to float arrays for (int i=0; im_PixelNumber; i++) { distanceArray[i] = this->m_DistanceDataBuffer[pos][i]; amplitudeArray[i] = this->m_AmplitudeDataBuffer[pos][i]; intensityArray[i] = this->m_IntensityDataBuffer[pos][i]; } m_ImageMutex->Unlock(); } void ToFCameraMITKPlayerDevice::SetInputFileName(std::string inputFileName) { this->m_InputFileName = inputFileName; this->m_Controller->SetInputFileName(inputFileName); } void ToFCameraMITKPlayerDevice::SetProperty( const char *propertyKey, BaseProperty* propertyValue ) { this->m_PropertyList->SetProperty(propertyKey, propertyValue); ToFCameraMITKPlayerController::Pointer myController = dynamic_cast(this->m_Controller.GetPointer()); std::string strValue; GetStringProperty(propertyValue, strValue); if (strcmp(propertyKey, "DistanceImageFileName") == 0) { myController->SetDistanceImageFileName(strValue); } else if (strcmp(propertyKey, "AmplitudeImageFileName") == 0) { myController->SetAmplitudeImageFileName(strValue); } else if (strcmp(propertyKey, "IntensityImageFileName") == 0) { myController->SetIntensityImageFileName(strValue); } } + void ToFCameraMITKPlayerDevice::CleanUpDataBuffers() + { + if (m_DistanceDataBuffer) + { + for(int i=0; im_MaxBufferSize; i++) + { + delete[] this->m_DistanceDataBuffer[i]; + } + delete[] this->m_DistanceDataBuffer; + } + if (m_AmplitudeDataBuffer) + { + for(int i=0; im_MaxBufferSize; i++) + { + delete[] this->m_AmplitudeDataBuffer[i]; + } + delete[] this->m_AmplitudeDataBuffer; + } + if (m_IntensityDataBuffer) + { + for(int i=0; im_MaxBufferSize; i++) + { + delete[] this->m_IntensityDataBuffer[i]; + } + delete[] this->m_IntensityDataBuffer; + } + } + + void ToFCameraMITKPlayerDevice::AllocateDataBuffers() + { + // free memory if it was already allocated + this->CleanUpDataBuffers(); + // allocate buffers + this->m_DistanceDataBuffer = new float*[this->m_MaxBufferSize]; + for(int i=0; im_MaxBufferSize; i++) + { + this->m_DistanceDataBuffer[i] = new float[this->m_PixelNumber]; + } + this->m_AmplitudeDataBuffer = new float*[this->m_MaxBufferSize]; + for(int i=0; im_MaxBufferSize; i++) + { + this->m_AmplitudeDataBuffer[i] = new float[this->m_PixelNumber]; + } + this->m_IntensityDataBuffer = new float*[this->m_MaxBufferSize]; + for(int i=0; im_MaxBufferSize; i++) + { + this->m_IntensityDataBuffer[i] = new float[this->m_PixelNumber]; + } + } } diff --git a/Modules/ToFHardware/mitkToFCameraMITKPlayerDevice.h b/Modules/ToFHardware/mitkToFCameraMITKPlayerDevice.h index 4bb760fc62..f6f03e683c 100644 --- a/Modules/ToFHardware/mitkToFCameraMITKPlayerDevice.h +++ b/Modules/ToFHardware/mitkToFCameraMITKPlayerDevice.h @@ -1,141 +1,149 @@ /*========================================================================= 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 __mitkToFCameraMITKPlayerDevice_h #define __mitkToFCameraMITKPlayerDevice_h #include "mitkToFHardwareExports.h" #include "mitkCommon.h" #include "mitkToFCameraDevice.h" #include "mitkToFCameraMITKPlayerController.h" #include "itkObject.h" #include "itkObjectFactory.h" #include "itkMultiThreader.h" #include "itkFastMutexLock.h" namespace mitk { /** * @brief Device class representing a player for MITK-ToF images. * * @ingroup ToFHardware */ class MITK_TOFHARDWARE_EXPORT ToFCameraMITKPlayerDevice : public ToFCameraDevice { public: mitkClassMacro( ToFCameraMITKPlayerDevice , ToFCameraDevice ); itkNewMacro( Self ); /*! \brief opens a connection to the ToF camera */ virtual bool ConnectCamera(); /*! \brief closes the connection to the camera */ virtual bool DisconnectCamera(); /*! \brief starts the continuous updating of the camera. A separate thread updates the source data, the main thread processes the source data and creates images and coordinates */ virtual void StartCamera(); /*! \brief stops the continuous updating of the camera */ virtual void StopCamera(); /*! \brief returns whether the camera is currently active or not */ virtual bool IsCameraActive(); /*! \brief gets the amplitude data from the ToF camera as the strength of the active illumination of every pixel. Caution! The user is responsible for allocating and deleting the images. These values can be used to determine the quality of the distance values. The higher the amplitude value, the higher the accuracy of the according distance value \param imageSequence the actually captured image sequence number \param amplitudeArray contains the returned amplitude data as an array. */ virtual void GetAmplitudes(float* amplitudeArray, int& imageSequence); /*! \brief gets the intensity data from the ToF camera as a greyscale image. Caution! The user is responsible for allocating and deleting the images. \param intensityArray contains the returned intensities data as an array. \param imageSequence the actually captured image sequence number */ virtual void GetIntensities(float* intensityArray, int& imageSequence); /*! \brief gets the distance data from the ToF camera measuring the distance between the camera and the different object points in millimeters. Caution! The user is responsible for allocating and deleting the images. \param distanceArray contains the returned distances data as an array. \param imageSequence the actually captured image sequence number */ virtual void GetDistances(float* distanceArray, int& imageSequence); /*! \brief gets the 3 images (distance, amplitude, intensity) from the ToF camera. Caution! The user is responsible for allocating and deleting the images. \param distanceArray contains the returned distance data as an array. \param amplitudeArray contains the returned amplitude data as an array. \param intensityArray contains the returned intensity data as an array. \param sourceDataArray contains the complete source data from the camera device. \param requiredImageSequence the required image sequence number \param capturedImageSequence the actually captured image sequence number */ virtual void GetAllImages(float* distanceArray, float* amplitudeArray, float* intensityArray, char* sourceDataArray, int requiredImageSequence, int& capturedImageSequence); // TODO: Buffer size currently set to 1. Once Buffer handling is working correctly, method may be reactivated // /*! // \brief pure virtual method resetting the buffer using the specified bufferSize. Has to be implemented by sub-classes // \param bufferSize buffer size the buffer should be reset to // */ // virtual void ResetBuffer(int bufferSize) = 0; //TODO add/correct documentation for requiredImageSequence and capturedImageSequence in the GetAllImages, GetDistances, GetIntensities and GetAmplitudes methods. /*! \brief Set file name where the data is recorded \param inputFileName name of input file which should be played */ virtual void SetInputFileName(std::string inputFileName); /*! \brief set a BaseProperty */ virtual void SetProperty( const char *propertyKey, BaseProperty* propertyValue ); protected: ToFCameraMITKPlayerDevice(); ~ToFCameraMITKPlayerDevice(); /*! \brief updates the camera for image acquisition */ virtual void UpdateCamera(); /*! \brief Thread method continuously acquiring images from the specified input file */ static ITK_THREAD_RETURN_TYPE Acquire(void* pInfoStruct); + /*! + \brief Clean up memory (pixel buffers) + */ + void CleanUpDataBuffers(); + /*! + \brief Allocate pixel buffers + */ + void AllocateDataBuffers(); ToFCameraMITKPlayerController::Pointer m_Controller; ///< member holding the corresponding controller std::string m_InputFileName; ///< member holding the file name of the current input file private: float** m_DistanceDataBuffer; ///< buffer holding the last distance images float** m_AmplitudeDataBuffer; ///< buffer holding the last amplitude images float** m_IntensityDataBuffer; ///< buffer holding the last intensity images }; } //END mitk namespace #endif diff --git a/Modules/ToFHardware/mitkToFCameraPMDDevice.cpp b/Modules/ToFHardware/mitkToFCameraPMDDevice.cpp index 95a12fe3e7..2402f2f93f 100644 --- a/Modules/ToFHardware/mitkToFCameraPMDDevice.cpp +++ b/Modules/ToFHardware/mitkToFCameraPMDDevice.cpp @@ -1,406 +1,415 @@ /*========================================================================= 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 "mitkToFCameraPMDDevice.h" #include "mitkRealTimeClock.h" #include "itkMultiThreader.h" #include namespace mitk { - ToFCameraPMDDevice::ToFCameraPMDDevice() + ToFCameraPMDDevice::ToFCameraPMDDevice() : + m_SourceDataArray(NULL), m_SourceDataBuffer(NULL) { } ToFCameraPMDDevice::~ToFCameraPMDDevice() { + this->CleanUpSourceData(); } bool ToFCameraPMDDevice::ConnectCamera() { bool ok = false; if (m_Controller) { ok = m_Controller->OpenCameraConnection(); if (ok) { this->m_CaptureWidth = m_Controller->GetCaptureWidth(); this->m_CaptureHeight = m_Controller->GetCaptureHeight(); this->m_SourceDataSize = m_Controller->GetSourceDataStructSize(); this->m_PixelNumber = this->m_CaptureWidth * this->m_CaptureHeight; - // allocate buffer - this->m_IntensityArray = new float[this->m_PixelNumber]; - for(int i=0; im_PixelNumber; i++) {this->m_IntensityArray[i]=0.0;} - this->m_DistanceArray = new float[this->m_PixelNumber]; - for(int i=0; im_PixelNumber; i++) {this->m_DistanceArray[i]=0.0;} - this->m_AmplitudeArray = new float[this->m_PixelNumber]; - for(int i=0; im_PixelNumber; i++) {this->m_AmplitudeArray[i]=0.0;} - this->m_SourceDataArray = new char[this->m_SourceDataSize]; - for(int i=0; im_SourceDataSize; i++) {this->m_SourceDataArray[i]=0;} - - this->m_SourceDataBuffer = new char*[this->m_MaxBufferSize]; - for(int i=0; im_MaxBufferSize; i++) - { - this->m_SourceDataBuffer[i] = new char[this->m_SourceDataSize]; - } + // allocate buffers + AllocatePixelArrays(); + this->AllocateSourceData(); m_CameraConnected = true; } } return ok; } bool ToFCameraPMDDevice::DisconnectCamera() { bool ok = false; if (m_Controller) { ok = m_Controller->CloseCameraConnection(); - // clean-up only if camera was connected - if (m_CameraConnected) + if (ok) { - MITK_INFO<<"free buffer"; - // free buffer - delete [] m_IntensityArray; - delete [] m_DistanceArray; - delete [] m_AmplitudeArray; - delete [] m_SourceDataArray; - for(int i=0; im_MaxBufferSize; i++) - { - delete[] this->m_SourceDataBuffer[i]; - } - delete[] this->m_SourceDataBuffer; m_CameraConnected = false; } } return ok; } void ToFCameraPMDDevice::StartCamera() { if (m_CameraConnected) { // get the first image this->m_Controller->UpdateCamera(); this->m_ImageMutex->Lock(); //this->m_Controller->GetSourceData(this->m_SourceDataArray); this->m_Controller->GetSourceData(this->m_SourceDataBuffer[this->m_FreePos]); this->m_FreePos = (this->m_FreePos+1) % this->m_BufferSize; this->m_CurrentPos = (this->m_CurrentPos+1) % this->m_BufferSize; this->m_ImageSequence++; this->m_ImageMutex->Unlock(); this->m_CameraActiveMutex->Lock(); this->m_CameraActive = true; this->m_CameraActiveMutex->Unlock(); this->m_ThreadID = this->m_MultiThreader->SpawnThread(this->Acquire, this); // wait a little to make sure that the thread is started itksys::SystemTools::Delay(10); } else { MITK_INFO<<"Camera not connected"; } } void ToFCameraPMDDevice::StopCamera() { m_CameraActiveMutex->Lock(); m_CameraActive = false; m_CameraActiveMutex->Unlock(); itksys::SystemTools::Delay(100); if (m_MultiThreader.IsNotNull()) { m_MultiThreader->TerminateThread(m_ThreadID); } // wait a little to make sure that the thread is terminated itksys::SystemTools::Delay(10); } bool ToFCameraPMDDevice::IsCameraActive() { m_CameraActiveMutex->Lock(); bool ok = m_CameraActive; m_CameraActiveMutex->Unlock(); return ok; } void ToFCameraPMDDevice::UpdateCamera() { if (m_Controller) { m_Controller->UpdateCamera(); } } ITK_THREAD_RETURN_TYPE ToFCameraPMDDevice::Acquire(void* pInfoStruct) { /* extract this pointer from Thread Info structure */ 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; } ToFCameraPMDDevice* toFCameraDevice = (ToFCameraPMDDevice*)pInfo->UserData; if (toFCameraDevice!=NULL) { mitk::RealTimeClock::Pointer realTimeClock; realTimeClock = mitk::RealTimeClock::New(); double t1, t2; t1 = realTimeClock->GetCurrentStamp(); int n = 100; bool overflow = false; bool printStatus = false; while (toFCameraDevice->IsCameraActive()) { // update the ToF camera toFCameraDevice->UpdateCamera(); // get the source data from the camera and write it at the next free position in the buffer toFCameraDevice->m_Controller->GetSourceData(toFCameraDevice->m_SourceDataBuffer[toFCameraDevice->m_FreePos]); // call modified to indicate that cameraDevice was modified toFCameraDevice->Modified(); /*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! TODO Buffer Handling currently only works for buffer size 1 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/ toFCameraDevice->m_ImageMutex->Lock(); //toFCameraDevice->m_ImageSequence++; toFCameraDevice->m_FreePos = (toFCameraDevice->m_FreePos+1) % toFCameraDevice->m_BufferSize; toFCameraDevice->m_CurrentPos = (toFCameraDevice->m_CurrentPos+1) % toFCameraDevice->m_BufferSize; toFCameraDevice->m_ImageSequence++; if (toFCameraDevice->m_FreePos == toFCameraDevice->m_CurrentPos) { // buffer overflow //MITK_INFO << "Buffer overflow!! "; //toFCameraDevice->m_CurrentPos = (toFCameraDevice->m_CurrentPos+1) % toFCameraDevice->m_BufferSize; //toFCameraDevice->m_ImageSequence++; overflow = true; } if (toFCameraDevice->m_ImageSequence % n == 0) { printStatus = true; } toFCameraDevice->m_ImageMutex->Unlock(); if (overflow) { //itksys::SystemTools::Delay(10); overflow = false; } /*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! END TODO Buffer Handling currently only works for buffer size 1 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/ // print current framerate if (printStatus) { t2 = realTimeClock->GetCurrentStamp() - t1; //MITK_INFO << "t2: " << t2 <<" Time (s) for 1 image: " << (t2/1000) / n << " Framerate (fps): " << n / (t2/1000) << " Sequence: " << toFCameraDevice->m_ImageSequence; MITK_INFO << " Framerate (fps): " << n / (t2/1000) << " Sequence: " << toFCameraDevice->m_ImageSequence; t1 = realTimeClock->GetCurrentStamp(); printStatus = false; } } // end of while loop } return ITK_THREAD_RETURN_VALUE; } // TODO: Buffer size currently set to 1. Once Buffer handling is working correctly, method may be reactivated // void ToFCameraPMDDevice::ResetBuffer(int bufferSize) // { // this->m_BufferSize = bufferSize; // this->m_CurrentPos = -1; // this->m_FreePos = 0; // } void ToFCameraPMDDevice::GetAmplitudes(float* amplitudeArray, int& imageSequence) { m_ImageMutex->Lock(); if (m_CameraActive) { // 1) copy the image buffer // 2) Flip around y- axis (vertical axis) this->m_Controller->GetAmplitudes(this->m_SourceDataBuffer[this->m_CurrentPos], this->m_AmplitudeArray); for (int i=0; im_CaptureHeight; i++) { for (int j=0; jm_CaptureWidth; j++) { amplitudeArray[i*this->m_CaptureWidth+j] = this->m_AmplitudeArray[(i+1)*this->m_CaptureWidth-1-j]; } } imageSequence = this->m_ImageSequence; } else { MITK_WARN("ToF") << "Warning: Data can only be acquired if camera is active."; } m_ImageMutex->Unlock(); } void ToFCameraPMDDevice::GetIntensities(float* intensityArray, int& imageSequence) { m_ImageMutex->Lock(); if (m_CameraActive) { // 1) copy the image buffer // 2) Flip around y- axis (vertical axis) this->m_Controller->GetIntensities(this->m_SourceDataBuffer[this->m_CurrentPos], this->m_IntensityArray); for (int i=0; im_CaptureHeight; i++) { for (int j=0; jm_CaptureWidth; j++) { intensityArray[i*this->m_CaptureWidth+j] = this->m_IntensityArray[(i+1)*this->m_CaptureWidth-1-j]; } } imageSequence = this->m_ImageSequence; } else { MITK_WARN("ToF") << "Warning: Data can only be acquired if camera is active."; } m_ImageMutex->Unlock(); } void ToFCameraPMDDevice::GetDistances(float* distanceArray, int& imageSequence) { m_ImageMutex->Lock(); if (m_CameraActive) { // 1) copy the image buffer // 2) convert the distance values from m to mm // 3) Flip around y- axis (vertical axis) this->m_Controller->GetDistances(this->m_SourceDataBuffer[this->m_CurrentPos], this->m_DistanceArray); for (int i=0; im_CaptureHeight; i++) { for (int j=0; jm_CaptureWidth; j++) { distanceArray[i*this->m_CaptureWidth+j] = 1000 * this->m_DistanceArray[(i+1)*this->m_CaptureWidth-1-j]; } } imageSequence = this->m_ImageSequence; } else { MITK_WARN("ToF") << "Warning: Data can only be acquired if camera is active."; } m_ImageMutex->Unlock(); } void ToFCameraPMDDevice::GetAllImages(float* distanceArray, float* amplitudeArray, float* intensityArray, char* sourceDataArray, int requiredImageSequence, int& capturedImageSequence) { if (m_CameraActive) { m_ImageMutex->Lock(); // 1) copy the image buffer // 2) convert the distance values from m to mm // 3) Flip around y- axis (vertical axis) // check for empty buffer if (this->m_ImageSequence < 0) { // buffer empty MITK_INFO << "Buffer empty!! "; capturedImageSequence = this->m_ImageSequence; m_ImageMutex->Unlock(); return; } // determine position of image in buffer int pos = 0; if ((requiredImageSequence < 0) || (requiredImageSequence > this->m_ImageSequence)) { capturedImageSequence = this->m_ImageSequence; pos = this->m_CurrentPos; //MITK_INFO << "Required image not found! Required: " << requiredImageSequence << " delivered/current: " << this->m_ImageSequence; } else if (requiredImageSequence <= this->m_ImageSequence - this->m_BufferSize) { capturedImageSequence = (this->m_ImageSequence - this->m_BufferSize) + 1; pos = (this->m_CurrentPos + 1) % this->m_BufferSize; //MITK_INFO << "Out of buffer! Required: " << requiredImageSequence << " delivered: " << capturedImageSequence << " current: " << this->m_ImageSequence; } else // (requiredImageSequence > this->m_ImageSequence - this->m_BufferSize) && (requiredImageSequence <= this->m_ImageSequence) { capturedImageSequence = requiredImageSequence; pos = (this->m_CurrentPos + (10-(this->m_ImageSequence - requiredImageSequence))) % this->m_BufferSize; } m_ImageMutex->Unlock(); this->m_Controller->GetDistances(this->m_SourceDataBuffer[pos], this->m_DistanceArray); this->m_Controller->GetAmplitudes(this->m_SourceDataBuffer[pos], this->m_AmplitudeArray); this->m_Controller->GetIntensities(this->m_SourceDataBuffer[pos], this->m_IntensityArray); int u, v; for (int i=0; im_CaptureHeight; i++) { for (int j=0; jm_CaptureWidth; j++) { u = i*this->m_CaptureWidth+j; v = (i+1)*this->m_CaptureWidth-1-j; distanceArray[u] = 1000 * this->m_DistanceArray[v]; // unit in minimeter //distanceArray[u] = this->m_DistanceArray[v]; // unit in meter amplitudeArray[u] = this->m_AmplitudeArray[v]; intensityArray[u] = this->m_IntensityArray[v]; } } memcpy(sourceDataArray, this->m_SourceDataBuffer[this->m_CurrentPos], this->m_SourceDataSize); } else { MITK_WARN("ToF") << "Warning: Data can only be acquired if camera is active."; } } ToFCameraPMDController::Pointer ToFCameraPMDDevice::GetController() { return this->m_Controller; } void ToFCameraPMDDevice::SetProperty( const char *propertyKey, BaseProperty* propertyValue ) { ToFCameraDevice::SetProperty(propertyKey,propertyValue); this->m_PropertyList->SetProperty(propertyKey, propertyValue); if (strcmp(propertyKey, "ModulationFrequency") == 0) { int modulationFrequency = 0; GetIntProperty(propertyValue, modulationFrequency); m_Controller->SetModulationFrequency(modulationFrequency); } else if (strcmp(propertyKey, "IntegrationTime") == 0) { int integrationTime = 0; GetIntProperty(propertyValue, integrationTime); m_Controller->SetIntegrationTime(integrationTime); } } + + void ToFCameraPMDDevice::AllocateSourceData() + { + // clean up if array and data have already been allocated + CleanUpSourceData(); + // (re-) allocate memory + this->m_SourceDataArray = new char[this->m_SourceDataSize]; + for(int i=0; im_SourceDataSize; i++) {this->m_SourceDataArray[i]=0;} + + this->m_SourceDataBuffer = new char*[this->m_MaxBufferSize]; + for(int i=0; im_MaxBufferSize; i++) + { + this->m_SourceDataBuffer[i] = new char[this->m_SourceDataSize]; + } + } + + void ToFCameraPMDDevice::CleanUpSourceData() + { + if (m_SourceDataArray) + { + delete[] m_SourceDataArray; + } + if (m_SourceDataBuffer) + { + for(int i=0; im_MaxBufferSize; i++) + { + delete[] this->m_SourceDataBuffer[i]; + } + delete[] this->m_SourceDataBuffer; + } + } } diff --git a/Modules/ToFHardware/mitkToFCameraPMDDevice.h b/Modules/ToFHardware/mitkToFCameraPMDDevice.h index e8cf253720..46f1f17d90 100644 --- a/Modules/ToFHardware/mitkToFCameraPMDDevice.h +++ b/Modules/ToFHardware/mitkToFCameraPMDDevice.h @@ -1,146 +1,155 @@ /*========================================================================= 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 __mitkToFCameraPMDDevice_h #define __mitkToFCameraPMDDevice_h #include "mitkToFHardwareExports.h" #include "mitkCommon.h" #include "mitkToFCameraDevice.h" #include "mitkToFCameraPMDController.h" #include "itkObject.h" #include "itkObjectFactory.h" #include "itkMultiThreader.h" #include "itkFastMutexLock.h" namespace mitk { /** * @brief Interface for all representations of PMD ToF devices. * ToFCameraPMDDevice internally holds an instance of ToFCameraPMDController and starts a thread * that continuously grabs images from the controller. A buffer structure buffers the last acquired images * to provide the image data loss-less. * * @ingroup ToFHardware */ class MITK_TOFHARDWARE_EXPORT ToFCameraPMDDevice : public ToFCameraDevice { public: mitkClassMacro( ToFCameraPMDDevice , ToFCameraDevice ); itkNewMacro( Self ); /*! \brief opens a connection to the ToF camera */ virtual bool ConnectCamera(); /*! \brief closes the connection to the camera */ virtual bool DisconnectCamera(); /*! \brief starts the continuous updating of the camera. A separate thread updates the source data, the main thread processes the source data and creates images and coordinates */ virtual void StartCamera(); /*! \brief stops the continuous updating of the camera */ virtual void StopCamera(); /*! \brief updates the camera for image acquisition */ virtual void UpdateCamera(); /*! \brief returns whether the camera is currently active or not */ virtual bool IsCameraActive(); /*! \brief gets the amplitude data from the ToF camera as the strength of the active illumination of every pixel. Caution! The user is responsible for allocating and deleting the images. These values can be used to determine the quality of the distance values. The higher the amplitude value, the higher the accuracy of the according distance value \param imageSequence the actually captured image sequence number \param amplitudeArray contains the returned amplitude data as an array. */ virtual void GetAmplitudes(float* amplitudeArray, int& imageSequence); /*! \brief gets the intensity data from the ToF camera as a greyscale image. Caution! The user is responsible for allocating and deleting the images. \param intensityArray contains the returned intensities data as an array. \param imageSequence the actually captured image sequence number */ virtual void GetIntensities(float* intensityArray, int& imageSequence); /*! \brief gets the distance data from the ToF camera measuring the distance between the camera and the different object points in millimeters. Caution! The user is responsible for allocating and deleting the images. \param distanceArray contains the returned distances data as an array. \param imageSequence the actually captured image sequence number */ virtual void GetDistances(float* distanceArray, int& imageSequence); /*! \brief gets the 3 images (distance, amplitude, intensity) from the ToF camera. Caution! The user is responsible for allocating and deleting the images. \param distanceArray contains the returned distance data as an array. \param amplitudeArray contains the returned amplitude data as an array. \param intensityArray contains the returned intensity data as an array. \param sourceDataArray contains the complete source data from the camera device. \param requiredImageSequence the required image sequence number \param capturedImageSequence the actually captured image sequence number */ virtual void GetAllImages(float* distanceArray, float* amplitudeArray, float* intensityArray, char* sourceDataArray, int requiredImageSequence, int& capturedImageSequence); // TODO: Buffer size currently set to 1. Once Buffer handling is working correctly, method may be reactivated // /*! // \brief pure virtual method resetting the buffer using the specified bufferSize. Has to be implemented by sub-classes // \param bufferSize buffer size the buffer should be reset to // */ // virtual void ResetBuffer(int bufferSize) = 0; //TODO add/correct documentation for requiredImageSequence and capturedImageSequence in the GetAllImages, GetDistances, GetIntensities and GetAmplitudes methods. /*! \brief returns the corresponding camera controller */ ToFCameraPMDController::Pointer GetController(); /*! \brief set a BaseProperty */ virtual void SetProperty( const char *propertyKey, BaseProperty* propertyValue ); protected: ToFCameraPMDDevice(); ~ToFCameraPMDDevice(); + /*! + \brief method for allocating m_SourceDataArray and m_SourceDataBuffer + */ + virtual void AllocateSourceData(); + /*! + \brief method for cleaning up memory allocated for m_SourceDataArray and m_SourceDataBuffer + */ + virtual void CleanUpSourceData(); + /*! \brief Thread method continuously acquiring images from the ToF hardware */ static ITK_THREAD_RETURN_TYPE Acquire(void* pInfoStruct); /*! \brief moves the position pointer m_CurrentPos to the next position in the buffer if that's not the next free position to prevent reading from an empty buffer */ void GetNextPos(); ToFCameraPMDController::Pointer m_Controller; ///< corresponding CameraController char** m_SourceDataBuffer; ///< buffer holding the last acquired images char* m_SourceDataArray; ///< array holding the current PMD source data private: }; } //END mitk namespace #endif diff --git a/Modules/ToFHardware/mitkToFImageGrabber.cpp b/Modules/ToFHardware/mitkToFImageGrabber.cpp index 1872499cd1..69b7519b1e 100644 --- a/Modules/ToFHardware/mitkToFImageGrabber.cpp +++ b/Modules/ToFHardware/mitkToFImageGrabber.cpp @@ -1,230 +1,252 @@ /*========================================================================= 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 "mitkToFImageGrabber.h" #include "mitkToFCameraPMDCamCubeDevice.h" #include "itkCommand.h" namespace mitk { ToFImageGrabber::ToFImageGrabber():m_CaptureWidth(204),m_CaptureHeight(204),m_PixelNumber(41616),m_ImageSequence(0), - m_IntensityArray(NULL), m_DistanceArray(NULL), m_AmplitudeArray(NULL) + m_IntensityArray(NULL), m_DistanceArray(NULL), m_AmplitudeArray(NULL), m_SourceDataArray(NULL) { // Create the output. We use static_cast<> here because we know the default // output must be of type TOutputImage OutputImageType::Pointer output0 = static_cast(this->MakeOutput(0).GetPointer()); OutputImageType::Pointer output1 = static_cast(this->MakeOutput(1).GetPointer()); OutputImageType::Pointer output2 = static_cast(this->MakeOutput(2).GetPointer()); mitk::ImageSource::SetNumberOfRequiredOutputs(3); mitk::ImageSource::SetNthOutput(0, output0.GetPointer()); mitk::ImageSource::SetNthOutput(1, output1.GetPointer()); mitk::ImageSource::SetNthOutput(2, output2.GetPointer()); } ToFImageGrabber::~ToFImageGrabber() { if (m_IntensityArray||m_AmplitudeArray||m_DistanceArray) { if (m_ToFCameraDevice) { m_ToFCameraDevice->RemoveObserver(m_DeviceObserverTag); } this->DisconnectCamera(); + this->CleanUpImageArrays(); } } mitk::ImageSource::DataObjectPointer mitk::ImageSource::MakeOutput(unsigned int) { return static_cast(OutputImageType::New().GetPointer()); } void ToFImageGrabber::GenerateData() { int requiredImageSequence = 0; int capturedImageSequence = 0; mitk::Image::Pointer distanceImage = this->GetOutput(0); mitk::Image::Pointer amplitudeImage = this->GetOutput(1); mitk::Image::Pointer intensityImage = this->GetOutput(2); if (!distanceImage->IsInitialized()) { distanceImage->ReleaseData(); amplitudeImage->ReleaseData(); intensityImage->ReleaseData(); unsigned int dimensions[2]; dimensions[0] = this->m_ToFCameraDevice->GetCaptureWidth(); dimensions[1] = this->m_ToFCameraDevice->GetCaptureHeight(); distanceImage->Initialize(mitk::PixelType(typeid(float)), 2, dimensions, 1); amplitudeImage->Initialize(mitk::PixelType(typeid(float)), 2, dimensions, 1); intensityImage->Initialize(mitk::PixelType(typeid(float)), 2, dimensions, 1); } if (m_DistanceArray&&m_AmplitudeArray&&m_IntensityArray) { this->m_ToFCameraDevice->GetAllImages(this->m_DistanceArray, this->m_AmplitudeArray, this->m_IntensityArray, this->m_SourceDataArray, requiredImageSequence, this->m_ImageSequence ); capturedImageSequence = this->m_ImageSequence; distanceImage->SetSlice(this->m_DistanceArray, 0, 0, 0); amplitudeImage->SetSlice(this->m_AmplitudeArray, 0, 0, 0); intensityImage->SetSlice(this->m_IntensityArray, 0, 0, 0); } } bool ToFImageGrabber::ConnectCamera() { bool ok = m_ToFCameraDevice->ConnectCamera(); if (ok) { m_CaptureWidth = m_ToFCameraDevice->GetCaptureWidth(); m_CaptureHeight = m_ToFCameraDevice->GetCaptureHeight(); m_PixelNumber = m_CaptureWidth * m_CaptureHeight; m_SourceDataSize = m_ToFCameraDevice->GetSourceDataSize(); - - // allocate buffer - m_IntensityArray = new float[m_PixelNumber]; - m_DistanceArray = new float[m_PixelNumber]; - m_AmplitudeArray = new float[m_PixelNumber]; - m_SourceDataArray = new char[m_SourceDataSize]; + AllocateImageArrays(); } return ok; } bool ToFImageGrabber::DisconnectCamera() { bool success = m_ToFCameraDevice->DisconnectCamera(); - // free buffer - if (m_IntensityArray||m_DistanceArray||m_AmplitudeArray) - { - delete [] m_IntensityArray; - delete [] m_DistanceArray; - delete [] m_AmplitudeArray; - m_IntensityArray = NULL; - m_DistanceArray = NULL; - m_AmplitudeArray = NULL; - } return success; } void ToFImageGrabber::StartCamera() { m_ToFCameraDevice->StartCamera(); } void ToFImageGrabber::StopCamera() { m_ToFCameraDevice->StopCamera(); } bool ToFImageGrabber::IsCameraActive() { return m_ToFCameraDevice->IsCameraActive(); } void ToFImageGrabber::SetCameraDevice(ToFCameraDevice* aToFCameraDevice) { m_ToFCameraDevice = aToFCameraDevice; itk::SimpleMemberCommand::Pointer modifiedCommand = itk::SimpleMemberCommand::New(); modifiedCommand->SetCallbackFunction(this, &ToFImageGrabber::OnToFCameraDeviceModified); m_DeviceObserverTag = m_ToFCameraDevice->AddObserver(itk::ModifiedEvent(), modifiedCommand); this->Modified(); } ToFCameraDevice* ToFImageGrabber::GetCameraDevice() { return m_ToFCameraDevice; } int ToFImageGrabber::GetCaptureWidth() { return m_CaptureWidth; } int ToFImageGrabber::GetCaptureHeight() { return m_CaptureHeight; } int ToFImageGrabber::GetPixelNumber() { return m_PixelNumber; } int ToFImageGrabber::SetModulationFrequency(int modulationFrequency) { this->m_ToFCameraDevice->SetProperty("ModulationFrequency",mitk::IntProperty::New(modulationFrequency)); this->Modified(); return modulationFrequency; } int ToFImageGrabber::SetIntegrationTime(int integrationTime) { this->m_ToFCameraDevice->SetProperty("IntegrationTime",mitk::IntProperty::New(integrationTime)); this->Modified(); return integrationTime; } int ToFImageGrabber::GetIntegrationTime() { int integrationTime = 0; BaseProperty* property = this->m_ToFCameraDevice->GetProperty("IntegrationTime"); this->m_ToFCameraDevice->GetIntProperty(property,integrationTime); return integrationTime; } int ToFImageGrabber::GetModulationFrequency() { int modulationFrequency = 0; BaseProperty* property = this->m_ToFCameraDevice->GetProperty("ModulationFrequency"); this->m_ToFCameraDevice->GetIntProperty(property,modulationFrequency); return modulationFrequency; } void ToFImageGrabber::SetBoolProperty( const char* propertyKey, bool boolValue ) { SetProperty(propertyKey, mitk::BoolProperty::New(boolValue)); } void ToFImageGrabber::SetIntProperty( const char* propertyKey, int intValue ) { SetProperty(propertyKey, mitk::IntProperty::New(intValue)); } void ToFImageGrabber::SetFloatProperty( const char* propertyKey, float floatValue ) { SetProperty(propertyKey, mitk::FloatProperty::New(floatValue)); } void ToFImageGrabber::SetStringProperty( const char* propertyKey, const char* stringValue ) { SetProperty(propertyKey, mitk::StringProperty::New(stringValue)); } void ToFImageGrabber::SetProperty( const char *propertyKey, BaseProperty* propertyValue ) { this->m_ToFCameraDevice->SetProperty(propertyKey, propertyValue); } void ToFImageGrabber::OnToFCameraDeviceModified() { this->Modified(); } + + void ToFImageGrabber::CleanUpImageArrays() + { + // free buffer + if (m_IntensityArray) + { + delete [] m_IntensityArray; + m_IntensityArray = NULL; + } + if (m_DistanceArray) + { + delete [] m_DistanceArray; + m_DistanceArray = NULL; + } + if (m_AmplitudeArray) + { + delete [] m_AmplitudeArray; + m_AmplitudeArray = NULL; + } + if (m_SourceDataArray) + { + delete [] m_SourceDataArray; + m_SourceDataArray = NULL; + } + } + + void ToFImageGrabber::AllocateImageArrays() + { + // cleanup memory if necessary + this->CleanUpImageArrays(); + // allocate buffer + m_IntensityArray = new float[m_PixelNumber]; + m_DistanceArray = new float[m_PixelNumber]; + m_AmplitudeArray = new float[m_PixelNumber]; + m_SourceDataArray = new char[m_SourceDataSize]; + } } diff --git a/Modules/ToFHardware/mitkToFImageGrabber.h b/Modules/ToFHardware/mitkToFImageGrabber.h index 0cbb604351..fa02437c58 100644 --- a/Modules/ToFHardware/mitkToFImageGrabber.h +++ b/Modules/ToFHardware/mitkToFImageGrabber.h @@ -1,164 +1,173 @@ /*========================================================================= 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 __mitkToFImageGrabber_h #define __mitkToFImageGrabber_h #include "mitkToFHardwareExports.h" #include "mitkCommon.h" #include "mitkImageSource.h" #include "mitkToFCameraDevice.h" #include "itkObject.h" #include "itkObjectFactory.h" namespace mitk { /**Documentation * \brief Image source providing ToF images. Interface for filters provided in ToFProcessing module * * This class internally holds a ToFCameraDevice to access the images acquired by a ToF camera. * A pre-configured instance for a specific ToF camera (e.g. PMD CamCube 3) can be obtained using * the class ToFImageGrabberCreator. * Provided images include: distance image (output 0), amplitude image (output 1), intensity image (output 2) * * \ingroup ToFHardware */ class MITK_TOFHARDWARE_EXPORT ToFImageGrabber : public mitk::ImageSource { public: mitkClassMacro( ToFImageGrabber , ImageSource ); itkNewMacro( Self ); /*! \brief Establish a connection to the ToF camera \param device specifies the actually used ToF Camera. 0: PMD O3D, 1: PMD CamCube 2.0 */ virtual bool ConnectCamera(); /*! \brief Disconnects the ToF camera */ virtual bool DisconnectCamera(); /*! \brief Starts the continuous updating of the camera. A separate thread updates the source data, the main thread processes the source data and creates images and coordinates */ virtual void StartCamera(); /*! \brief Stops the continuous updating of the camera */ virtual void StopCamera(); /*! \brief Returns true if the camera is connected and started */ virtual bool IsCameraActive(); /*! \brief Sets the ToF device, the image grabber is grabbing the images from \param aToFCameraDevice device internally used for grabbing the images from the camera */ void SetCameraDevice(ToFCameraDevice* aToFCameraDevice); /*! \brief Get the currently set ToF camera device \return device currently used for grabbing images from the camera */ ToFCameraDevice* GetCameraDevice(); /*! \brief Set the modulation frequency used by the ToF camera. For default values see the corresponding device classes \param modulationFrequency modulation frequency in Hz */ int SetModulationFrequency(int modulationFrequency); /*! \brief Get the modulation frequency used by the ToF camera. \return modulation frequency in MHz */ int GetModulationFrequency(); /*! \brief Set the integration time used by the ToF camera. For default values see the corresponding device classes \param integrationTime integration time in ms */ int SetIntegrationTime(int integrationTime); /*! \brief Get the integration time in used by the ToF camera. \return integration time in ms */ int GetIntegrationTime(); /*! \brief Get the dimension in x direction of the ToF image \return width of the image */ int GetCaptureWidth(); /*! \brief Get the dimension in y direction of the ToF image \return height of the image */ int GetCaptureHeight(); /*! \brief Get the number of pixel in the ToF image \return number of pixel */ int GetPixelNumber(); // properties void SetBoolProperty( const char* propertyKey, bool boolValue ); void SetIntProperty( const char* propertyKey, int intValue ); void SetFloatProperty( const char* propertyKey, float floatValue ); void SetStringProperty( const char* propertyKey, const char* stringValue ); void SetProperty( const char *propertyKey, BaseProperty* propertyValue ); protected: /// /// called when the ToFCameraDevice was modified /// void OnToFCameraDeviceModified(); + /*! + \brief clean up memory allocated for the image arrays m_IntensityArray, m_DistanceArray, m_AmplitudeArray and m_SourceDataArray + */ + virtual void CleanUpImageArrays(); + /*! + \brief Allocate memory for the image arrays m_IntensityArray, m_DistanceArray, m_AmplitudeArray and m_SourceDataArray + */ + virtual void AllocateImageArrays(); + ToFCameraDevice::Pointer m_ToFCameraDevice; ///< Device allowing acces to ToF image data int m_CaptureWidth; ///< Width of the captured ToF image int m_CaptureHeight; ///< Height of the captured ToF image int m_PixelNumber; ///< Number of pixels in the image int m_ImageSequence; ///< counter for currently acquired images int m_SourceDataSize; ///< size of the source data in bytes float* m_IntensityArray; ///< member holding the current intensity array float* m_DistanceArray; ///< member holding the current distance array float* m_AmplitudeArray; ///< member holding the current amplitude array char* m_SourceDataArray;///< member holding the current source data array unsigned long m_DeviceObserverTag; ///< tag of the oberver for the the ToFCameraDevice ToFImageGrabber(); ~ToFImageGrabber(); /*! \brief Method generating the outputs of this filter. Called in the updated process of the pipeline. 0: distance image 1: amplitude image 2: intensity image */ void GenerateData(); private: }; } //END mitk namespace #endif diff --git a/Modules/ToFProcessing/mitkToFSurfaceVtkMapper3D.cpp b/Modules/ToFProcessing/mitkToFSurfaceVtkMapper3D.cpp index e5a7efdd5c..8f8d93480e 100644 --- a/Modules/ToFProcessing/mitkToFSurfaceVtkMapper3D.cpp +++ b/Modules/ToFProcessing/mitkToFSurfaceVtkMapper3D.cpp @@ -1,532 +1,532 @@ /*========================================================================= Program: Medical Imaging & Interaction Toolkit Language: C++ Date: $Date: 2010-05-26 14:10:28 +0200 (Mi, 26 Mai 2010) $ Version: $Revision: 23106 $ 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 "mitkToFSurfaceVtkMapper3D.h" #include "mitkDataNode.h" #include "mitkProperties.h" #include "mitkColorProperty.h" #include "mitkLookupTableProperty.h" #include "mitkVtkRepresentationProperty.h" #include "mitkVtkInterpolationProperty.h" #include "mitkVtkScalarModeProperty.h" #include "mitkClippingProperty.h" #include "mitkShaderProperty.h" #include "mitkShaderRepository.h" #include #include #include #include #include #include #include #include #include #include #include //const mitk::ToFSurface* mitk::ToFSurfaceVtkMapper3D::GetInput() const mitk::Surface* mitk::ToFSurfaceVtkMapper3D::GetInput() { //return static_cast ( GetData() ); return static_cast ( GetData() ); } mitk::ToFSurfaceVtkMapper3D::ToFSurfaceVtkMapper3D() { // m_Prop3D = vtkActor::New(); m_GenerateNormals = false; this->m_Texture = NULL; this->m_TextureWidth = 0; this->m_TextureHeight = 0; this->m_VtkScalarsToColors = NULL; } mitk::ToFSurfaceVtkMapper3D::~ToFSurfaceVtkMapper3D() { // m_Prop3D->Delete(); } -void mitk::ToFSurfaceVtkMapper3D::GenerateData(mitk::BaseRenderer* renderer) +void mitk::ToFSurfaceVtkMapper3D::GenerateDataForRenderer(mitk::BaseRenderer* renderer) { LocalStorage *ls = m_LSH.GetLocalStorage(renderer); bool visible = IsVisible(renderer); if(visible==false) { ls->m_Actor->VisibilityOff(); return; } // // set the input-object at time t for the mapper // //mitk::ToFSurface::Pointer input = const_cast< mitk::ToFSurface* >( this->GetInput() ); mitk::Surface::Pointer input = const_cast< mitk::Surface* >( this->GetInput() ); vtkPolyData * polydata = input->GetVtkPolyData( this->GetTimestep() ); if(polydata == NULL) { ls->m_Actor->VisibilityOff(); return; } if ( m_GenerateNormals ) { ls->m_VtkPolyDataNormals->SetInput( polydata ); ls->m_VtkPolyDataMapper->SetInput( ls->m_VtkPolyDataNormals->GetOutput() ); } else { ls->m_VtkPolyDataMapper->SetInput( polydata ); } // // apply properties read from the PropertyList // ApplyProperties(ls->m_Actor, renderer); if(visible) ls->m_Actor->VisibilityOn(); // // TOF extension for visualization (color/texture mapping) // if (this->m_VtkScalarsToColors) { // set the color transfer funtion if applied ls->m_VtkPolyDataMapper->SetLookupTable(this->m_VtkScalarsToColors); } if (this->m_Texture) { // create a vtk image as basic for texture vtkImageData* imageData = vtkImageData::New(); int width = this->m_TextureWidth; int height = this->m_TextureHeight; imageData->SetDimensions(width, height, 1); imageData->SetScalarTypeToUnsignedChar(); imageData->SetNumberOfScalarComponents(3); // RGB imageData->SetSpacing(0.0, 0.0, 0.0); imageData->SetOrigin(width/2, height/2, 0.0); imageData->AllocateScalars(); // allocate storage for image data imageData->SetScalarType( VTK_UNSIGNED_CHAR ); // create a vtk array to hold the input unsigned char* texture (e.g. from the video camera) vtkDataArray *scalars; scalars = vtkUnsignedCharArray::New(); scalars->SetNumberOfComponents(3); scalars->SetVoidArray(this->GetTexture(), width*height*3, 1); // prepare the image data from vtk array imageData->GetPointData()->SetScalars(scalars); scalars->Delete(); // create vtk texture vtkTexture *aTexture = vtkTexture::New(); aTexture->SetInput(imageData); aTexture->InterpolateOn(); ls->m_Actor->SetTexture(aTexture); aTexture->Delete(); } else { // remove the texture ls->m_Actor->SetTexture(0); } } void mitk::ToFSurfaceVtkMapper3D::ResetMapper( BaseRenderer* renderer ) { LocalStorage *ls = m_LSH.GetLocalStorage(renderer); ls->m_Actor->VisibilityOff(); } void mitk::ToFSurfaceVtkMapper3D::ApplyMitkPropertiesToVtkProperty(mitk::DataNode *node, vtkProperty* property, mitk::BaseRenderer* renderer) { // Colors { double ambient [3] = { 0.5,0.5,0.0 }; double diffuse [3] = { 0.5,0.5,0.0 }; double specular[3] = { 1.0,1.0,1.0 }; float coeff_ambient = 0.5f; float coeff_diffuse = 0.5f; float coeff_specular= 0.5f; float power_specular=10.0f; // Color { mitk::ColorProperty::Pointer p; node->GetProperty(p, "color", renderer); if(p.IsNotNull()) { mitk::Color c = p->GetColor(); ambient[0]=c.GetRed(); ambient[1]=c.GetGreen(); ambient[2]=c.GetBlue(); diffuse[0]=c.GetRed(); diffuse[1]=c.GetGreen(); diffuse[2]=c.GetBlue(); // Setting specular color to the same, make physically no real sense, however vtk rendering slows down, if these colors are different. specular[0]=c.GetRed(); specular[1]=c.GetGreen(); specular[2]=c.GetBlue(); } } // Ambient { mitk::ColorProperty::Pointer p; node->GetProperty(p, "material.ambientColor", renderer); if(p.IsNotNull()) { mitk::Color c = p->GetColor(); ambient[0]=c.GetRed(); ambient[1]=c.GetGreen(); ambient[2]=c.GetBlue(); } } // Diffuse { mitk::ColorProperty::Pointer p; node->GetProperty(p, "material.diffuseColor", renderer); if(p.IsNotNull()) { mitk::Color c = p->GetColor(); diffuse[0]=c.GetRed(); diffuse[1]=c.GetGreen(); diffuse[2]=c.GetBlue(); } } // Specular { mitk::ColorProperty::Pointer p; node->GetProperty(p, "material.specularColor", renderer); if(p.IsNotNull()) { mitk::Color c = p->GetColor(); specular[0]=c.GetRed(); specular[1]=c.GetGreen(); specular[2]=c.GetBlue(); } } // Ambient coeff { node->GetFloatProperty("material.ambientCoefficient", coeff_ambient, renderer); } // Diffuse coeff { node->GetFloatProperty("material.diffuseCoefficient", coeff_diffuse, renderer); } // Specular coeff { node->GetFloatProperty("material.specularCoefficient", coeff_specular, renderer); } // Specular power { node->GetFloatProperty("material.specularPower", power_specular, renderer); } property->SetAmbient( coeff_ambient ); property->SetDiffuse( coeff_diffuse ); property->SetSpecular( coeff_specular ); property->SetSpecularPower( power_specular ); property->SetAmbientColor( ambient ); property->SetDiffuseColor( diffuse ); property->SetSpecularColor( specular ); } // Render mode { // Opacity { float opacity = 1.0f; if( node->GetOpacity(opacity,renderer) ) property->SetOpacity( opacity ); } // Wireframe line width { float lineWidth = 1; node->GetFloatProperty("material.wireframeLineWidth", lineWidth, renderer); property->SetLineWidth( lineWidth ); } // Representation { mitk::VtkRepresentationProperty::Pointer p; node->GetProperty(p, "material.representation", renderer); if(p.IsNotNull()) property->SetRepresentation( p->GetVtkRepresentation() ); } // Interpolation { mitk::VtkInterpolationProperty::Pointer p; node->GetProperty(p, "material.interpolation", renderer); if(p.IsNotNull()) property->SetInterpolation( p->GetVtkInterpolation() ); } } } void mitk::ToFSurfaceVtkMapper3D::ApplyProperties(vtkActor* /*actor*/, mitk::BaseRenderer* renderer) { LocalStorage *ls = m_LSH.GetLocalStorage(renderer); // Applying shading properties { Superclass::ApplyProperties( ls->m_Actor, renderer ) ; // VTK Properties ApplyMitkPropertiesToVtkProperty( this->GetDataNode(), ls->m_Actor->GetProperty(), renderer ); // Shaders mitk::ShaderRepository::GetGlobalShaderRepository()->ApplyProperties(this->GetDataNode(),ls->m_Actor,renderer,ls->m_ShaderTimestampUpdate); } mitk::LookupTableProperty::Pointer lookupTableProp; this->GetDataNode()->GetProperty(lookupTableProp, "LookupTable", renderer); if (lookupTableProp.IsNotNull() ) { ls->m_VtkPolyDataMapper->SetLookupTable(lookupTableProp->GetLookupTable()->GetVtkLookupTable()); } mitk::LevelWindow levelWindow; if(this->GetDataNode()->GetLevelWindow(levelWindow, renderer, "levelWindow")) { ls->m_VtkPolyDataMapper->SetScalarRange(levelWindow.GetLowerWindowBound(),levelWindow.GetUpperWindowBound()); } else if(this->GetDataNode()->GetLevelWindow(levelWindow, renderer)) { ls->m_VtkPolyDataMapper->SetScalarRange(levelWindow.GetLowerWindowBound(),levelWindow.GetUpperWindowBound()); } bool scalarVisibility = false; this->GetDataNode()->GetBoolProperty("scalar visibility", scalarVisibility); ls->m_VtkPolyDataMapper->SetScalarVisibility( (scalarVisibility ? 1 : 0) ); if(scalarVisibility) { mitk::VtkScalarModeProperty* scalarMode; if(this->GetDataNode()->GetProperty(scalarMode, "scalar mode", renderer)) { ls->m_VtkPolyDataMapper->SetScalarMode(scalarMode->GetVtkScalarMode()); } else ls->m_VtkPolyDataMapper->SetScalarModeToDefault(); bool colorMode = false; this->GetDataNode()->GetBoolProperty("color mode", colorMode); ls->m_VtkPolyDataMapper->SetColorMode( (colorMode ? 1 : 0) ); float scalarsMin = 0; if (dynamic_cast(this->GetDataNode()->GetProperty("ScalarsRangeMinimum")) != NULL) scalarsMin = dynamic_cast(this->GetDataNode()->GetProperty("ScalarsRangeMinimum"))->GetValue(); float scalarsMax = 1.0; if (dynamic_cast(this->GetDataNode()->GetProperty("ScalarsRangeMaximum")) != NULL) scalarsMax = dynamic_cast(this->GetDataNode()->GetProperty("ScalarsRangeMaximum"))->GetValue(); ls->m_VtkPolyDataMapper->SetScalarRange(scalarsMin,scalarsMax); } // deprecated settings bool deprecatedUseCellData = false; this->GetDataNode()->GetBoolProperty("deprecated useCellDataForColouring", deprecatedUseCellData); bool deprecatedUsePointData = false; this->GetDataNode()->GetBoolProperty("deprecated usePointDataForColouring", deprecatedUsePointData); if (deprecatedUseCellData) { ls->m_VtkPolyDataMapper->SetColorModeToDefault(); ls->m_VtkPolyDataMapper->SetScalarRange(0,255); ls->m_VtkPolyDataMapper->ScalarVisibilityOn(); ls->m_VtkPolyDataMapper->SetScalarModeToUseCellData(); ls->m_Actor->GetProperty()->SetSpecular (1); ls->m_Actor->GetProperty()->SetSpecularPower (50); ls->m_Actor->GetProperty()->SetInterpolationToPhong(); } else if (deprecatedUsePointData) { float scalarsMin = 0; if (dynamic_cast(this->GetDataNode()->GetProperty("ScalarsRangeMinimum")) != NULL) scalarsMin = dynamic_cast(this->GetDataNode()->GetProperty("ScalarsRangeMinimum"))->GetValue(); float scalarsMax = 0.1; if (dynamic_cast(this->GetDataNode()->GetProperty("ScalarsRangeMaximum")) != NULL) scalarsMax = dynamic_cast(this->GetDataNode()->GetProperty("ScalarsRangeMaximum"))->GetValue(); ls->m_VtkPolyDataMapper->SetScalarRange(scalarsMin,scalarsMax); ls->m_VtkPolyDataMapper->SetColorModeToMapScalars(); ls->m_VtkPolyDataMapper->ScalarVisibilityOn(); ls->m_Actor->GetProperty()->SetSpecular (1); ls->m_Actor->GetProperty()->SetSpecularPower (50); ls->m_Actor->GetProperty()->SetInterpolationToPhong(); } int deprecatedScalarMode = VTK_COLOR_MODE_DEFAULT; if(this->GetDataNode()->GetIntProperty("deprecated scalar mode", deprecatedScalarMode, renderer)) { ls->m_VtkPolyDataMapper->SetScalarMode(deprecatedScalarMode); ls->m_VtkPolyDataMapper->ScalarVisibilityOn(); ls->m_Actor->GetProperty()->SetSpecular (1); ls->m_Actor->GetProperty()->SetSpecularPower (50); //m_Actor->GetProperty()->SetInterpolationToPhong(); } // Check whether one or more ClippingProperty objects have been defined for // this node. Check both renderer specific and global property lists, since // properties in both should be considered. const PropertyList::PropertyMap *rendererProperties = this->GetDataNode()->GetPropertyList( renderer )->GetMap(); const PropertyList::PropertyMap *globalProperties = this->GetDataNode()->GetPropertyList( NULL )->GetMap(); // Add clipping planes (if any) ls->m_ClippingPlaneCollection->RemoveAllItems(); PropertyList::PropertyMap::const_iterator it; for ( it = rendererProperties->begin(); it != rendererProperties->end(); ++it ) { this->CheckForClippingProperty( renderer,(*it).second.GetPointer() ); } for ( it = globalProperties->begin(); it != globalProperties->end(); ++it ) { this->CheckForClippingProperty( renderer,(*it).second.GetPointer() ); } if ( ls->m_ClippingPlaneCollection->GetNumberOfItems() > 0 ) { ls->m_VtkPolyDataMapper->SetClippingPlanes( ls->m_ClippingPlaneCollection ); } else { ls->m_VtkPolyDataMapper->RemoveAllClippingPlanes(); } } vtkProp *mitk::ToFSurfaceVtkMapper3D::GetVtkProp(mitk::BaseRenderer *renderer) { LocalStorage *ls = m_LSH.GetLocalStorage(renderer); return ls->m_Actor; } void mitk::ToFSurfaceVtkMapper3D::CheckForClippingProperty( mitk::BaseRenderer* renderer, mitk::BaseProperty *property ) { LocalStorage *ls = m_LSH.GetLocalStorage(renderer); // m_Prop3D = ls->m_Actor; ClippingProperty *clippingProperty = dynamic_cast< ClippingProperty * >( property ); if ( (clippingProperty != NULL) && (clippingProperty->GetClippingEnabled()) ) { const Point3D &origin = clippingProperty->GetOrigin(); const Vector3D &normal = clippingProperty->GetNormal(); vtkPlane *clippingPlane = vtkPlane::New(); clippingPlane->SetOrigin( origin[0], origin[1], origin[2] ); clippingPlane->SetNormal( normal[0], normal[1], normal[2] ); ls->m_ClippingPlaneCollection->AddItem( clippingPlane ); clippingPlane->UnRegister( NULL ); } } void mitk::ToFSurfaceVtkMapper3D::SetDefaultPropertiesForVtkProperty(mitk::DataNode* node, mitk::BaseRenderer* renderer, bool overwrite) { // Shading { node->AddProperty( "material.wireframeLineWidth", mitk::FloatProperty::New(1.0f) , renderer, overwrite ); node->AddProperty( "material.ambientCoefficient" , mitk::FloatProperty::New(0.05f) , renderer, overwrite ); node->AddProperty( "material.diffuseCoefficient" , mitk::FloatProperty::New(0.9f) , renderer, overwrite ); node->AddProperty( "material.specularCoefficient", mitk::FloatProperty::New(1.0f) , renderer, overwrite ); node->AddProperty( "material.specularPower" , mitk::FloatProperty::New(16.0f) , renderer, overwrite ); //node->AddProperty( "material.ambientColor" , mitk::ColorProperty::New(1.0f,1.0f,1.0f), renderer, overwrite ); //node->AddProperty( "material.diffuseColor" , mitk::ColorProperty::New(1.0f,1.0f,1.0f), renderer, overwrite ); //node->AddProperty( "material.specularColor" , mitk::ColorProperty::New(1.0f,1.0f,1.0f), renderer, overwrite ); node->AddProperty( "material.representation" , mitk::VtkRepresentationProperty::New() , renderer, overwrite ); node->AddProperty( "material.interpolation" , mitk::VtkInterpolationProperty::New() , renderer, overwrite ); } // Shaders { mitk::ShaderRepository::GetGlobalShaderRepository()->AddDefaultProperties(node,renderer,overwrite); } } void mitk::ToFSurfaceVtkMapper3D::SetDefaultProperties(mitk::DataNode* node, mitk::BaseRenderer* renderer, bool overwrite) { node->AddProperty( "color", mitk::ColorProperty::New(1.0f,1.0f,1.0f), renderer, overwrite ); node->AddProperty( "opacity", mitk::FloatProperty::New(1.0), renderer, overwrite ); mitk::ToFSurfaceVtkMapper3D::SetDefaultPropertiesForVtkProperty(node,renderer,overwrite); // Shading node->AddProperty( "scalar visibility", mitk::BoolProperty::New(false), renderer, overwrite ); node->AddProperty( "color mode", mitk::BoolProperty::New(false), renderer, overwrite ); node->AddProperty( "scalar mode", mitk::VtkScalarModeProperty::New(), renderer, overwrite ); mitk::Surface::Pointer surface = dynamic_cast(node->GetData()); if(surface.IsNotNull()) { if((surface->GetVtkPolyData() != 0) && (surface->GetVtkPolyData()->GetPointData() != NULL) && (surface->GetVtkPolyData()->GetPointData()->GetScalars() != 0)) { node->AddProperty( "scalar visibility", mitk::BoolProperty::New(true), renderer, overwrite ); node->AddProperty( "color mode", mitk::BoolProperty::New(true), renderer, overwrite ); } } Superclass::SetDefaultProperties(node, renderer, overwrite); } void mitk::ToFSurfaceVtkMapper3D::SetImmediateModeRenderingOn(int /*on*/) { /* if (m_VtkPolyDataMapper != NULL) m_VtkPolyDataMapper->SetImmediateModeRendering(on); */ } void mitk::ToFSurfaceVtkMapper3D::SetTexture(unsigned char* texture) { this->m_Texture = texture; } unsigned char* mitk::ToFSurfaceVtkMapper3D::GetTexture() { return this->m_Texture; } void mitk::ToFSurfaceVtkMapper3D::SetVtkScalarsToColors(vtkScalarsToColors* vtkScalarsToColors) { this->m_VtkScalarsToColors = vtkScalarsToColors; } vtkScalarsToColors* mitk::ToFSurfaceVtkMapper3D::GetVtkScalarsToColors() { return this->m_VtkScalarsToColors; } diff --git a/Modules/ToFProcessing/mitkToFSurfaceVtkMapper3D.h b/Modules/ToFProcessing/mitkToFSurfaceVtkMapper3D.h index 058defe90a..48e9d655fb 100644 --- a/Modules/ToFProcessing/mitkToFSurfaceVtkMapper3D.h +++ b/Modules/ToFProcessing/mitkToFSurfaceVtkMapper3D.h @@ -1,186 +1,186 @@ /*========================================================================= Program: Medical Imaging & Interaction Toolkit Language: C++ Date: $Date: 2010-03-18 14:08:01 +0100 (Do, 18 Mrz 2010) $ Version: $Revision: 21794 $ 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 MITKTOFSURFACEDATAVTKMAPPER3D_H_HEADER_INCLUDED_C1907273 #define MITKTOFSURFACEDATAVTKMAPPER3D_H_HEADER_INCLUDED_C1907273 #include "mitkCommon.h" #include "mitkVtkMapper3D.h" #include "mitkSurface.h" #include "mitkBaseRenderer.h" #include #include #include #include #include #include #include #include "mitkToFProcessingExports.h" namespace mitk { //##Documentation //## @brief Vtk-based mapper for Surface //## //## @ingroup Mapper /** * @brief Vtk-based mapper for Surface * * Properties that can be set for surfaces and influence the surfaceVTKMapper3D are: * * - \b "color": (ColorProperty) Diffuse color of the surface object (this property will be read when material.diffuseColor is not defined) * - \b "Opacity": (FloatProperty) Opacity of the surface object * - \b "material.ambientColor": (ColorProperty) Ambient color of the surface object * - \b "material.ambientCoefficient": ( FloatProperty) Ambient coefficient of the surface object * - \b "material.diffuseColor": ( ColorProperty) Diffuse color of the surface object * - \b "material.diffuseCoefficient": (FloatProperty) Diffuse coefficient of the surface object * - \b "material.specularColor": (ColorProperty) Specular Color of the surface object * - \b "material.specularCoefficient": (FloatProperty) Specular coefficient of the surface object * - \b "material.specularPower": (FloatProperty) Specular power of the surface object * - \b "material.interpolation": (VtkInterpolationProperty) Interpolation * - \b "material.representation": (VtkRepresentationProperty*) Representation * - \b "material.wireframeLineWidth": (FloatProperty) Width in pixels of the lines drawn. * - \b "scalar visibility": (BoolProperty) If the scarlars of the surface are visible * Properties to look for are: * * - \b "scalar visibility": if set to on, scalars assigned to the data are shown * Turn this on if using a lookup table. * - \b "ScalarsRangeMinimum": Optional. Can be used to store the scalar min, e.g. * for the level window settings. * - \b "ScalarsRangeMaximum": Optional. See above. * * There might be still some other, deprecated properties. These will not be documented anymore. * Please check the source if you really need them. * * @ingroup Mapper */ class mitkToFProcessing_EXPORT ToFSurfaceVtkMapper3D : public VtkMapper3D { public: mitkClassMacro(ToFSurfaceVtkMapper3D, VtkMapper3D); itkNewMacro(Self); itkSetMacro(GenerateNormals, bool); itkGetMacro(GenerateNormals, bool); //enable ImmediateModeRendering for vtkMapping //yet to solve bug 1398 void SetImmediateModeRenderingOn(int on = 1); itkGetMacro(ImmediateModeRenderingOn, int); //virtual const mitk::ToFSurface* GetInput(); virtual const mitk::Surface* GetInput(); virtual vtkProp *GetVtkProp(mitk::BaseRenderer *renderer); virtual void ApplyProperties(vtkActor* actor, mitk::BaseRenderer* renderer); static void SetDefaultProperties(mitk::DataNode* node, mitk::BaseRenderer* renderer = NULL, bool overwrite = false); void SetTexture(unsigned char*); unsigned char* GetTexture(); itkSetMacro(TextureWidth, int); itkSetMacro(TextureHeight, int); void SetVtkScalarsToColors(vtkScalarsToColors* vtkScalarsToColors); vtkScalarsToColors* GetVtkScalarsToColors(); protected: ToFSurfaceVtkMapper3D(); virtual ~ToFSurfaceVtkMapper3D(); - virtual void GenerateData(mitk::BaseRenderer* renderer); + virtual void GenerateDataForRenderer(mitk::BaseRenderer* renderer); virtual void ResetMapper( mitk::BaseRenderer* renderer ); /** Checks whether the specified property is a ClippingProperty and if yes, * adds it to m_ClippingPlaneCollection (internal method). */ virtual void CheckForClippingProperty( mitk::BaseRenderer* renderer, mitk::BaseProperty *property ); bool m_GenerateNormals; //enable ImmediateModeRendering for the vtkMapper int m_ImmediateModeRenderingOn; unsigned char* m_Texture; // pointer to the texture/video image int m_TextureWidth; // width of the texture/video image int m_TextureHeight; // height of the texture/video image vtkScalarsToColors* m_VtkScalarsToColors; // vtk color transfer funtion public: class LocalStorage : public mitk::Mapper::BaseLocalStorage { public: vtkActor* m_Actor; vtkPolyDataMapper *m_VtkPolyDataMapper; vtkPolyDataNormals *m_VtkPolyDataNormals; vtkPlaneCollection *m_ClippingPlaneCollection; itk::TimeStamp m_ShaderTimestampUpdate; LocalStorage() { m_VtkPolyDataMapper = vtkOpenGLPolyDataMapper::New(); m_VtkPolyDataNormals = vtkPolyDataNormals::New(); m_Actor = vtkActor::New(); m_ClippingPlaneCollection = vtkPlaneCollection::New(); m_Actor->SetMapper(m_VtkPolyDataMapper); } ~LocalStorage() { m_VtkPolyDataMapper->Delete(); m_VtkPolyDataNormals->Delete(); m_Actor->Delete(); m_ClippingPlaneCollection->Delete(); } }; mitk::Mapper::LocalStorageHandler m_LSH; static void ApplyMitkPropertiesToVtkProperty(mitk::DataNode *node, vtkProperty* property, mitk::BaseRenderer* renderer); static void SetDefaultPropertiesForVtkProperty(mitk::DataNode* node, mitk::BaseRenderer* renderer, bool overwrite); }; } // namespace mitk #endif /* MITKTOFSURFACEDATAVTKMAPPER3D_H_HEADER_INCLUDED_C1907273 */