diff --git a/Modules/ToFHardware/CMakeLists.txt b/Modules/ToFHardware/CMakeLists.txt index 22f063037b..efce2913ba 100644 --- a/Modules/ToFHardware/CMakeLists.txt +++ b/Modules/ToFHardware/CMakeLists.txt @@ -1,34 +1,39 @@ include(mitkToFHardware.cmake) if(MITK_USE_TOF_PMDCAMCUBE) set(INCLUDE_DIRS_INTERNAL ${INCLUDE_DIRS_INTERNAL} ${MITK_PMD_SDK_DIR}/include) set(ADDITIONAL_LIBS ${ADDITIONAL_LIBS} ${MITK_PMD_LIB}) endif(MITK_USE_TOF_PMDCAMCUBE) if(MITK_USE_TOF_O3) set(INCLUDE_DIRS_INTERNAL ${INCLUDE_DIRS_INTERNAL} ${MITK_PMD_SDK_DIR}/include) set(ADDITIONAL_LIBS ${ADDITIONAL_LIBS} ${MITK_PMD_LIB}) endif(MITK_USE_TOF_O3) if(MITK_USE_TOF_PMDCAMBOARD) set(INCLUDE_DIRS_INTERNAL ${INCLUDE_DIRS_INTERNAL} ${MITK_PMD_SDK_DIR}/include) set(ADDITIONAL_LIBS ${ADDITIONAL_LIBS} ${MITK_PMD_LIB}) endif(MITK_USE_TOF_PMDCAMBOARD) if(MITK_USE_TOF_MESASR4000) set(INCLUDE_DIRS_INTERNAL ${INCLUDE_DIRS_INTERNAL} ${MITK_MESA_SDK_DIR}/include) set(ADDITIONAL_LIBS ${ADDITIONAL_LIBS} ${MITK_MESA_LIB}) endif(MITK_USE_TOF_MESASR4000) +IF(MITK_USE_TOF_KINECT) + SET(INCLUDE_DIRS_INTERNAL ${INCLUDE_DIRS_INTERNAL} ${MITK_KINECT_INCLUDE_DIR}) + SET(ADDITIONAL_LIBS ${ADDITIONAL_LIBS} ${MITK_KINECT_LIB}) +ENDIF(MITK_USE_TOF_KINECT) + MITK_CREATE_MODULE(mitkToFHardware SUBPROJECTS MITK-ToF INCLUDE_DIRS ${MITK_BIN_DIR} INTERNAL_INCLUDE_DIRS ${INCLUDE_DIRS_INTERNAL} DEPENDS Mitk MitkExt mitkOpenCVVideoSupport MitkIGT LegacyAdaptors EXPORT_DEFINE MITK_TOFHARDWARE_EXPORT ADDITIONAL_LIBS ${ADDITIONAL_LIBS} ) add_subdirectory(Testing) diff --git a/Modules/ToFHardware/Testing/files.cmake b/Modules/ToFHardware/Testing/files.cmake index c2997f92f5..8a641c6fce 100644 --- a/Modules/ToFHardware/Testing/files.cmake +++ b/Modules/ToFHardware/Testing/files.cmake @@ -1,29 +1,30 @@ set(MODULE_TESTS mitkThreadedToFRawDataReconstructionTest.cpp mitkToFCameraMITKPlayerControllerTest.cpp mitkToFCameraMITKPlayerDeviceTest.cpp mitkToFCameraPMDCamBoardControllerTest.cpp mitkToFCameraPMDCamBoardDeviceTest.cpp #mitkToFCameraPMDRawDataCamBoardDeviceTest.cpp mitkToFCameraPMDCamCubeControllerTest.cpp mitkToFCameraPMDCamCubeDeviceTest.cpp #mitkToFCameraPMDRawDataCamCubeDeviceTest.cpp mitkToFCameraPMDControllerTest.cpp mitkToFCameraPMDDeviceTest.cpp mitkToFCameraPMDRawDataDeviceTest.cpp mitkToFCameraPMDMITKPlayerControllerTest.cpp mitkToFCameraPMDMITKPlayerDeviceTest.cpp mitkToFCameraPMDO3ControllerTest.cpp mitkToFCameraPMDO3DeviceTest.cpp mitkToFCameraPMDPlayerControllerTest.cpp mitkToFCameraPMDPlayerDeviceTest.cpp mitkToFImageCsvWriterTest.cpp mitkToFImageGrabberTest.cpp mitkToFImageRecorderTest.cpp mitkToFImageRecorderFilterTest.cpp mitkToFImageWriterTest.cpp mitkToFNrrdImageWriterTest.cpp - mitkToFPicImageWriterTest.cpp mitkToFOpenCVImageGrabberTest.cpp + mitkKinectControllerTest.cpp + mitkKinectDeviceTest.cpp ) diff --git a/Modules/ToFHardware/Testing/mitkKinectControllerTest.cpp b/Modules/ToFHardware/Testing/mitkKinectControllerTest.cpp new file mode 100644 index 0000000000..2d13ab73ae --- /dev/null +++ b/Modules/ToFHardware/Testing/mitkKinectControllerTest.cpp @@ -0,0 +1,41 @@ +/*========================================================================= + +Program: Medical Imaging & Interaction Toolkit +Language: C++ +Date: $Date: 2010-03-12 14:05:50 +0100 (Fr, 12 Mrz 2010) $ +Version: $Revision: 16010 $ + +Copyright (c) German Cancer Research Center, Division of Medical and +Biological Informatics. All rights reserved. +See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. + +This software is distributed WITHOUT ANY WARRANTY; without even +the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the above copyright notices for more information. + +=========================================================================*/ + +#include +#include + +/**Documentation + * test for the class "KinectController". + */ +int mitkKinectControllerTest(int /* argc */, char* /*argv*/[]) +{ + + MITK_TEST_BEGIN("KinectController"); + + mitk::KinectController::Pointer testObject = mitk::KinectController::New(); + MITK_TEST_CONDITION_REQUIRED(!testObject.GetPointer()==NULL,"Testing initialzation!"); + MITK_TEST_CONDITION_REQUIRED(testObject->GetCaptureHeight()== 480 ,"Testing initialization of CaptureHeight"); + MITK_TEST_CONDITION_REQUIRED(testObject->GetCaptureWidth()== 640 ,"Testing initialization of CaptureWidth"); + MITK_TEST_CONDITION_REQUIRED(testObject->OpenCameraConnection(),"Testing opening of camera connection!"); + MITK_TEST_CONDITION_REQUIRED(testObject->UpdateCamera(),"Testing UpdateCamera()"); + MITK_TEST_CONDITION_REQUIRED(testObject->CloseCameraConnection(),"Testing closing of camera connection!"); + + MITK_TEST_END(); + +} + + diff --git a/Modules/ToFHardware/Testing/mitkKinectDeviceTest.cpp b/Modules/ToFHardware/Testing/mitkKinectDeviceTest.cpp new file mode 100644 index 0000000000..28bcf40929 --- /dev/null +++ b/Modules/ToFHardware/Testing/mitkKinectDeviceTest.cpp @@ -0,0 +1,46 @@ +/*========================================================================= + +Program: Medical Imaging & Interaction Toolkit +Language: C++ +Date: $Date: 2010-03-12 14:05:50 +0100 (Fr, 12 Mrz 2010) $ +Version: $Revision: 16010 $ + +Copyright (c) German Cancer Research Center, Division of Medical and +Biological Informatics. All rights reserved. +See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. + +This software is distributed WITHOUT ANY WARRANTY; without even +the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the above copyright notices for more information. + +=========================================================================*/ + +#include +#include + +/**Documentation + * test for the class "KinectDevice". + */ +int mitkKinectDeviceTest(int /* argc */, char* /*argv*/[]) +{ + + MITK_TEST_BEGIN("KinectDevice"); + + mitk::KinectDevice::Pointer testObject = mitk::KinectDevice::New(); + + MITK_TEST_CONDITION_REQUIRED(!testObject.GetPointer()==NULL,"Testing initialzation!"); + MITK_TEST_CONDITION_REQUIRED(testObject->ConnectCamera(),"Testing ConnectCamera()"); + MITK_TEST_OUTPUT(<<"Testing StartCamera()"); + testObject->StartCamera(); + int captureHeight = testObject->GetCaptureHeight(); + int captureWidth = testObject->GetCaptureWidth(); + MITK_TEST_CONDITION_REQUIRED(captureHeight== 480 ,"Testing initialization of CaptureHeight"); + MITK_TEST_CONDITION_REQUIRED(captureWidth== 640 ,"Testing initialization of CaptureWidth"); + // + MITK_TEST_OUTPUT(<<"Testing StopCamera()"); + testObject->StopCamera(); + MITK_TEST_CONDITION_REQUIRED(testObject->DisconnectCamera(),"Testing DisconnectCamera()"); + + MITK_TEST_END(); + +} diff --git a/Modules/ToFHardware/Testing/mitkToFPicImageWriterTest.cpp b/Modules/ToFHardware/Testing/mitkToFPicImageWriterTest.cpp deleted file mode 100644 index 6ad86ac061..0000000000 --- a/Modules/ToFHardware/Testing/mitkToFPicImageWriterTest.cpp +++ /dev/null @@ -1,134 +0,0 @@ -/*=================================================================== - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center, -Division of Medical and Biological Informatics. -All rights reserved. - -This software is distributed WITHOUT ANY WARRANTY; without -even the implied warranty of MERCHANTABILITY or FITNESS FOR -A PARTICULAR PURPOSE. - -See LICENSE.txt or http://www.mitk.org for details. - -===================================================================*/ - -#include -#include -#include -#include -#include -#include - -/**Documentation - * test for the class "ToFPicImageWriter". - */ -int mitkToFPicImageWriterTest(int /* argc */, char* /*argv*/[]) -{ - MITK_TEST_BEGIN("ToFPicImageWriter"); - - mitk::ToFPicImageWriter::Pointer tofPicWriter = mitk::ToFPicImageWriter::New(); - MITK_TEST_CONDITION_REQUIRED(tofPicWriter.GetPointer(), "Testing initialization of test object!"); - MITK_TEST_CONDITION_REQUIRED(tofPicWriter->GetExtension() == ".pic", "Testing initialization of extension member variable!"); - - //run the test with some unusual parameters - unsigned int dimX = 255; - unsigned int dimY = 188; - unsigned int pixelNumber = dimX*dimY; - unsigned int numOfFrames = 117; //or numberOfSlices - - //create 3 images filled with random values - mitk::Image::Pointer distanceImage = mitk::ImageGenerator::GenerateRandomImage(dimX, dimY, numOfFrames,0); - mitk::Image::Pointer amplitudeImage = mitk::ImageGenerator::GenerateRandomImage(dimX, dimY, numOfFrames,0); - mitk::Image::Pointer intensityImage = mitk::ImageGenerator::GenerateRandomImage(dimX, dimY, numOfFrames,0); - - //file names on the disc - std::string distanceImageFileName("distImg.pic"); - std::string amplitudeImageFileName("amplImg.pic"); - std::string intensityImageFileName("intImg.pic"); - - tofPicWriter->SetDistanceImageFileName(distanceImageFileName); - tofPicWriter->SetAmplitudeImageFileName(amplitudeImageFileName); - tofPicWriter->SetIntensityImageFileName(intensityImageFileName); - tofPicWriter->SetCaptureWidth(dimX); - tofPicWriter->SetCaptureHeight(dimY); - tofPicWriter->SetToFImageType(mitk::ToFImageWriter::ToFImageType3D); - - //buffer for each slice - float* distanceArray; - float* amplitudeArray; - float* intensityArray; - - float* distanceArrayRead; - float* amplitudeArrayRead; - float* intensityArrayRead; - - tofPicWriter->Open(); //open file/stream - //Note: the slices are written out reverse order, because the ToFPicImageWriter has to write them out immediately. - //A PicFileWriter would write them out vice versa and the PicFileWriter reads the slices vice versa. - - for(unsigned int i = numOfFrames; i > 0 ; i--) - { //write values to file/stream - //The slice index is "i-1", because "for(unsigned int i = numOfFrames-1; i >= 0 ; i--)" does not work for some reason - distanceArray = (float*)distanceImage->GetSliceData(i-1, 0, 0)->GetData(); - amplitudeArray = (float*)amplitudeImage->GetSliceData(i-1, 0, 0)->GetData(); - intensityArray = (float*)intensityImage->GetSliceData(i-1, 0, 0)->GetData(); - - //write (or add) the three slices to the file - tofPicWriter->Add(distanceArray, amplitudeArray, intensityArray); - } - tofPicWriter->Close(); //close file - - //read in the three images from disc - mitk::PicFileReader::Pointer fileReader = mitk::PicFileReader::New(); - fileReader->SetFileName(distanceImageFileName); - fileReader->Update(); - mitk::Image::Pointer distanceImageRead = fileReader->GetOutput(); - - fileReader = mitk::PicFileReader::New(); - fileReader->SetFileName(amplitudeImageFileName); - fileReader->Update(); - mitk::Image::Pointer amplitudeImageRead = fileReader->GetOutput(); - - fileReader = mitk::PicFileReader::New(); - fileReader->SetFileName(intensityImageFileName); - fileReader->Update(); - mitk::Image::Pointer intensityImageRead = fileReader->GetOutput(); - - bool readingCorrect = true; - // for all frames... - for(unsigned int j=0; jGetSliceData(j, 0, 0)->GetData(); - amplitudeArray = (float*)amplitudeImage->GetSliceData(j, 0, 0)->GetData(); - intensityArray = (float*)intensityImage->GetSliceData(j, 0, 0)->GetData(); - - //data read from disc - distanceArrayRead = (float*)distanceImageRead->GetSliceData(j, 0, 0)->GetData(); - amplitudeArrayRead = (float*)amplitudeImageRead->GetSliceData(j, 0, 0)->GetData(); - intensityArrayRead = (float*)intensityImageRead->GetSliceData(j, 0, 0)->GetData(); - - //for all pixels -for(unsigned int i=0; i +#endif + +namespace mitk +{ +class KinectController::KinectControllerPrivate +{ +public: + KinectControllerPrivate(); + ~KinectControllerPrivate(); + + bool ErrorText(unsigned int error); +#ifdef MITK_USE_TOF_KINECT + xn::Context m_Context; ///< OpenNI context + xn::DepthGenerator m_DepthGenerator; ///< Depth generator to access depth image of kinect + xn::ImageGenerator m_ImageGenerator; ///< Image generator to access RGB image of kinect + xn::IRGenerator m_IRGenerator; ///< IR generator to access IR image of kinect +#endif + + bool m_ConnectionCheck; ///< check if camera is connected or not + + bool m_UseIR; ///< flag indicating whether IR image is used or not + + unsigned int m_CaptureWidth; ///< image width + unsigned int m_CaptureHeight; ///< image height +}; + +KinectController::KinectControllerPrivate::KinectControllerPrivate(): + m_Context(NULL), + m_DepthGenerator(NULL), + m_ImageGenerator(NULL), + m_IRGenerator(NULL), + m_ConnectionCheck(false), + m_UseIR(false), + m_CaptureWidth(640), + m_CaptureHeight(480) +{ +} + +KinectController::KinectControllerPrivate::~KinectControllerPrivate() +{ +} + +bool KinectController::KinectControllerPrivate::ErrorText(unsigned int error) +{ + if(error != XN_STATUS_OK) + { + MITK_ERROR << "Camera Error " << xnGetStatusString(error); + return false; + } + else return true; +} + +KinectController::KinectController(): d(new KinectControllerPrivate) +{ +} + +KinectController::~KinectController() +{ + delete d; + } + + bool KinectController::OpenCameraConnection() + { + if (!d->m_ConnectionCheck) + { + // Initialize the OpenNI status + d->m_ConnectionCheck = !d->ErrorText(d->m_Context.Init()); + // Create a depth generator and set its resolution + XnMapOutputMode DepthMode; + d->m_ConnectionCheck = !d->ErrorText(d->m_DepthGenerator.Create(d->m_Context)); + d->m_DepthGenerator.GetMapOutputMode(DepthMode); + DepthMode.nXRes = xn::Resolution((XnResolution)XN_RES_VGA).GetXResolution(); + DepthMode.nYRes = xn::Resolution((XnResolution)XN_RES_VGA).GetYResolution(); + d->m_ConnectionCheck = !d->ErrorText(d->m_DepthGenerator.SetMapOutputMode(DepthMode)); + { + XnUInt32 NumModes = 10; + XnMapOutputMode *SupportedModes = new XnMapOutputMode[NumModes]; + d->m_ConnectionCheck = !d->ErrorText(d->m_DepthGenerator.GetSupportedMapOutputModes(SupportedModes, NumModes)); + for ( unsigned int i = 0; i < NumModes; i++ ) + { + std::cout << "DepthModes #" << i << std::endl; + std::cout << "Nx=" << SupportedModes[i].nXRes << std::endl; + std::cout << "Ny=" << SupportedModes[i].nYRes << std::endl; + std::cout << "FPS=" << SupportedModes[i].nFPS << std::endl; + } + delete[] SupportedModes; + } + + if (d->m_UseIR) + { + // Create the IR generator and set its resolution + d->m_ConnectionCheck = !d->ErrorText(d->m_IRGenerator.Create(d->m_Context)); + XnMapOutputMode IRMode; + d->m_IRGenerator.GetMapOutputMode(IRMode); + IRMode.nXRes = XN_VGA_X_RES; + IRMode.nYRes = XN_VGA_Y_RES; + IRMode.nFPS = 30; + d->m_ConnectionCheck = !d->ErrorText(d->m_IRGenerator.SetMapOutputMode(IRMode)); + + XnUInt32 NumModes = 10; + XnMapOutputMode *SupportedModes = new XnMapOutputMode[NumModes]; + d->m_ConnectionCheck = !d->ErrorText(d->m_IRGenerator.GetSupportedMapOutputModes(SupportedModes, NumModes)); + for ( unsigned int i = 0; i < NumModes; i++ ) + { + std::cout << "Mode #" << i << std::endl; + std::cout << "Nx=" << SupportedModes[i].nXRes << std::endl; + std::cout << "Ny=" << SupportedModes[i].nYRes << std::endl; + std::cout << "FPS=" << SupportedModes[i].nFPS << std::endl; + } + delete[] SupportedModes; + } + else + { + // Create an image generator and set its resolution + XnMapOutputMode ImageMode; + d->m_ConnectionCheck = !d->ErrorText(d->m_ImageGenerator.Create(d->m_Context)); + d->m_ImageGenerator.GetMapOutputMode(ImageMode); + ImageMode.nXRes = xn::Resolution((XnResolution)XN_RES_VGA).GetXResolution(); + ImageMode.nYRes = xn::Resolution((XnResolution)XN_RES_VGA).GetYResolution(); + d->m_ConnectionCheck = !d->ErrorText(d->m_ImageGenerator.SetMapOutputMode(ImageMode)); + { + XnUInt32 NumModes = 10; + XnMapOutputMode *SupportedModes = new XnMapOutputMode[NumModes]; + d->m_ConnectionCheck = !d->ErrorText(d->m_ImageGenerator.GetSupportedMapOutputModes(SupportedModes, NumModes)); + for ( unsigned int i = 0; i < NumModes; i++ ) + { + std::cout << "ImageModes #" << i << std::endl; + std::cout << "Nx=" << SupportedModes[i].nXRes << std::endl; + std::cout << "Ny=" << SupportedModes[i].nYRes << std::endl; + std::cout << "FPS=" << SupportedModes[i].nFPS << std::endl; + } + delete[] SupportedModes; + } + } + + // Camera registration + if ( d->m_DepthGenerator.IsCapabilitySupported(XN_CAPABILITY_ALTERNATIVE_VIEW_POINT) ) + { + if (d->m_UseIR) + { + d->m_ConnectionCheck = !d->ErrorText(d->m_DepthGenerator.GetAlternativeViewPointCap().SetViewPoint(d->m_IRGenerator)); + } + else + { + d->m_ConnectionCheck = !d->ErrorText(d->m_DepthGenerator.GetAlternativeViewPointCap().SetViewPoint(d->m_ImageGenerator)); + } + } + else + { + std::cout << "Alternative view point not supported by the depth generator..." << std::endl; + } + if (d->m_UseIR) + { + if ( d->m_IRGenerator.IsCapabilitySupported(XN_CAPABILITY_ALTERNATIVE_VIEW_POINT) ) + { + d->m_ConnectionCheck = !d->ErrorText(d->m_IRGenerator.GetAlternativeViewPointCap().SetViewPoint(d->m_DepthGenerator)); + } + else + { + std::cout << "Alternative view point not supported by the depth generator..." << std::endl; + } + } + + // Mirror data + d->m_ConnectionCheck = d->ErrorText(d->m_Context.SetGlobalMirror(!d->m_Context.GetGlobalMirror())); + + // Start data generation + d->m_ConnectionCheck = d->ErrorText(d->m_Context.StartGeneratingAll()); + +// // Update the connected flag +// d->m_ConnectionCheck = true; + } + MITK_INFO<<"Controller connect?"<m_ConnectionCheck; + return d->m_ConnectionCheck; + } + + bool KinectController::CloseCameraConnection() + { + d->m_ConnectionCheck = !d->ErrorText(d->m_Context.StopGeneratingAll()); + return !d->m_ConnectionCheck; + } + + bool KinectController::UpdateCamera() + { + bool updateSuccessful = d->ErrorText(d->m_Context.WaitAndUpdateAll()); + xn::DepthMetaData DepthMD; + d->m_DepthGenerator.GetMetaData(DepthMD); + d->m_CaptureWidth = DepthMD.XRes(); + d->m_CaptureHeight = DepthMD.YRes(); + return updateSuccessful; + } + + // TODO flag image + void KinectController::GetDistances(float* distances) + { + xn::DepthMetaData DepthMD; + d->m_DepthGenerator.GetMetaData(DepthMD); + const XnDepthPixel* DepthData = DepthMD.Data(); + + for (unsigned int i=0; im_CaptureWidth*d->m_CaptureHeight; i++) + { + distances[i] = DepthData[i]; + } + } + + void KinectController::GetRgb(unsigned char* rgb) + { + if (!d->m_UseIR) + { + xn::ImageMetaData ImageMD; + d->m_ImageGenerator.GetMetaData(ImageMD); + const XnRGB24Pixel* rgbPixelArray = ImageMD.RGB24Data(); + for (int i=0; im_CaptureWidth*d->m_CaptureHeight; i++) + { + rgb[i*3] = rgbPixelArray[i].nRed; + rgb[i*3+1] = rgbPixelArray[i].nGreen; + rgb[i*3+2] = rgbPixelArray[i].nBlue; + } + } + } + + void KinectController::GetAllData(float* distances, float* amplitudes, unsigned char* rgb) + { + // get current distance data + xn::DepthMetaData DepthMD; + d->m_DepthGenerator.GetMetaData(DepthMD); + const XnDepthPixel* DepthData = DepthMD.Data(); + // IR data + xn::IRMetaData IRData; + const XnIRPixel* IRPixelData; + // Image data + xn::ImageMetaData ImageMD; + const XnRGB24Pixel* rgbPixelArray; + if (d->m_UseIR) + { + d->m_IRGenerator.GetMetaData(IRData); + IRPixelData = IRData.Data(); + } + else + { + // get current rgb data + d->m_ImageGenerator.GetMetaData(ImageMD); + rgbPixelArray = ImageMD.RGB24Data(); + } + + for (unsigned int i=0; im_CaptureWidth*d->m_CaptureHeight; i++) + { + distances[i] = DepthData[i]; + if (d->m_UseIR) + { + amplitudes[i] = IRPixelData[i]; + } + else + { + rgb[i*3] = rgbPixelArray[i].nRed; + rgb[i*3+1] = rgbPixelArray[i].nGreen; + rgb[i*3+2] = rgbPixelArray[i].nBlue; + } + } + } + + void KinectController::GetAmplitudes( float* amplitudes ) + { + if (d->m_UseIR) + { + xn::IRMetaData IRData; + d->m_IRGenerator.GetMetaData(IRData); + const XnIRPixel* IRPixelData = IRData.Data(); + + for (unsigned int i=0; im_CaptureWidth*d->m_CaptureHeight; i++) + { + amplitudes[i] = IRPixelData[i]; + } + } + } + + void KinectController::GetIntensities( float* intensities ) + { + + } + unsigned int KinectController::GetCaptureWidth() const + { + return d->m_CaptureWidth; + } + + unsigned int KinectController::GetCaptureHeight() const + { + return d->m_CaptureHeight; + } + + bool KinectController::GetUseIR() const + { + return d->m_UseIR; + } + void KinectController::SetUseIR(bool useIR) + { + if (d->m_UseIR!=useIR) + { + d->m_UseIR = useIR; + this->Modified(); + } + } +} diff --git a/Modules/ToFHardware/mitkKinectController.h b/Modules/ToFHardware/mitkKinectController.h new file mode 100644 index 0000000000..8f9745f98f --- /dev/null +++ b/Modules/ToFHardware/mitkKinectController.h @@ -0,0 +1,93 @@ +/*========================================================================= + +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 __mitkKinectController_h +#define __mitkKinectController_h + +#include "mitkToFHardwareExports.h" +#include "mitkCommon.h" +#include "mitkToFConfig.h" + +#include "itkObject.h" +#include "itkObjectFactory.h" + +namespace mitk +{ + /** + * @brief Interface to the Kinect camera + * + * + * @ingroup ToFHardware + */ + class MITK_TOFHARDWARE_EXPORT KinectController : public itk::Object + { + public: + + mitkClassMacro( KinectController , itk::Object ); + + itkNewMacro( Self ); + + unsigned int GetCaptureWidth() const; + unsigned int GetCaptureHeight() const; + bool GetUseIR() const; + + void SetUseIR(bool useIR); + + /*! + \brief opens a connection to the Kinect camera. + */ + virtual bool OpenCameraConnection(); + /*! + \brief closes the connection to the camera + */ + virtual bool CloseCameraConnection(); + /*! + \brief updates the camera. The update function of the hardware interface is called only when new data is available + */ + virtual bool UpdateCamera(); + /*! + \brief acquire new distance data from the Kinect camera + \param distances pointer to memory location where distances should be stored + */ + void GetDistances(float* distances); + void GetAmplitudes(float* amplitudes); + void GetIntensities(float* intensities); + /*! + \brief acquire new rgb data from the Kinect camera + \parama rgb pointer to memory location where rgb information should be stored + */ + void GetRgb(unsigned char* rgb); + /*! + \brief convenience method for faster access to distance and rgb data + \param distances pointer to memory location where distances should be stored + \param rgb pointer to memory location where rgb information should be stored + */ + void GetAllData(float* distances, float* amplitudes, unsigned char* rgb); + + protected: + + KinectController(); + + ~KinectController(); + + private: + class KinectControllerPrivate; + KinectControllerPrivate *d; + + }; +} //END mitk namespace +#endif diff --git a/Modules/ToFHardware/mitkKinectControllerStub.cpp b/Modules/ToFHardware/mitkKinectControllerStub.cpp new file mode 100644 index 0000000000..4ab8bc8266 --- /dev/null +++ b/Modules/ToFHardware/mitkKinectControllerStub.cpp @@ -0,0 +1,81 @@ +/*========================================================================= + +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 "mitkKinectController.h" + +namespace mitk +{ + KinectController::KinectController() + { + MITK_WARN("ToF") << "Error: Kinect camera currently not available"; + } + + KinectController::~KinectController() + { + MITK_WARN("ToF") << "Error: Kinect camera currently not available"; + } + + bool KinectController::OpenCameraConnection() + { + MITK_WARN("ToF") << "Error: Kinect camera currently not available"; + return true; + } + + bool KinectController::CloseCameraConnection() + { + MITK_WARN("ToF") << "Error: Kinect camera currently not available"; + return true; + } + + bool KinectController::UpdateCamera() + { + MITK_WARN("ToF") << "Error: Kinect camera currently not available"; + return true; + } + + // TODO flag image + void KinectController::GetDistances(float* distances) + { + MITK_WARN("ToF") << "Error: Kinect camera currently not available"; + } + + void KinectController::GetRgb(unsigned char* rgb) + { + MITK_WARN("ToF") << "Error: Kinect camera currently not available"; + } + + void KinectController::GetAllData(float* distances, float* amplitudes, unsigned char* rgb) + { + MITK_WARN("ToF") << "Error: Kinect camera currently not available"; + } + + bool KinectController::ErrorText(unsigned int error) + { + MITK_WARN("ToF") << "Error: Kinect camera currently not available"; + return true; + } + + void KinectController::GetAmplitudes( float* amplitudes ) + { + MITK_WARN("ToF") << "Error: Kinect camera currently not available"; + } + + void KinectController::GetIntensities( float* intensities ) + { + MITK_WARN("ToF") << "Error: Kinect camera currently not available"; + } +} diff --git a/Modules/ToFHardware/mitkToFCameraMESADevice.cpp b/Modules/ToFHardware/mitkKinectDevice.cpp similarity index 69% copy from Modules/ToFHardware/mitkToFCameraMESADevice.cpp copy to Modules/ToFHardware/mitkKinectDevice.cpp index 7ba8527722..2c86bce71c 100644 --- a/Modules/ToFHardware/mitkToFCameraMESADevice.cpp +++ b/Modules/ToFHardware/mitkKinectDevice.cpp @@ -1,446 +1,427 @@ -/*=================================================================== +/*========================================================================= -The Medical Imaging Interaction Toolkit (MITK) +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. +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. +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. -See LICENSE.txt or http://www.mitk.org for details. - -===================================================================*/ -#include "mitkToFCameraMESADevice.h" +=========================================================================*/ +#include "mitkKinectDevice.h" #include "mitkRealTimeClock.h" #include "itkMultiThreader.h" #include namespace mitk { - ToFCameraMESADevice::ToFCameraMESADevice() + KinectDevice::KinectDevice() { + m_Controller = mitk::KinectController::New(); } - ToFCameraMESADevice::~ToFCameraMESADevice() + KinectDevice::~KinectDevice() { } - bool ToFCameraMESADevice::ConnectCamera() + bool KinectDevice::ConnectCamera() { bool ok = false; if (m_Controller) { ok = m_Controller->OpenCameraConnection(); + MITK_INFO<<"Device ok? "<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]; } + this->m_RGBDataBuffer = new unsigned char*[this->m_MaxBufferSize]; + for (int i=0; im_MaxBufferSize; i++) + { + this->m_RGBDataBuffer[i] = new unsigned char[this->m_PixelNumber*3]; + } m_CameraConnected = true; } } return ok; } - bool ToFCameraMESADevice::DisconnectCamera() + bool KinectDevice::DisconnectCamera() { bool ok = false; if (m_Controller) { ok = m_Controller->CloseCameraConnection(); // clean-up only if camera was connected if (m_CameraConnected) { 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_RGBDataBuffer[i]; } + delete[] this->m_DistanceDataBuffer; + delete[] this->m_AmplitudeDataBuffer; delete[] this->m_IntensityDataBuffer; + delete[] this->m_RGBDataBuffer; m_CameraConnected = false; } } return ok; } - void ToFCameraMESADevice::StartCamera() + void KinectDevice::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_Controller->GetAllData(this->m_DistanceDataBuffer[this->m_FreePos],this->m_AmplitudeDataBuffer[this->m_FreePos],this->m_RGBDataBuffer[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 ToFCameraMESADevice::StopCamera() + void KinectDevice::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 ToFCameraMESADevice::IsCameraActive() + bool KinectDevice::IsCameraActive() { m_CameraActiveMutex->Lock(); bool ok = m_CameraActive; m_CameraActiveMutex->Unlock(); return ok; } - void ToFCameraMESADevice::UpdateCamera() + void KinectDevice::UpdateCamera() { if (m_Controller) { m_Controller->UpdateCamera(); } } - ITK_THREAD_RETURN_TYPE ToFCameraMESADevice::Acquire(void* pInfoStruct) + ITK_THREAD_RETURN_TYPE KinectDevice::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; } - ToFCameraMESADevice* toFCameraDevice = (ToFCameraMESADevice*)pInfo->UserData; + KinectDevice* toFCameraDevice = (KinectDevice*)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 image data from the camera and write it at the next free position in the buffer toFCameraDevice->m_ImageMutex->Lock(); - 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->m_Controller->GetAllData(toFCameraDevice->m_DistanceDataBuffer[toFCameraDevice->m_FreePos],toFCameraDevice->m_AmplitudeDataBuffer[toFCameraDevice->m_FreePos],toFCameraDevice->m_RGBDataBuffer[toFCameraDevice->m_FreePos]); toFCameraDevice->m_ImageMutex->Unlock(); // call modified to indicate that cameraDevice was modified toFCameraDevice->Modified(); /*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - TODO Buffer Handling currently only works for buffer size 1 - !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/ + TODO Buffer Handling currently only works for buffer size 1 + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/ //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; } if (overflow) { //itksys::SystemTools::Delay(10); overflow = false; } /*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - END TODO Buffer Handling currently only works for buffer size 1 - !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/ + 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 ToFCameraMESADevice::ResetBuffer(int bufferSize) + // void KinectDevice::ResetBuffer(int bufferSize) // { // this->m_BufferSize = bufferSize; // this->m_CurrentPos = -1; // this->m_FreePos = 0; // } - void ToFCameraMESADevice::GetAmplitudes(float* amplitudeArray, int& imageSequence) + void KinectDevice::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]; - } + for (int j=0; jm_CaptureWidth; j++) + { + amplitudeArray[i*this->m_CaptureWidth+j] = this->m_AmplitudeArray[(i+1)*this->m_CaptureWidth-1-j]; + } } */ for (int i=0; im_PixelNumber; i++) { amplitudeArray[i] = this->m_AmplitudeDataBuffer[this->m_CurrentPos][i]; } imageSequence = this->m_ImageSequence; } else { MITK_WARN("ToF") << "Warning: Data can only be acquired if camera is active."; } m_ImageMutex->Unlock(); } - void ToFCameraMESADevice::GetIntensities(float* intensityArray, int& imageSequence) + void KinectDevice::GetIntensities(float* intensityArray, int& imageSequence) { m_ImageMutex->Lock(); if (m_CameraActive) { - // 1) copy the image buffer - // 2) Flip around y- axis (vertical axis) + // 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++) - { + /* + 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]; + intensityArray[i*this->m_CaptureWidth+j] = this->m_IntensityArray[(i+1)*this->m_CaptureWidth-1-j]; } - } - */ + } + */ for (int i=0; im_PixelNumber; i++) { intensityArray[i] = this->m_IntensityDataBuffer[this->m_CurrentPos][i]; } imageSequence = this->m_ImageSequence; } else { MITK_WARN("ToF") << "Warning: Data can only be acquired if camera is active."; } m_ImageMutex->Unlock(); } - void ToFCameraMESADevice::GetDistances(float* distanceArray, int& imageSequence) + void KinectDevice::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]; - } + for (int j=0; jm_CaptureWidth; j++) + { + distanceArray[i*this->m_CaptureWidth+j] = 1000 * this->m_DistanceArray[(i+1)*this->m_CaptureWidth-1-j]; + } } */ for (int i=0; im_PixelNumber; i++) { distanceArray[i] = this->m_DistanceDataBuffer[this->m_CurrentPos][i]; // * 1000 } imageSequence = this->m_ImageSequence; } else { MITK_WARN("ToF") << "Warning: Data can only be acquired if camera is active."; } m_ImageMutex->Unlock(); } - void ToFCameraMESADevice::GetAllImages(float* distanceArray, float* amplitudeArray, float* intensityArray, char* sourceDataArray, - int requiredImageSequence, int& capturedImageSequence) + void KinectDevice::GetAllImages(float* distanceArray, float* amplitudeArray, float* intensityArray, char* sourceDataArray, + int requiredImageSequence, int& capturedImageSequence, unsigned char* rgbDataArray) { if (m_CameraActive) { // 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; 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; } // write image data to float arrays for (int i=0; im_PixelNumber; i++) { - distanceArray[i] = this->m_DistanceDataBuffer[pos][i] /* * 1000 */; + distanceArray[i] = this->m_DistanceDataBuffer[pos][i]; amplitudeArray[i] = this->m_AmplitudeDataBuffer[pos][i]; intensityArray[i] = this->m_IntensityDataBuffer[pos][i]; + rgbDataArray[i*3] = this->m_RGBDataBuffer[pos][i*3]; + rgbDataArray[i*3+1] = this->m_RGBDataBuffer[pos][i*3+1]; + rgbDataArray[i*3+2] = this->m_RGBDataBuffer[pos][i*3+2]; } - - - /* - 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 mm - //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."; } } - ToFCameraMESAController::Pointer ToFCameraMESADevice::GetController() + KinectController::Pointer KinectDevice::GetController() { return this->m_Controller; } - void ToFCameraMESADevice::SetProperty( const char *propertyKey, BaseProperty* propertyValue ) + void KinectDevice::SetProperty( const char *propertyKey, BaseProperty* propertyValue ) { ToFCameraDevice::SetProperty(propertyKey,propertyValue); this->m_PropertyList->SetProperty(propertyKey, propertyValue); - if (strcmp(propertyKey, "ModulationFrequency") == 0) + if (strcmp(propertyKey, "RGB") == 0) { - int modulationFrequency = 0; - GetIntProperty(propertyValue, modulationFrequency); - m_Controller->SetModulationFrequency(modulationFrequency); + bool rgb = false; + GetBoolProperty(propertyKey, rgb); + m_Controller->SetUseIR(!rgb); } - else if (strcmp(propertyKey, "IntegrationTime") == 0) + else if (strcmp(propertyKey, "IR") == 0) { - int integrationTime = 0; - GetIntProperty(propertyValue, integrationTime); - m_Controller->SetIntegrationTime(integrationTime); + bool ir = false; + GetBoolProperty(propertyKey, ir); + m_Controller->SetUseIR(ir); } } } diff --git a/Modules/ToFHardware/mitkToFCameraMESADevice.h b/Modules/ToFHardware/mitkKinectDevice.h similarity index 73% copy from Modules/ToFHardware/mitkToFCameraMESADevice.h copy to Modules/ToFHardware/mitkKinectDevice.h index 2f48778903..3a3276ab09 100644 --- a/Modules/ToFHardware/mitkToFCameraMESADevice.h +++ b/Modules/ToFHardware/mitkKinectDevice.h @@ -1,146 +1,149 @@ -/*=================================================================== +/*========================================================================= -The Medical Imaging Interaction Toolkit (MITK) +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. +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. +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. -See LICENSE.txt or http://www.mitk.org for details. - -===================================================================*/ -#ifndef __mitkToFCameraMESADevice_h -#define __mitkToFCameraMESADevice_h +=========================================================================*/ +#ifndef __mitkKinectDevice_h +#define __mitkKinectDevice_h #include "mitkToFHardwareExports.h" #include "mitkCommon.h" #include "mitkToFCameraDevice.h" -#include "mitkToFCameraMESAController.h" +#include "mitkKinectController.h" #include "itkObject.h" #include "itkObjectFactory.h" #include "itkMultiThreader.h" #include "itkFastMutexLock.h" namespace mitk { /** * @brief Interface for all representations of MESA ToF devices. - * ToFCameraMESADevice internally holds an instance of ToFCameraMESAController and starts a thread + * KinectDevice internally holds an instance of KinectController 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 ToFCameraMESADevice : public ToFCameraDevice + class MITK_TOFHARDWARE_EXPORT KinectDevice : public ToFCameraDevice { public: - mitkClassMacro( ToFCameraMESADevice , ToFCameraDevice ); + mitkClassMacro( KinectDevice , 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; + int requiredImageSequence, int& capturedImageSequence, unsigned char* rgbDataArray=NULL); + // 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 */ - ToFCameraMESAController::Pointer GetController(); + KinectController::Pointer GetController(); /*! \brief set a BaseProperty */ virtual void SetProperty( const char *propertyKey, BaseProperty* propertyValue ); protected: - ToFCameraMESADevice(); + KinectDevice(); - ~ToFCameraMESADevice(); + ~KinectDevice(); /*! \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(); - ToFCameraMESAController::Pointer m_Controller; ///< corresponding CameraController + KinectController::Pointer m_Controller; ///< corresponding CameraController 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 + unsigned char** m_RGBDataBuffer; ///< buffer holding the last RGB image private: }; } //END mitk namespace #endif diff --git a/Modules/ToFHardware/mitkToFCameraDevice.cpp b/Modules/ToFHardware/mitkToFCameraDevice.cpp index 4c8ed4de92..c8f30aa753 100644 --- a/Modules/ToFHardware/mitkToFCameraDevice.cpp +++ b/Modules/ToFHardware/mitkToFCameraDevice.cpp @@ -1,135 +1,134 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "mitkToFCameraDevice.h" namespace mitk { ToFCameraDevice::ToFCameraDevice():m_BufferSize(1),m_MaxBufferSize(100),m_CurrentPos(-1),m_FreePos(0), m_CaptureWidth(204),m_CaptureHeight(204),m_PixelNumber(41616),m_SourceDataSize(0), m_ThreadID(0),m_CameraActive(false),m_CameraConnected(false),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) + bool ToFCameraDevice::GetBoolProperty(const char *propertyKey, bool& boolValue) { - mitk::BoolProperty::Pointer boolprop = dynamic_cast(propertyValue); + mitk::BoolProperty::Pointer boolprop = dynamic_cast(this->GetProperty(propertyKey)); if(boolprop.IsNull()) return false; boolValue = boolprop->GetValue(); return true; } - bool ToFCameraDevice::GetStringProperty(BaseProperty* propertyValue, std::string& string) + bool ToFCameraDevice::GetStringProperty(const char *propertyKey, std::string& string) { - mitk::StringProperty::Pointer stringProp = dynamic_cast(propertyValue); + mitk::StringProperty::Pointer stringProp = dynamic_cast(this->GetProperty(propertyKey)); if(stringProp.IsNull()) { return false; } else { string = stringProp->GetValue(); return true; } } - bool ToFCameraDevice::GetIntProperty(BaseProperty* propertyValue, int& integer) + bool ToFCameraDevice::GetIntProperty(const char *propertyKey, int& integer) { - mitk::IntProperty::Pointer intProp = dynamic_cast(propertyValue); + mitk::IntProperty::Pointer intProp = dynamic_cast(this->GetProperty(propertyKey)); 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 115b237c92..13ccdc7160 100644 --- a/Modules/ToFHardware/mitkToFCameraDevice.h +++ b/Modules/ToFHardware/mitkToFCameraDevice.h @@ -1,215 +1,215 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #ifndef __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; + virtual void GetAllImages(float* distanceArray, float* amplitudeArray, float* intensityArray, char* sourceDataArray, + int requiredImageSequence, int& capturedImageSequence, unsigned char* rgbDataArray=NULL) = 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); + bool GetBoolProperty(const char *propertyKey, bool& boolValue); /*! \brief get a string from the property list */ - static bool GetStringProperty(BaseProperty* propertyValue, std::string& string); + bool GetStringProperty(const char *propertyKey, std::string& string); /*! \brief get an int from the property list */ - static bool GetIntProperty(BaseProperty* propertyValue, int& integer); + bool GetIntProperty(const char *propertyKey, 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/mitkToFCameraMESADevice.cpp b/Modules/ToFHardware/mitkToFCameraMESADevice.cpp index 7ba8527722..6d7f87bbac 100644 --- a/Modules/ToFHardware/mitkToFCameraMESADevice.cpp +++ b/Modules/ToFHardware/mitkToFCameraMESADevice.cpp @@ -1,446 +1,446 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "mitkToFCameraMESADevice.h" #include "mitkRealTimeClock.h" #include "itkMultiThreader.h" #include namespace mitk { ToFCameraMESADevice::ToFCameraMESADevice() { } ToFCameraMESADevice::~ToFCameraMESADevice() { } bool ToFCameraMESADevice::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_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]; } m_CameraConnected = true; } } return ok; } bool ToFCameraMESADevice::DisconnectCamera() { bool ok = false; if (m_Controller) { ok = m_Controller->CloseCameraConnection(); // clean-up only if camera was connected if (m_CameraConnected) { 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 ToFCameraMESADevice::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 ToFCameraMESADevice::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 ToFCameraMESADevice::IsCameraActive() { m_CameraActiveMutex->Lock(); bool ok = m_CameraActive; m_CameraActiveMutex->Unlock(); return ok; } void ToFCameraMESADevice::UpdateCamera() { if (m_Controller) { m_Controller->UpdateCamera(); } } ITK_THREAD_RETURN_TYPE ToFCameraMESADevice::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; } ToFCameraMESADevice* toFCameraDevice = (ToFCameraMESADevice*)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 image data from the camera and write it at the next free position in the buffer toFCameraDevice->m_ImageMutex->Lock(); 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->m_ImageMutex->Unlock(); // call modified to indicate that cameraDevice was modified toFCameraDevice->Modified(); /*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! TODO Buffer Handling currently only works for buffer size 1 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/ //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; } 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 ToFCameraMESADevice::ResetBuffer(int bufferSize) // { // this->m_BufferSize = bufferSize; // this->m_CurrentPos = -1; // this->m_FreePos = 0; // } void ToFCameraMESADevice::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]; } } */ for (int i=0; im_PixelNumber; i++) { amplitudeArray[i] = this->m_AmplitudeDataBuffer[this->m_CurrentPos][i]; } imageSequence = this->m_ImageSequence; } else { MITK_WARN("ToF") << "Warning: Data can only be acquired if camera is active."; } m_ImageMutex->Unlock(); } void ToFCameraMESADevice::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]; } } */ for (int i=0; im_PixelNumber; i++) { intensityArray[i] = this->m_IntensityDataBuffer[this->m_CurrentPos][i]; } imageSequence = this->m_ImageSequence; } else { MITK_WARN("ToF") << "Warning: Data can only be acquired if camera is active."; } m_ImageMutex->Unlock(); } void ToFCameraMESADevice::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]; } } */ for (int i=0; im_PixelNumber; i++) { distanceArray[i] = this->m_DistanceDataBuffer[this->m_CurrentPos][i]; // * 1000 } imageSequence = this->m_ImageSequence; } else { MITK_WARN("ToF") << "Warning: Data can only be acquired if camera is active."; } m_ImageMutex->Unlock(); } void ToFCameraMESADevice::GetAllImages(float* distanceArray, float* amplitudeArray, float* intensityArray, char* sourceDataArray, - int requiredImageSequence, int& capturedImageSequence) + int requiredImageSequence, int& capturedImageSequence, unsigned char* rgbDataArray) { if (m_CameraActive) { // 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; 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; } // write image data to float arrays for (int i=0; im_PixelNumber; i++) { distanceArray[i] = this->m_DistanceDataBuffer[pos][i] /* * 1000 */; amplitudeArray[i] = this->m_AmplitudeDataBuffer[pos][i]; intensityArray[i] = this->m_IntensityDataBuffer[pos][i]; } /* 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 mm //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."; } } ToFCameraMESAController::Pointer ToFCameraMESADevice::GetController() { return this->m_Controller; } void ToFCameraMESADevice::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); + GetIntProperty(propertyKey, modulationFrequency); m_Controller->SetModulationFrequency(modulationFrequency); } else if (strcmp(propertyKey, "IntegrationTime") == 0) { int integrationTime = 0; - GetIntProperty(propertyValue, integrationTime); + GetIntProperty(propertyKey, integrationTime); m_Controller->SetIntegrationTime(integrationTime); } } } diff --git a/Modules/ToFHardware/mitkToFCameraMESADevice.h b/Modules/ToFHardware/mitkToFCameraMESADevice.h index 2f48778903..7a85b18717 100644 --- a/Modules/ToFHardware/mitkToFCameraMESADevice.h +++ b/Modules/ToFHardware/mitkToFCameraMESADevice.h @@ -1,146 +1,146 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #ifndef __mitkToFCameraMESADevice_h #define __mitkToFCameraMESADevice_h #include "mitkToFHardwareExports.h" #include "mitkCommon.h" #include "mitkToFCameraDevice.h" #include "mitkToFCameraMESAController.h" #include "itkObject.h" #include "itkObjectFactory.h" #include "itkMultiThreader.h" #include "itkFastMutexLock.h" namespace mitk { /** * @brief Interface for all representations of MESA ToF devices. * ToFCameraMESADevice internally holds an instance of ToFCameraMESAController 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 ToFCameraMESADevice : public ToFCameraDevice { public: mitkClassMacro( ToFCameraMESADevice , 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); + int requiredImageSequence, int& capturedImageSequence, unsigned char* rgbDataArray=NULL); // 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 */ ToFCameraMESAController::Pointer GetController(); /*! \brief set a BaseProperty */ virtual void SetProperty( const char *propertyKey, BaseProperty* propertyValue ); protected: ToFCameraMESADevice(); ~ToFCameraMESADevice(); /*! \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(); ToFCameraMESAController::Pointer m_Controller; ///< corresponding CameraController 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 private: }; } //END mitk namespace #endif diff --git a/Modules/ToFHardware/mitkToFCameraMESASR4000Device.cpp b/Modules/ToFHardware/mitkToFCameraMESASR4000Device.cpp index d02587ddc3..60ffbeab5d 100644 --- a/Modules/ToFHardware/mitkToFCameraMESASR4000Device.cpp +++ b/Modules/ToFHardware/mitkToFCameraMESASR4000Device.cpp @@ -1,69 +1,69 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "mitkToFCameraMESASR4000Device.h" #include "mitkToFCameraMESASR4000Controller.h" #include "mitkRealTimeClock.h" #include "itkMultiThreader.h" namespace mitk { ToFCameraMESASR4000Device::ToFCameraMESASR4000Device() { m_Controller = ToFCameraMESASR4000Controller::New(); } ToFCameraMESASR4000Device::~ToFCameraMESASR4000Device() { } void ToFCameraMESASR4000Device::SetRegionOfInterest(unsigned int leftUpperCornerX, unsigned int leftUpperCornerY, unsigned int width, unsigned int height) { //if (m_Controller.IsNotNull()) //{ // dynamic_cast(m_Controller.GetPointer())->SetRegionOfInterest(leftUpperCornerX,leftUpperCornerY,width,height); //} } void ToFCameraMESASR4000Device::SetProperty( const char *propertyKey, BaseProperty* propertyValue ) { ToFCameraMESADevice::SetProperty(propertyKey,propertyValue); this->m_PropertyList->SetProperty(propertyKey, propertyValue); ToFCameraMESASR4000Controller::Pointer myController = dynamic_cast(this->m_Controller.GetPointer()); bool boolValue = false; - GetBoolProperty(propertyValue, boolValue); + GetBoolProperty(propertyKey, boolValue); if (strcmp(propertyKey, "SetFPN") == 0) { myController->SetFPN(boolValue); } else if (strcmp(propertyKey, "SetConvGray") == 0) { myController->SetConvGray(boolValue); } else if (strcmp(propertyKey, "SetMedian") == 0) { myController->SetMedian(boolValue); } else if (strcmp(propertyKey, "SetANF") == 0) { myController->SetANF(boolValue); } } } diff --git a/Modules/ToFHardware/mitkToFCameraMITKPlayerController.cpp b/Modules/ToFHardware/mitkToFCameraMITKPlayerController.cpp index 26dfa8fb73..0046700601 100644 --- a/Modules/ToFHardware/mitkToFCameraMITKPlayerController.cpp +++ b/Modules/ToFHardware/mitkToFCameraMITKPlayerController.cpp @@ -1,344 +1,396 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include #include // mitk includes #include "mitkItkImageFileReader.h" #include "mitkPicFileReader.h" #include namespace mitk { ToFCameraMITKPlayerController::ToFCameraMITKPlayerController() : m_PixelNumber(0), m_NumberOfBytes(0), m_CaptureWidth(0), m_CaptureHeight(0), m_ConnectionCheck(false), m_InputFileName(""), m_Extension(""), m_ToFImageType(ToFImageType3D), m_DistanceImage(0), m_AmplitudeImage(0), m_IntensityImage(0), + m_RGBImage(0), m_DistanceInfile(NULL), m_AmplitudeInfile(NULL), m_IntensityInfile(NULL), + m_RGBInfile(NULL), m_IntensityArray(NULL), m_DistanceArray(NULL), m_AmplitudeArray(NULL), + m_RGBArray(NULL), m_DistanceImageFileName(""), m_AmplitudeImageFileName(""), m_IntensityImageFileName(""), + m_RGBImageFileName(""), m_PixelStartInFile(0), m_CurrentFrame(-1), m_NumOfFrames(0) { - m_ImageStatus = std::vector(3,true); + m_ImageStatus = std::vector(4,true); } ToFCameraMITKPlayerController::~ToFCameraMITKPlayerController() { this->CleanUp(); } void ToFCameraMITKPlayerController::CleanUp() { if(m_DistanceImage.IsNotNull()) { m_DistanceImage->ReleaseData(); m_DistanceImage = NULL; } if(m_AmplitudeImage.IsNotNull()) { m_AmplitudeImage->ReleaseData(); m_AmplitudeImage = NULL; } if(m_IntensityImage.IsNotNull()) { m_IntensityImage->ReleaseData(); m_IntensityImage = NULL; } + if(m_RGBImage.IsNotNull()) + { + m_RGBImage->ReleaseData(); + m_RGBImage = NULL; + } delete[] this->m_DistanceArray; this->m_DistanceArray = NULL; delete[] this->m_AmplitudeArray; this->m_AmplitudeArray = NULL; delete[] this->m_IntensityArray; this->m_IntensityArray = NULL; + delete[] this->m_RGBArray; + this->m_RGBArray = NULL; } bool ToFCameraMITKPlayerController::CheckCurrentFileType() { if(!this->m_DistanceImageFileName.empty()) { if(ItkImageFileReader::CanReadFile(m_DistanceImageFileName,"",".nrrd")) { m_Extension = ".nrrd"; return true; } else if (PicFileReader::CanReadFile(m_DistanceImageFileName,"",".pic")) { m_Extension = ".pic"; return true; } } if(!this->m_AmplitudeImageFileName.empty()) { if(ItkImageFileReader::CanReadFile(m_AmplitudeImageFileName,"",".nrrd")) { m_Extension = ".nrrd"; return true; } else if (PicFileReader::CanReadFile(m_AmplitudeImageFileName,"",".pic")) { m_Extension = ".pic"; return true; } } if(!this->m_IntensityImageFileName.empty()) { if(ItkImageFileReader::CanReadFile(m_IntensityImageFileName,"",".nrrd")) { m_Extension = ".nrrd"; return true; } else if (PicFileReader::CanReadFile(m_IntensityImageFileName,"",".pic")) { m_Extension = ".pic"; return true; } } + if(!this->m_RGBImageFileName.empty()) + { + if(ItkImageFileReader::CanReadFile(m_RGBImageFileName,"",".nrrd")) + { + m_Extension = ".nrrd"; + return true; + } + else if (PicFileReader::CanReadFile(m_RGBImageFileName,"",".pic")) + { + m_Extension = ".pic"; + return true; + } + } return false; } bool ToFCameraMITKPlayerController::OpenCameraConnection() { if(!this->m_ConnectionCheck) { try { // Check for file type, only .nrrd and .pic files are supported! if( this->CheckCurrentFileType()) { if(m_Extension == ".nrrd") { this->OpenNrrdImageFile(this->m_DistanceImageFileName, m_DistanceImage); this->OpenNrrdImageFile(this->m_AmplitudeImageFileName, m_AmplitudeImage); this->OpenNrrdImageFile(this->m_IntensityImageFileName, m_IntensityImage); + this->OpenNrrdImageFile(this->m_RGBImageFileName, m_RGBImage); } else if(m_Extension == ".pic") { this->OpenPicImageFile(this->m_DistanceImageFileName, m_DistanceImage); this->OpenPicImageFile(this->m_AmplitudeImageFileName, m_AmplitudeImage); this->OpenPicImageFile(this->m_IntensityImageFileName, m_IntensityImage); + this->OpenPicImageFile(this->m_RGBImageFileName, m_RGBImage); } } else { throw std::logic_error("Please check image type, currently only .nrrd files are supported (.pic files are deprecated!)"); } // check if the opened files contained data if(m_DistanceImage.IsNull()) { m_ImageStatus.at(0) = false; } if(m_AmplitudeImage.IsNull()) { m_ImageStatus.at(1) = false; } if(m_IntensityImage.IsNull()) { m_ImageStatus.at(2) = false; } - + if(m_RGBImage.IsNull()) + { + m_ImageStatus.at(3) = false; + } + // Check for dimension type mitk::Image::Pointer infoImage = NULL; if(m_ImageStatus.at(0)) { infoImage = m_DistanceImage; } else if (m_ImageStatus.at(1)) { infoImage = m_AmplitudeImage; } else if(m_ImageStatus.at(2)) { infoImage = m_IntensityImage; } + else if(m_ImageStatus.at(3)) + { + infoImage = m_RGBImage; + } if (infoImage->GetDimension() == 2) this->m_ToFImageType = ToFImageType2DPlusT; else if (infoImage->GetDimension() == 3) this->m_ToFImageType = ToFImageType3D; else if (infoImage->GetDimension() == 4) this->m_ToFImageType = ToFImageType2DPlusT; else throw std::logic_error("Error opening ToF data file: Invalid dimension."); this->m_CaptureWidth = infoImage->GetDimension(0); this->m_CaptureHeight = infoImage->GetDimension(1); this->m_PixelNumber = this->m_CaptureWidth*this->m_CaptureHeight; this->m_NumberOfBytes = this->m_PixelNumber * sizeof(float); if (this->m_ToFImageType == ToFImageType2DPlusT) { this->m_NumOfFrames = infoImage->GetDimension(3); } else { this->m_NumOfFrames = infoImage->GetDimension(2); } // allocate buffer 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_IntensityArray = new float[this->m_PixelNumber]; for(int i=0; im_PixelNumber; i++) {this->m_IntensityArray[i]=0.0;} + this->m_RGBArray = new unsigned char[this->m_PixelNumber*3]; + for(int i=0; im_PixelNumber*3; i++) {this->m_RGBArray[i]=0.0;} MITK_INFO << "NumOfFrames: " << this->m_NumOfFrames; this->m_ConnectionCheck = true; return this->m_ConnectionCheck; } catch(std::exception& e) { MITK_ERROR << "Error opening ToF data file " << this->m_InputFileName << " " << e.what(); throw std::logic_error("Error opening ToF data file"); return false; } } else return this->m_ConnectionCheck; } void ToFCameraMITKPlayerController::OpenNrrdImageFile( const std::string outfileName, Image::Pointer &image) { if(!outfileName.empty()) { if(image.IsNotNull()) { image->ReleaseData(); image = NULL; } ItkImageFileReader::Pointer nrrdReader = ItkImageFileReader::New(); nrrdReader->SetFileName(outfileName); nrrdReader->Update(); image = nrrdReader->GetOutput()->Clone(); } else { MITK_ERROR << "Error opening ToF data file " << outfileName; } } void ToFCameraMITKPlayerController::OpenPicImageFile( const std::string outfileName, Image::Pointer &image) { if(!outfileName.empty()) { if(image.IsNotNull()) { image->ReleaseData(); image = NULL; } PicFileReader::Pointer picReader = PicFileReader::New(); picReader->SetFileName(outfileName); picReader->Update(); image = picReader->GetOutput()->Clone(); } else { MITK_ERROR << "Error opening ToF data file " << outfileName; } } bool ToFCameraMITKPlayerController::CloseCameraConnection() { if (this->m_ConnectionCheck) { this->CleanUp(); this->m_ConnectionCheck = false; return true; } return false; } void ToFCameraMITKPlayerController::UpdateCamera() { this->m_CurrentFrame++; if(this->m_CurrentFrame >= this->m_NumOfFrames) { this->m_CurrentFrame = 0; } if(this->m_ImageStatus.at(0)) { this->AccessData(this->m_CurrentFrame, this->m_DistanceImage, this->m_DistanceArray); } if(this->m_ImageStatus.at(1)) { this->AccessData(this->m_CurrentFrame, this->m_AmplitudeImage, this->m_AmplitudeArray); } if(this->m_ImageStatus.at(2)) { this->AccessData(this->m_CurrentFrame, this->m_IntensityImage, this->m_IntensityArray); } + if(this->m_ImageStatus.at(3)) + { + if(!this->m_ToFImageType) + { + memcpy(m_RGBArray, m_RGBImage->GetSliceData(m_CurrentFrame)->GetData(),m_PixelNumber * sizeof(unsigned char)*3 ); + } + else if(this->m_ToFImageType) + { + memcpy(m_RGBArray, m_RGBImage->GetVolumeData(m_CurrentFrame)->GetData(), m_PixelNumber * sizeof(unsigned char)*3); + } + } itksys::SystemTools::Delay(50); } void ToFCameraMITKPlayerController::AccessData(int frame, Image::Pointer image, float* &data) { if(!this->m_ToFImageType) { memcpy(data, image->GetSliceData(frame)->GetData(),this->m_NumberOfBytes ); } else if(this->m_ToFImageType) { memcpy(data, image->GetVolumeData(frame)->GetData(), this->m_NumberOfBytes); } } void ToFCameraMITKPlayerController::GetAmplitudes(float* amplitudeArray) { memcpy(amplitudeArray, this->m_AmplitudeArray, this->m_NumberOfBytes); } void ToFCameraMITKPlayerController::GetIntensities(float* intensityArray) { memcpy(intensityArray, this->m_IntensityArray, this->m_NumberOfBytes); } void ToFCameraMITKPlayerController::GetDistances(float* distanceArray) { memcpy(distanceArray, this->m_DistanceArray, this->m_NumberOfBytes); } + void ToFCameraMITKPlayerController::GetRgb(unsigned char* rgbArray) + { + memcpy(rgbArray, this->m_RGBArray, m_PixelNumber * sizeof(unsigned char)*3); + } + void ToFCameraMITKPlayerController::SetInputFileName(std::string inputFileName) { this->m_InputFileName = inputFileName; } } diff --git a/Modules/ToFHardware/mitkToFCameraMITKPlayerController.h b/Modules/ToFHardware/mitkToFCameraMITKPlayerController.h index 78a577c77d..4fd8443f38 100644 --- a/Modules/ToFHardware/mitkToFCameraMITKPlayerController.h +++ b/Modules/ToFHardware/mitkToFCameraMITKPlayerController.h @@ -1,132 +1,142 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #ifndef __mitkToFCameraMITKPlayerController_h #define __mitkToFCameraMITKPlayerController_h #include "mitkToFHardwareExports.h" #include "mitkCommon.h" #include "mitkFileReader.h" #include "mitkImage.h" #include "itkObject.h" #include "itkObjectFactory.h" namespace mitk { /** * @brief Controller for playing ToF images saved in MITK (.pic) format * * @ingroup ToFHardware */ class MITK_TOFHARDWARE_EXPORT ToFCameraMITKPlayerController : public itk::Object { public: mitkClassMacro( ToFCameraMITKPlayerController , itk::Object ); itkNewMacro( Self ); /*! \brief opens a connection to the ToF camera \return Returns 'true' if connection could be established and 'false' otherwise */ virtual bool OpenCameraConnection(); /*! \brief closes the connection to the camera \return Returns 'true' if connection could be closed (i.e. only if a connection was established before) and 'false' otherwise */ virtual bool CloseCameraConnection(); /*! \brief gets the current amplitude frame from the input 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 */ virtual void GetAmplitudes(float* amplitudeArray); /*! \brief gets the current intensity frame from the input as a greyscale image */ virtual void GetIntensities(float* intensityArray); /*! \brief gets the current distance frame from the inpug measuring the distance between the camera and the different object points in millimeters */ virtual void GetDistances(float* distanceArray); /*! + \brief gets the current RGB frame from the input if available + */ + virtual void GetRgb(unsigned char* rgbArray); + /*! \brief updates the current image frames from input */ virtual void UpdateCamera(); virtual void SetInputFileName(std::string inputFileName); itkGetMacro(CaptureWidth, int); itkGetMacro(CaptureHeight, int); itkGetMacro( DistanceImageFileName, std::string ); itkGetMacro( AmplitudeImageFileName, std::string ); itkGetMacro( IntensityImageFileName, std::string ); + itkGetMacro( RGBImageFileName, std::string ); itkSetMacro( DistanceImageFileName, std::string ); itkSetMacro( AmplitudeImageFileName, std::string ); itkSetMacro( IntensityImageFileName, std::string ); + itkSetMacro( RGBImageFileName, std::string ); enum ToFImageType{ ToFImageType3D, ToFImageType2DPlusT }; protected: ToFCameraMITKPlayerController(); ~ToFCameraMITKPlayerController(); int m_PixelNumber; ///< holds the number of pixels contained in the image int m_NumberOfBytes; ///< holds the number of bytes contained in the image int m_CaptureWidth; ///< holds the width of the image int m_CaptureHeight; ///< holds the height of the image bool m_ConnectionCheck; ///< flag showing whether the camera is connected (true) or not (false) std::string m_InputFileName; std::string m_Extension; ToFImageType m_ToFImageType; ///< type of the ToF image to be played: 3D Volume (ToFImageType3D), temporal 2D image stack (ToFImageType2DPlusT) Image::Pointer m_DistanceImage; Image::Pointer m_AmplitudeImage; Image::Pointer m_IntensityImage; + Image::Pointer m_RGBImage; std::vector m_ImageStatus; FILE* m_DistanceInfile; ///< file holding the distance data FILE* m_AmplitudeInfile; ///< file holding the amplitude data FILE* m_IntensityInfile; ///< file holding the intensity data + FILE* m_RGBInfile; ///< file holding the rgb data float* m_IntensityArray; ///< member holding the current intensity frame float* m_DistanceArray; ///< member holding the current distance frame float* m_AmplitudeArray; ///< member holding the current amplitude frame + unsigned char* m_RGBArray; ///< member holding the current rgb frame std::string m_DistanceImageFileName; ///< file name of the distance image to be played std::string m_AmplitudeImageFileName; ///< file name of the amplitude image to be played std::string m_IntensityImageFileName; ///< file name of the intensity image to be played + std::string m_RGBImageFileName; ///< file name of the rgb image to be played long m_PixelStartInFile; int m_CurrentFrame; int m_NumOfFrames; private: //void OpenPicFileToData(FILE** outfile, const char *outfileName); void AccessData(int frame, Image::Pointer image, float* &data); bool CheckCurrentFileType(); void OpenNrrdImageFile( const std::string outfileName, Image::Pointer &image); void OpenPicImageFile( const std::string outfileName, Image::Pointer &image); void CleanUp(); }; } //END mitk namespace #endif diff --git a/Modules/ToFHardware/mitkToFCameraMITKPlayerDevice.cpp b/Modules/ToFHardware/mitkToFCameraMITKPlayerDevice.cpp index ed4ad55ba9..b8b77c3344 100644 --- a/Modules/ToFHardware/mitkToFCameraMITKPlayerDevice.cpp +++ b/Modules/ToFHardware/mitkToFCameraMITKPlayerDevice.cpp @@ -1,371 +1,410 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "mitkToFCameraMITKPlayerDevice.h" #include "mitkToFCameraMITKPlayerController.h" #include "mitkRealTimeClock.h" #include "itkMultiThreader.h" #include namespace mitk { ToFCameraMITKPlayerDevice::ToFCameraMITKPlayerDevice() : - m_DistanceDataBuffer(NULL), m_AmplitudeDataBuffer(NULL), m_IntensityDataBuffer(NULL) + m_DistanceDataBuffer(NULL), m_AmplitudeDataBuffer(NULL), m_IntensityDataBuffer(NULL), m_RGBDataBuffer(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; AllocatePixelArrays(); AllocateDataBuffers(); m_CameraConnected = true; } return ok; } bool ToFCameraMITKPlayerDevice::DisconnectCamera() { bool ok = m_Controller->CloseCameraConnection(); if (ok) { 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_Controller->GetRgb(this->m_RGBDataBuffer[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->m_Controller->GetRgb(toFCameraDevice->m_RGBDataBuffer[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::GetRgb(unsigned char* rgbArray, int& imageSequence) + { + m_ImageMutex->Lock(); + /*!!!!!!!!!!!!!!!!!!!!!! + TODO Buffer handling??? + !!!!!!!!!!!!!!!!!!!!!!!!*/ + // write intensity image data to unsigned char array + for (int i=0; im_PixelNumber*3; i++) + { + rgbArray[i] = this->m_RGBDataBuffer[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) + int requiredImageSequence, int& capturedImageSequence, unsigned char* rgbDataArray) { /*!!!!!!!!!!!!!!!!!!!!!! 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; } - if(this->m_DistanceDataBuffer&&this->m_AmplitudeDataBuffer&&this->m_IntensityDataBuffer) + if(this->m_DistanceDataBuffer&&this->m_AmplitudeDataBuffer&&this->m_IntensityDataBuffer&&this->m_RGBDataBuffer) { // 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]; + rgbDataArray[i] = this->m_RGBDataBuffer[pos][i]; + } + for (int j=this->m_PixelNumber; jm_PixelNumber*3; j++) + { + rgbDataArray[j] = this->m_RGBDataBuffer[pos][j]; } } 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); + GetStringProperty(propertyKey, 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); } + else if (strcmp(propertyKey, "RGBImageFileName") == 0) + { + myController->SetRGBImageFileName(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; } + if (m_RGBDataBuffer) + { + for(int i=0; im_MaxBufferSize; i++) + { + delete[] this->m_RGBDataBuffer[i]; + } + delete[] this->m_RGBDataBuffer; + } } 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]; } + this->m_RGBDataBuffer = new unsigned char*[this->m_MaxBufferSize]; + for(int i=0; im_MaxBufferSize; i++) + { + this->m_RGBDataBuffer[i] = new unsigned char[this->m_PixelNumber*3]; + } } } diff --git a/Modules/ToFHardware/mitkToFCameraMITKPlayerDevice.h b/Modules/ToFHardware/mitkToFCameraMITKPlayerDevice.h index 6645d52f71..b02392795c 100644 --- a/Modules/ToFHardware/mitkToFCameraMITKPlayerDevice.h +++ b/Modules/ToFHardware/mitkToFCameraMITKPlayerDevice.h @@ -1,147 +1,154 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #ifndef __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 rgb data from the ToF camera. Caution! The user is responsible for allocating and deleting the images. + \param rgbArray contains the returned rgb data as an array. + \param imageSequence the actually captured image sequence number + */ + virtual void GetRgb(unsigned char* rgbArray, 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); + int requiredImageSequence, int& capturedImageSequence, unsigned char* rgbDataArray=NULL); // 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 + unsigned char** m_RGBDataBuffer; ///< buffer holding the last rgb images }; } //END mitk namespace #endif diff --git a/Modules/ToFHardware/mitkToFCameraPMDCamBoardDevice.cpp b/Modules/ToFHardware/mitkToFCameraPMDCamBoardDevice.cpp index d67babacb3..5bbe284f84 100644 --- a/Modules/ToFHardware/mitkToFCameraPMDCamBoardDevice.cpp +++ b/Modules/ToFHardware/mitkToFCameraPMDCamBoardDevice.cpp @@ -1,79 +1,79 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "mitkToFCameraPMDCamBoardDevice.h" #include "mitkToFCameraPMDCamBoardController.h" #include "mitkRealTimeClock.h" #include "itkMultiThreader.h" namespace mitk { ToFCameraPMDCamBoardDevice::ToFCameraPMDCamBoardDevice() { m_Controller = ToFCameraPMDCamBoardController::New(); } ToFCameraPMDCamBoardDevice::~ToFCameraPMDCamBoardDevice() { } void ToFCameraPMDCamBoardDevice::SetRegionOfInterest(unsigned int leftUpperCornerX, unsigned int leftUpperCornerY, unsigned int width, unsigned int height) { if (m_Controller.IsNotNull()) { dynamic_cast(m_Controller.GetPointer())->SetRegionOfInterest(leftUpperCornerX,leftUpperCornerY,width,height); } } void ToFCameraPMDCamBoardDevice::SetProperty( const char *propertyKey, BaseProperty* propertyValue ) { this->m_PropertyList->SetProperty(propertyKey, propertyValue); ToFCameraPMDCamBoardController::Pointer myController = dynamic_cast(this->m_Controller.GetPointer()); bool boolValue = false; - GetBoolProperty(propertyValue, boolValue); + GetBoolProperty(propertyKey, boolValue); if (strcmp(propertyKey, "SetFPNCalibration") == 0) { myController->SetFPNCalibration(boolValue); } else if (strcmp(propertyKey, "SetFPPNCalibration") == 0) { myController->SetFPPNCalibration(boolValue); } else if (strcmp(propertyKey, "SetLinearityCalibration") == 0) { myController->SetLinearityCalibration(boolValue); } else if (strcmp(propertyKey, "SetLensCalibration") == 0) { myController->SetLensCalibration(boolValue); } else if (strcmp(propertyKey, "SetExposureMode") == 0) { if (boolValue) { myController->SetExposureMode(1); } else { myController->SetExposureMode(0); } } } } diff --git a/Modules/ToFHardware/mitkToFCameraPMDCamCubeDevice.cpp b/Modules/ToFHardware/mitkToFCameraPMDCamCubeDevice.cpp index 7d5e2949a8..fda0b81dcc 100644 --- a/Modules/ToFHardware/mitkToFCameraPMDCamCubeDevice.cpp +++ b/Modules/ToFHardware/mitkToFCameraPMDCamCubeDevice.cpp @@ -1,71 +1,71 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "mitkToFCameraPMDCamCubeDevice.h" #include "mitkRealTimeClock.h" #include "itkMultiThreader.h" namespace mitk { ToFCameraPMDCamCubeDevice::ToFCameraPMDCamCubeDevice() { m_Controller = ToFCameraPMDCamCubeController::New(); } ToFCameraPMDCamCubeDevice::~ToFCameraPMDCamCubeDevice() { } void ToFCameraPMDCamCubeDevice::SetProperty( const char *propertyKey, BaseProperty* propertyValue ) { ToFCameraPMDDevice::SetProperty(propertyKey,propertyValue); this->m_PropertyList->SetProperty(propertyKey, propertyValue); ToFCameraPMDCamCubeController::Pointer myController = dynamic_cast(this->m_Controller.GetPointer()); bool boolValue = false; - GetBoolProperty(propertyValue, boolValue); + GetBoolProperty(propertyKey, boolValue); if (strcmp(propertyKey, "SetFPNCalibration") == 0) { myController->SetFPNCalibration(boolValue); } else if (strcmp(propertyKey, "SetFPPNCalibration") == 0) { myController->SetFPPNCalibration(boolValue); } else if (strcmp(propertyKey, "SetLinearityCalibration") == 0) { myController->SetLinearityCalibration(boolValue); } else if (strcmp(propertyKey, "SetLensCalibration") == 0) { myController->SetLensCalibration(boolValue); } else if (strcmp(propertyKey, "SetExposureMode") == 0) { if (boolValue) { myController->SetExposureMode(1); } else { myController->SetExposureMode(0); } } } } diff --git a/Modules/ToFHardware/mitkToFCameraPMDDevice.cpp b/Modules/ToFHardware/mitkToFCameraPMDDevice.cpp index afbec13d99..e369ab3c70 100644 --- a/Modules/ToFHardware/mitkToFCameraPMDDevice.cpp +++ b/Modules/ToFHardware/mitkToFCameraPMDDevice.cpp @@ -1,409 +1,410 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "mitkToFCameraPMDDevice.h" #include "mitkRealTimeClock.h" #include "itkMultiThreader.h" #include namespace mitk { ToFCameraPMDDevice::ToFCameraPMDDevice() : m_SourceDataBuffer(NULL), m_SourceDataArray(NULL) { } ToFCameraPMDDevice::~ToFCameraPMDDevice() { this->CleanUpSourceData(); + CleanupPixelArrays(); } 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 buffers AllocatePixelArrays(); this->AllocateSourceData(); m_CameraConnected = true; } } return ok; } bool ToFCameraPMDDevice::DisconnectCamera() { bool ok = false; if (m_Controller) { ok = m_Controller->CloseCameraConnection(); if (ok) { 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_ImageMutex->Lock(); toFCameraDevice->m_Controller->GetSourceData(toFCameraDevice->m_SourceDataBuffer[toFCameraDevice->m_FreePos]); toFCameraDevice->m_ImageMutex->Unlock(); // call modified to indicate that cameraDevice was modified toFCameraDevice->Modified(); /*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! TODO Buffer Handling currently only works for buffer size 1 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/ //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; } 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) { if (m_CameraActive) { // 1) copy the image buffer // 2) Flip around y- axis (vertical axis) m_ImageMutex->Lock(); this->m_Controller->GetAmplitudes(this->m_SourceDataBuffer[this->m_CurrentPos], this->m_AmplitudeArray); m_ImageMutex->Unlock(); 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."; } } void ToFCameraPMDDevice::GetIntensities(float* intensityArray, int& imageSequence) { if (m_CameraActive) { // 1) copy the image buffer // 2) Flip around y- axis (vertical axis) m_ImageMutex->Lock(); this->m_Controller->GetIntensities(this->m_SourceDataBuffer[this->m_CurrentPos], this->m_IntensityArray); m_ImageMutex->Unlock(); 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) { if (m_CameraActive) { // 1) copy the image buffer // 2) convert the distance values from m to mm // 3) Flip around y- axis (vertical axis) m_ImageMutex->Lock(); this->m_Controller->GetDistances(this->m_SourceDataBuffer[this->m_CurrentPos], this->m_DistanceArray); m_ImageMutex->Unlock(); 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."; } } void ToFCameraPMDDevice::GetAllImages(float* distanceArray, float* amplitudeArray, float* intensityArray, char* sourceDataArray, - int requiredImageSequence, int& capturedImageSequence) + int requiredImageSequence, int& capturedImageSequence, unsigned char* rgbDataArray) { if (m_CameraActive) { // 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; 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->Lock(); 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); memcpy(sourceDataArray, this->m_SourceDataBuffer[this->m_CurrentPos], this->m_SourceDataSize); m_ImageMutex->Unlock(); 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]; } } } 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); + GetIntProperty(propertyKey, modulationFrequency); m_Controller->SetModulationFrequency(modulationFrequency); } else if (strcmp(propertyKey, "IntegrationTime") == 0) { int integrationTime = 0; - GetIntProperty(propertyValue, integrationTime); + GetIntProperty(propertyKey, 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 963d4baf90..cbaea80758 100644 --- a/Modules/ToFHardware/mitkToFCameraPMDDevice.h +++ b/Modules/ToFHardware/mitkToFCameraPMDDevice.h @@ -1,153 +1,153 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #ifndef __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); + int requiredImageSequence, int& capturedImageSequence, unsigned char* rgbDataArray=NULL); // 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/mitkToFCameraPMDPlayerDevice.cpp b/Modules/ToFHardware/mitkToFCameraPMDPlayerDevice.cpp index 8bd049a3cc..7aecfe9c6d 100644 --- a/Modules/ToFHardware/mitkToFCameraPMDPlayerDevice.cpp +++ b/Modules/ToFHardware/mitkToFCameraPMDPlayerDevice.cpp @@ -1,47 +1,47 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "mitkToFCameraPMDPlayerDevice.h" #include "mitkToFCameraPMDPlayerController.h" #include "itkMultiThreader.h" namespace mitk { ToFCameraPMDPlayerDevice::ToFCameraPMDPlayerDevice() { m_Controller = ToFCameraPMDPlayerController::New(); m_InputFileName = ""; } ToFCameraPMDPlayerDevice::~ToFCameraPMDPlayerDevice() { } void ToFCameraPMDPlayerDevice::SetProperty(const char* propertyKey, BaseProperty* propertyValue) { this->m_PropertyList->SetProperty(propertyKey, propertyValue); ToFCameraPMDPlayerController::Pointer myController = dynamic_cast(this->m_Controller.GetPointer()); std::string strValue; - GetStringProperty(propertyValue, strValue); + GetStringProperty(propertyKey, strValue); if (strcmp(propertyKey, "PMDFileName") == 0) { myController->SetPMDFileName(strValue); } } } diff --git a/Modules/ToFHardware/mitkToFCameraPMDRawDataCamBoardDevice.cpp b/Modules/ToFHardware/mitkToFCameraPMDRawDataCamBoardDevice.cpp index c152f68d72..b6ebfe6d69 100644 --- a/Modules/ToFHardware/mitkToFCameraPMDRawDataCamBoardDevice.cpp +++ b/Modules/ToFHardware/mitkToFCameraPMDRawDataCamBoardDevice.cpp @@ -1,102 +1,102 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "mitkToFCameraPMDRawDataCamBoardDevice.h" #include "mitkToFCameraPMDCamBoardController.h" // vtk includes #include "vtkSmartPointer.h" namespace mitk { ToFCameraPMDRawDataCamBoardDevice::ToFCameraPMDRawDataCamBoardDevice() { m_Controller = ToFCameraPMDCamBoardController::New(); } ToFCameraPMDRawDataCamBoardDevice::~ToFCameraPMDRawDataCamBoardDevice() { } void ToFCameraPMDRawDataCamBoardDevice::GetChannelSourceData(short* sourceData, vtkShortArray* vtkChannelArray ) { int i = 0; //unsigned int channelDataPosition = 0; unsigned int channelSize = (this->GetCaptureHeight()*this->GetCaptureWidth()*2); this->SetChannelSize(channelSize); signed short* channel1; signed short* channel2; signed short* channel3; signed short* channel4; vtkSmartPointer cvtkChannelArray = vtkShortArray::New(); cvtkChannelArray->SetNumberOfComponents(channelSize); cvtkChannelArray->SetNumberOfTuples(4); cvtkChannelArray->Allocate(1); channel1 = sourceData; cvtkChannelArray->InsertTupleValue(0,channel1); sourceData += channelSize; channel2 = sourceData; cvtkChannelArray->InsertTupleValue(1,channel2); sourceData += channelSize; channel3 = sourceData; cvtkChannelArray->InsertTupleValue(2,channel3); sourceData += channelSize; channel4 = sourceData; cvtkChannelArray->InsertTupleValue(3,channel4); vtkChannelArray->DeepCopy(cvtkChannelArray); cvtkChannelArray->Delete(); } void ToFCameraPMDRawDataCamBoardDevice::SetProperty( const char *propertyKey, BaseProperty* propertyValue ) { ToFCameraPMDRawDataDevice::SetProperty(propertyKey,propertyValue); this->m_PropertyList->SetProperty(propertyKey, propertyValue); ToFCameraPMDCamBoardController::Pointer myController = dynamic_cast(this->m_Controller.GetPointer()); bool boolValue = false; - GetBoolProperty(propertyValue, boolValue); + GetBoolProperty(propertyKey, boolValue); if (strcmp(propertyKey, "SetFPNCalibration") == 0) { myController->SetFPNCalibration(boolValue); } else if (strcmp(propertyKey, "SetFPPNCalibration") == 0) { myController->SetFPPNCalibration(boolValue); } else if (strcmp(propertyKey, "SetLinearityCalibration") == 0) { myController->SetLinearityCalibration(boolValue); } else if (strcmp(propertyKey, "SetLensCalibration") == 0) { myController->SetLensCalibration(boolValue); } else if (strcmp(propertyKey, "SetExposureMode") == 0) { if (boolValue) { myController->SetExposureMode(1); } else { myController->SetExposureMode(0); } } } } diff --git a/Modules/ToFHardware/mitkToFCameraPMDRawDataCamCubeDevice.cpp b/Modules/ToFHardware/mitkToFCameraPMDRawDataCamCubeDevice.cpp index 972a9e90dd..ac3cc2ceef 100644 --- a/Modules/ToFHardware/mitkToFCameraPMDRawDataCamCubeDevice.cpp +++ b/Modules/ToFHardware/mitkToFCameraPMDRawDataCamCubeDevice.cpp @@ -1,105 +1,105 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "mitkToFCameraPMDRawDataCamCubeDevice.h" #include "mitkToFCameraPMDCamCubeController.h" // vtk includes #include "vtkSmartPointer.h" namespace mitk { ToFCameraPMDRawDataCamCubeDevice::ToFCameraPMDRawDataCamCubeDevice() { m_Controller = ToFCameraPMDCamCubeController::New(); } ToFCameraPMDRawDataCamCubeDevice::~ToFCameraPMDRawDataCamCubeDevice() { } void ToFCameraPMDRawDataCamCubeDevice::GetChannelSourceData(short* sourceData, vtkShortArray* vtkChannelArray ) { int i = 0; unsigned int channelSize = (this->GetCaptureHeight()*this->GetCaptureWidth()*2); this->SetChannelSize(channelSize); signed short* channel1; signed short* channel2; signed short* channel3; signed short* channel4; vtkSmartPointer tempVTKChannelArray = vtkShortArray::New(); tempVTKChannelArray->SetNumberOfComponents(channelSize); tempVTKChannelArray->SetNumberOfTuples(4); tempVTKChannelArray->Allocate(1); sourceData += 256; channel1 = sourceData; tempVTKChannelArray->InsertTupleValue(0,channel1); sourceData += channelSize; sourceData += 256; channel2 = sourceData; tempVTKChannelArray->InsertTupleValue(1,channel2); sourceData += channelSize; sourceData += 256; channel3 = sourceData; tempVTKChannelArray->InsertTupleValue(2,channel3); sourceData += channelSize; sourceData += 256; channel4 = sourceData; tempVTKChannelArray->InsertTupleValue(3,channel4); vtkChannelArray->DeepCopy(tempVTKChannelArray); tempVTKChannelArray->Delete(); } void ToFCameraPMDRawDataCamCubeDevice::SetProperty( const char *propertyKey, BaseProperty* propertyValue ) { ToFCameraPMDRawDataDevice::SetProperty(propertyKey,propertyValue); this->m_PropertyList->SetProperty(propertyKey, propertyValue); ToFCameraPMDCamCubeController::Pointer myController = dynamic_cast(this->m_Controller.GetPointer()); bool boolValue = false; - GetBoolProperty(propertyValue, boolValue); + GetBoolProperty(propertyKey, boolValue); if (strcmp(propertyKey, "SetFPNCalibration") == 0) { myController->SetFPNCalibration(boolValue); } else if (strcmp(propertyKey, "SetFPPNCalibration") == 0) { myController->SetFPPNCalibration(boolValue); } else if (strcmp(propertyKey, "SetLinearityCalibration") == 0) { myController->SetLinearityCalibration(boolValue); } else if (strcmp(propertyKey, "SetLensCalibration") == 0) { myController->SetLensCalibration(boolValue); } else if (strcmp(propertyKey, "SetExposureMode") == 0) { if (boolValue) { myController->SetExposureMode(1); } else { myController->SetExposureMode(0); } } } } diff --git a/Modules/ToFHardware/mitkToFCameraPMDRawDataDevice.cpp b/Modules/ToFHardware/mitkToFCameraPMDRawDataDevice.cpp index 3133a60f56..3ac6750a4c 100644 --- a/Modules/ToFHardware/mitkToFCameraPMDRawDataDevice.cpp +++ b/Modules/ToFHardware/mitkToFCameraPMDRawDataDevice.cpp @@ -1,465 +1,465 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "mitkToFCameraPMDRawDataDevice.h" #include "mitkRealTimeClock.h" #include "itkMultiThreader.h" #include namespace mitk { ToFCameraPMDRawDataDevice::ToFCameraPMDRawDataDevice() : m_SourceDataBuffer(NULL), m_SourceDataArray(NULL), m_ShortSourceData(NULL) { m_RawDataSource = ThreadedToFRawDataReconstruction::New(); } ToFCameraPMDRawDataDevice::~ToFCameraPMDRawDataDevice() { this->CleanUpSourceData(); } bool ToFCameraPMDRawDataDevice::ConnectCamera() { bool ok = false; if (m_Controller.IsNotNull()) { 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 buffers this->AllocatePixelArrays(); this->AllocateSourceData(); m_CameraConnected = true; } } return ok; } bool ToFCameraPMDRawDataDevice::DisconnectCamera() { bool ok = false; if (m_Controller) { ok = m_Controller->CloseCameraConnection(); if (ok) { m_CameraConnected = false; } } return ok; } void ToFCameraPMDRawDataDevice::StartCamera() { if (m_CameraConnected) { // get the first image this->m_Controller->UpdateCamera(); this->m_ImageMutex->Lock(); 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(100); } else { MITK_INFO<<"Camera not connected"; } } void ToFCameraPMDRawDataDevice::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 ToFCameraPMDRawDataDevice::IsCameraActive() { m_CameraActiveMutex->Lock(); bool ok = m_CameraActive; m_CameraActiveMutex->Unlock(); return ok; } void ToFCameraPMDRawDataDevice::UpdateCamera() { if (m_Controller) { m_Controller->UpdateCamera(); } } ITK_THREAD_RETURN_TYPE ToFCameraPMDRawDataDevice::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; } ToFCameraPMDRawDataDevice* toFCameraDevice = (ToFCameraPMDRawDataDevice*)pInfo->UserData; if (toFCameraDevice!=NULL) { mitk::RealTimeClock::Pointer 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 // call modified to indicate that cameraDevice was modified toFCameraDevice->Modified(); vtkShortArray* channelData = vtkShortArray::New(); //toFCameraDevice->m_ImageMutex->Lock(); toFCameraDevice->m_Controller->GetShortSourceData(toFCameraDevice->m_ShortSourceData); toFCameraDevice->GetChannelSourceData( toFCameraDevice->m_ShortSourceData, channelData ); //toFCameraDevice->m_ImageMutex->Unlock(); if(!toFCameraDevice->m_RawDataSource->GetInit()) { toFCameraDevice->m_RawDataSource->Initialize(toFCameraDevice->m_CaptureWidth, toFCameraDevice->m_CaptureHeight, toFCameraDevice->m_Controller->GetModulationFrequency(), toFCameraDevice->GetChannelSize()); } toFCameraDevice->m_RawDataSource->SetChannelData(channelData); toFCameraDevice->m_RawDataSource->Update(); toFCameraDevice->m_ImageMutex->Lock(); toFCameraDevice->m_Controller->GetSourceData(toFCameraDevice->m_SourceDataArray); toFCameraDevice->m_RawDataSource->GetAllData(toFCameraDevice->m_DistanceArray, toFCameraDevice->m_AmplitudeArray, toFCameraDevice->m_IntensityArray); toFCameraDevice->m_ImageMutex->Unlock(); /*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! TODO Buffer Handling currently only works for buffer size 1 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/ 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) { overflow = true; } if (toFCameraDevice->m_ImageSequence % n == 0) { printStatus = true; } channelData->Delete(); if (overflow) { 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 ToFCameraPMDRawDataDevice::GetAmplitudes(float* amplitudeArray, int& imageSequence) { if (m_CameraActive) { memcpy(amplitudeArray, this->m_AmplitudeArray, this->m_PixelNumber*sizeof(float)); imageSequence = this->m_ImageSequence; } else { MITK_WARN("ToF") << "Warning: Data can only be acquired if camera is active."; } } void ToFCameraPMDRawDataDevice::GetIntensities(float* intensityArray, int& imageSequence) { if (m_CameraActive) { memcpy(intensityArray, this->m_IntensityArray, this->m_PixelNumber*sizeof(float)); imageSequence = this->m_ImageSequence; } else { MITK_WARN("ToF") << "Warning: Data can only be acquired if camera is active."; } } void ToFCameraPMDRawDataDevice::GetDistances(float* distanceArray, int& imageSequence) { if (m_CameraActive) { memcpy(distanceArray, this->m_DistanceArray, this->m_PixelNumber*sizeof(float)); imageSequence = this->m_ImageSequence; } else { MITK_WARN("ToF") << "Warning: Data can only be acquired if camera is active."; } } void ToFCameraPMDRawDataDevice::GetAllImages(float* distanceArray, float* amplitudeArray, float* intensityArray, char* sourceDataArray, - int requiredImageSequence, int& capturedImageSequence) + int requiredImageSequence, int& capturedImageSequence, unsigned char* rgbDataArray) { if (m_CameraActive) { // 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; 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; } memcpy(distanceArray, this->m_DistanceArray, this->m_PixelNumber*sizeof(float)); memcpy(amplitudeArray, this->m_AmplitudeArray, this->m_PixelNumber*sizeof(float)); memcpy(intensityArray, this->m_IntensityArray, this->m_PixelNumber*sizeof(float)); 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."; } } void ToFCameraPMDRawDataDevice::XYAxisFlipImage( float* imageData, float* &flippedData, int xAxis, int yAxis, int dimension ) { int captureWidth = this->GetCaptureWidth(); int captureHeight = this->GetCaptureHeight(); // //flips image around x- axis (horizontal axis) // if(xAxis == 1 && yAxis != 1) { for (int i=0; im_Controller; } void ToFCameraPMDRawDataDevice::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); + GetIntProperty(propertyKey, modulationFrequency); m_Controller->SetModulationFrequency(modulationFrequency); } else if (strcmp(propertyKey, "IntegrationTime") == 0) { int integrationTime = 0; - GetIntProperty(propertyValue, integrationTime); + GetIntProperty(propertyKey, integrationTime); m_Controller->SetIntegrationTime(integrationTime); } } void ToFCameraPMDRawDataDevice::CleanupPixelArrays() { if (m_IntensityArray) { delete [] m_IntensityArray; } if (m_DistanceArray) { delete [] m_DistanceArray; } if (m_AmplitudeArray) { delete [] m_AmplitudeArray; } if (m_ShortSourceData) { delete [] m_ShortSourceData; } } void ToFCameraPMDRawDataDevice::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;} this->m_ShortSourceData = new short[this->m_SourceDataSize]; for(int i=0; im_SourceDataSize; i++) {this->m_ShortSourceData[i]=0.0;} } void ToFCameraPMDRawDataDevice::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 ToFCameraPMDRawDataDevice::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/mitkToFCameraPMDRawDataDevice.h b/Modules/ToFHardware/mitkToFCameraPMDRawDataDevice.h index a63ef493f4..b687e75a34 100644 --- a/Modules/ToFHardware/mitkToFCameraPMDRawDataDevice.h +++ b/Modules/ToFHardware/mitkToFCameraPMDRawDataDevice.h @@ -1,175 +1,175 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #ifndef __mitkToFCameraPMDRawDataDevice_h #define __mitkToFCameraPMDRawDataDevice_h #include "mitkToFHardwareExports.h" #include "mitkToFCameraDevice.h" #include "mitkToFCameraPMDController.h" #include "mitkThreadedToFRawDataReconstruction.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 ToFCameraPMDRawDataDevice : public ToFCameraDevice { public: mitkClassMacro( ToFCameraPMDRawDataDevice , ToFCameraDevice ); itkNewMacro( Self ); itkSetMacro(ChannelSize, int); itkGetMacro(ChannelSize, int); /*! \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); + int requiredImageSequence, int& capturedImageSequence, unsigned char* rgbDataArray=NULL); // 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(); virtual void GetChannelSourceData(short* /*sourceData*/, vtkShortArray* /*vtkChannelArray*/ ){}; /*! \brief set a BaseProperty */ virtual void SetProperty( const char *propertyKey, BaseProperty* propertyValue ); protected: ToFCameraPMDRawDataDevice(); ~ToFCameraPMDRawDataDevice(); /*! \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 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(); /*! \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(); /*! \brief gets the image data and flips it according to user needs Caution! The user is responsible for allocating and deleting the data. \param imageData contains array to the input data. \param flippedData contains flipped output array - Caution! The user is responsible for allocating and deleting the data. Size should be equal to imageData! \param xAxis flag is set to flip around x axis (1 - set, 0 - not set). \param yAxis flag is set to flip around y axis (1 - set, 0 - not set). \param dimension contains the extend of the z dimension (preset is 1) */ void XYAxisFlipImage( float* imageData, float* &flippedData, int xAxis, int yAxis, int dimension = 1 ); ToFCameraPMDController::Pointer m_Controller; ///< corresponding CameraController ThreadedToFRawDataReconstruction::Pointer m_RawDataSource; char** m_SourceDataBuffer; ///< buffer holding the last acquired images char* m_SourceDataArray; ///< array holding the current PMD source data short* m_ShortSourceData; ///< array holding the current PMD raw data private: //member variables int m_ChannelSize; ///< member holds the size of a single raw data channel }; } //END mitk namespace #endif diff --git a/Modules/ToFHardware/mitkToFConfig.h.in b/Modules/ToFHardware/mitkToFConfig.h.in index abd6154cd6..3c89f9486a 100644 --- a/Modules/ToFHardware/mitkToFConfig.h.in +++ b/Modules/ToFHardware/mitkToFConfig.h.in @@ -1,15 +1,16 @@ /* mitToFConfig.h this file is generated. Do not change! */ #define MITK_TOF_PMDCAMBOARD_SOURCE_PLUGIN "@MITK_TOF_PMD_CAMBOARD_SOURCE@" #define MITK_TOF_PMDCAMBOARD_PROCESSING_PLUGIN "@MITK_TOF_PMD_CAMBOARD_PROC@" #define MITK_TOF_PMDO3_SOURCE_PLUGIN "@MITK_TOF_PMD_O3D_SOURCE@" #define MITK_TOF_PMDO3_PROCESSING_PLUGIN "@MITK_TOF_PMD_O3D_PROC@" #define MITK_TOF_PMDFILE_SOURCE_PLUGIN "@MITK_TOF_PMD_FILE_SOURCE@" #define MITK_TOF_PMDCAMCUBE_SOURCE_PLUGIN "@MITK_TOF_PMD_CAMCUBE_SOURCE@" #define MITK_TOF_PMDCAMCUBE_PROCESSING_PLUGIN "@MITK_TOF_PMD_CAMCUBE_PROC@" #define MITK_TOF_PLATFORM "@_PLATFORM_STRING@" #define MITK_TOF_DATA_DIR "@MITK_DATA_DIR@/ToF-Data" #define MITK_TOF_CAMERAS "@MITK_TOF_AVAILABLE_CAMERAS@" +#cmakedefine MITK_USE_TOF_KINECT diff --git a/Modules/ToFHardware/mitkToFHardware.cmake b/Modules/ToFHardware/mitkToFHardware.cmake index 8e2fd01aff..f8e3054a40 100644 --- a/Modules/ToFHardware/mitkToFHardware.cmake +++ b/Modules/ToFHardware/mitkToFHardware.cmake @@ -1,116 +1,129 @@ #option MITK_USE_TOF_HARDWARE -if(WIN32) - if(CMAKE_CL_64) - set(_PLATFORM_STRING "W64") - else(CMAKE_CL_64) - set(_PLATFORM_STRING "W32") - endif(CMAKE_CL_64) -else(WIN32) - if(CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64") - set(_PLATFORM_STRING "L64") - else(CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64") - set(_PLATFORM_STRING "L32") - endif(CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64") -endif(WIN32) +IF(WIN32) + IF(CMAKE_CL_64) + SET(_PLATFORM_STRING "W64") + ELSE(CMAKE_CL_64) + SET(_PLATFORM_STRING "W32") + ENDIF(CMAKE_CL_64) +ELSE(WIN32) + IF(CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64") + SET(_PLATFORM_STRING "L64") + ELSE(CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64") + SET(_PLATFORM_STRING "L32") + ENDIF(CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64") +ENDIF(WIN32) -set(MITK_TOF_AVAILABLE_CAMERAS MITK Player) +SET(MITK_TOF_AVAILABLE_CAMERAS MITK Player) + +OPTION(MITK_ENABLE_TOF_HARDWARE "Support for range cameras" OFF) +IF(MITK_ENABLE_TOF_HARDWARE) -option(MITK_ENABLE_TOF_HARDWARE "Support for range cameras" OFF) -if(MITK_ENABLE_TOF_HARDWARE) - #Begin PMD Camcube hardware -option(MITK_USE_TOF_PMDCAMCUBE "Enable support for PMD camcube" OFF) +OPTION(MITK_USE_TOF_PMDCAMCUBE "Enable support for PMD camcube" OFF) # only if PMD Camcube is enabled -if(MITK_USE_TOF_PMDCAMCUBE) - find_library(MITK_PMD_LIB pmdaccess2 DOC "PMD access library.") - get_filename_component(MITK_PMD_SDK_DIR ${MITK_PMD_LIB} PATH) - set(MITK_PMD_SDK_DIR ${MITK_PMD_SDK_DIR}/..) - find_path(MITK_PMD_INCLUDE_DIR pmdsdk2.h ${MITK_PMD_SDK_DIR}/include DOC "Include directory of PMD-SDK.") - set(MITK_TOF_PMD_CAMCUBE_SOURCE ${MITK_PMD_SDK_DIR}/plugins/camcube3.${_PLATFORM_STRING}.pap) - set(MITK_TOF_PMD_CAMCUBE_PROC ${MITK_PMD_SDK_DIR}/plugins/camcubeproc.${_PLATFORM_STRING}.ppp) - set(MITK_TOF_PMD_FILE_SOURCE ${MITK_PMD_SDK_DIR}/plugins/pmdfile.${_PLATFORM_STRING}.pcp) - set(MITK_TOF_AVAILABLE_CAMERAS ${MITK_TOF_AVAILABLE_CAMERAS},PMD CamCube 2.0/3.0,PMD CamCubeRaw 2.0/3.0,PMD Player,PMD Raw Data Player) -# file(GLOB MITK_TOF_PMD_CAMCUBE_SOURCE camcube3.${_PLATFORM_STRING}.pap) -# file(GLOB MITK_TOF_PMD_CAMCUBE_PROC camcubeproc.${_PLATFORM_STRING}.ppp) -# file(GLOB MITK_TOF_PMD_FILE_SOURCE pmdfile.${_PLATFORM_STRING}.pcp) - if(WIN32) +IF(MITK_USE_TOF_PMDCAMCUBE) + FIND_LIBRARY(MITK_PMD_LIB pmdaccess2 DOC "PMD access library.") + GET_FILENAME_COMPONENT(MITK_PMD_SDK_DIR ${MITK_PMD_LIB} PATH) + SET(MITK_PMD_SDK_DIR ${MITK_PMD_SDK_DIR}/..) + FIND_PATH(MITK_PMD_INCLUDE_DIR pmdsdk2.h ${MITK_PMD_SDK_DIR}/include DOC "Include directory of PMD-SDK.") + SET(MITK_TOF_PMD_CAMCUBE_SOURCE ${MITK_PMD_SDK_DIR}/plugins/camcube3.${_PLATFORM_STRING}.pap) + SET(MITK_TOF_PMD_CAMCUBE_PROC ${MITK_PMD_SDK_DIR}/plugins/camcubeproc.${_PLATFORM_STRING}.ppp) + SET(MITK_TOF_PMD_FILE_SOURCE ${MITK_PMD_SDK_DIR}/plugins/pmdfile.${_PLATFORM_STRING}.pcp) + SET(MITK_TOF_AVAILABLE_CAMERAS ${MITK_TOF_AVAILABLE_CAMERAS},PMD CamCube 2.0/3.0,PMD CamCubeRaw 2.0/3.0,PMD Player,PMD Raw Data Player) +# FILE(GLOB MITK_TOF_PMD_CAMCUBE_SOURCE camcube3.${_PLATFORM_STRING}.pap) +# FILE(GLOB MITK_TOF_PMD_CAMCUBE_PROC camcubeproc.${_PLATFORM_STRING}.ppp) +# FILE(GLOB MITK_TOF_PMD_FILE_SOURCE pmdfile.${_PLATFORM_STRING}.pcp) + IF(WIN32) MITK_INSTALL(FILES ${MITK_PMD_SDK_DIR}/bin/pmdaccess2.dll CONFIGURATIONS Release) MITK_INSTALL(FILES ${MITK_PMD_SDK_DIR}/plugins/camcube3.W32.pap CONFIGURATIONS Release) MITK_INSTALL(FILES ${MITK_PMD_SDK_DIR}/plugins/camcubeproc.W32.ppp CONFIGURATIONS Release) MITK_INSTALL(FILES ${MITK_PMD_SDK_DIR}/plugins/camcube3.W64.pap CONFIGURATIONS Release) MITK_INSTALL(FILES ${MITK_PMD_SDK_DIR}/plugins/camcubeproc.W64.ppp CONFIGURATIONS Release) MITK_INSTALL(FILES ${MITK_PMD_SDK_DIR}/plugins/pmdfile.W32.pcp CONFIGURATIONS Release) - endif(WIN32) -endif(MITK_USE_TOF_PMDCAMCUBE) + ENDIf(WIN32) +ENDIF(MITK_USE_TOF_PMDCAMCUBE) #End PMD Camcube Hardware #Begin PMD CamBoard hardware -option(MITK_USE_TOF_PMDCAMBOARD "Enable support for PMD camboard" OFF) +OPTION(MITK_USE_TOF_PMDCAMBOARD "Enable support for PMD camboard" OFF) # only if PMD CamBoard is enabled -if(MITK_USE_TOF_PMDCAMBOARD) - find_library(MITK_PMD_LIB pmdaccess2 DOC "PMD access library.") - get_filename_component(MITK_PMD_SDK_DIR ${MITK_PMD_LIB} PATH) - set(MITK_PMD_SDK_DIR ${MITK_PMD_SDK_DIR}/..) - find_path(MITK_PMD_INCLUDE_DIR pmdsdk2.h ${MITK_PMD_SDK_DIR}/include DOC "Include directory of PMD-SDK.") - set(MITK_TOF_PMD_CAMBOARD_SOURCE ${MITK_PMD_SDK_DIR}/plugins/camboard.${_PLATFORM_STRING}.pap) - set(MITK_TOF_PMD_CAMBOARD_PROC ${MITK_PMD_SDK_DIR}/plugins/camboardproc.${_PLATFORM_STRING}.ppp) - set(MITK_TOF_AVAILABLE_CAMERAS ${MITK_TOF_AVAILABLE_CAMERAS},PMD CamBoard,PMD CamBoardRaw) -# file(GLOB MITK_TOF_PMD_CAMBOARD_SOURCE camboard.${_PLATFORM_STRING}.pap) -# file(GLOB MITK_TOF_PMD_CAMBOARD_PROC camboardproc.${_PLATFORM_STRING}.ppp) -# file(GLOB MITK_TOF_PMD_FILE_SOURCE ${MITK_PMD_SDK_DIR}/plugins/pmdfile.${_PLATFORM_STRING}.pcp) - if(WIN32) - install(FILES ${MITK_PMD_SDK_DIR}/bin/pmdaccess2.dll DESTINATION bin CONFIGURATIONS Release) - install(FILES ${MITK_PMD_SDK_DIR}/plugins/camboard.W32.pap DESTINATION bin CONFIGURATIONS Release) - install(FILES ${MITK_PMD_SDK_DIR}/plugins/camboardproc.W32.ppp DESTINATION bin CONFIGURATIONS Release) -# install(FILES ${MITK_PMD_SDK_DIR}/plugins/camboard.W64.pap DESTINATION bin CONFIGURATIONS Release) -# install(FILES ${MITK_PMD_SDK_DIR}/plugins/camboardproc.W64.ppp DESTINATION bin CONFIGURATIONS Release) -# install(FILES ${MITK_PMD_SDK_DIR}/plugins/pmdfile.W32.pcp DESTINATION bin CONFIGURATIONS Release) - endif(WIN32) -endif(MITK_USE_TOF_PMDCAMBOARD) +IF(MITK_USE_TOF_PMDCAMBOARD) + FIND_LIBRARY(MITK_PMD_LIB pmdaccess2 DOC "PMD access library.") + GET_FILENAME_COMPONENT(MITK_PMD_SDK_DIR ${MITK_PMD_LIB} PATH) + SET(MITK_PMD_SDK_DIR ${MITK_PMD_SDK_DIR}/..) + FIND_PATH(MITK_PMD_INCLUDE_DIR pmdsdk2.h ${MITK_PMD_SDK_DIR}/include DOC "Include directory of PMD-SDK.") + SET(MITK_TOF_PMD_CAMBOARD_SOURCE ${MITK_PMD_SDK_DIR}/plugins/camboard.${_PLATFORM_STRING}.pap) + SET(MITK_TOF_PMD_CAMBOARD_PROC ${MITK_PMD_SDK_DIR}/plugins/camboardproc.${_PLATFORM_STRING}.ppp) + SET(MITK_TOF_AVAILABLE_CAMERAS ${MITK_TOF_AVAILABLE_CAMERAS},PMD CamBoard,PMD CamBoardRaw) +# FILE(GLOB MITK_TOF_PMD_CAMBOARD_SOURCE camboard.${_PLATFORM_STRING}.pap) +# FILE(GLOB MITK_TOF_PMD_CAMBOARD_PROC camboardproc.${_PLATFORM_STRING}.ppp) +# FILE(GLOB MITK_TOF_PMD_FILE_SOURCE ${MITK_PMD_SDK_DIR}/plugins/pmdfile.${_PLATFORM_STRING}.pcp) + IF(WIN32) + INSTALL(FILES ${MITK_PMD_SDK_DIR}/bin/pmdaccess2.dll DESTINATION bin CONFIGURATIONS Release) + INSTALL(FILES ${MITK_PMD_SDK_DIR}/plugins/camboard.W32.pap DESTINATION bin CONFIGURATIONS Release) + INSTALL(FILES ${MITK_PMD_SDK_DIR}/plugins/camboardproc.W32.ppp DESTINATION bin CONFIGURATIONS Release) +# INSTALL(FILES ${MITK_PMD_SDK_DIR}/plugins/camboard.W64.pap DESTINATION bin CONFIGURATIONS Release) +# INSTALL(FILES ${MITK_PMD_SDK_DIR}/plugins/camboardproc.W64.ppp DESTINATION bin CONFIGURATIONS Release) +# INSTALL(FILES ${MITK_PMD_SDK_DIR}/plugins/pmdfile.W32.pcp DESTINATION bin CONFIGURATIONS Release) + ENDIf(WIN32) +ENDIF(MITK_USE_TOF_PMDCAMBOARD) #End PMD CamBoard Hardware #Begin MESA SR4000 hardware -option(MITK_USE_TOF_MESASR4000 "Enable support for MESA SR4000" OFF) +OPTION(MITK_USE_TOF_MESASR4000 "Enable support for MESA SR4000" OFF) # only if MESA SR4000 is enabled -if(MITK_USE_TOF_MESASR4000) - find_library(MITK_MESA_LIB libMesaSR DOC "MESA access library.") - get_filename_component(MITK_MESA_SDK_DIR ${MITK_MESA_LIB} PATH) - set(MITK_MESA_SDK_DIR ${MITK_MESA_SDK_DIR}/..) - find_path(MITK_MESA_INCLUDE_DIR libMesaSR.h ${MITK_MESA_SDK_DIR}/include DOC "Include directory of MESA-SDK.") - set(MITK_TOF_AVAILABLE_CAMERAS ${MITK_TOF_AVAILABLE_CAMERAS},MESA Swissranger 4000) - if(WIN32) - install(FILES ${MITK_MESA_SDK_DIR}/bin/libMesaSR.dll DESTINATION bin CONFIGURATIONS Release) - endif(WIN32) -endif(MITK_USE_TOF_MESASR4000) +IF(MITK_USE_TOF_MESASR4000) + FIND_LIBRARY(MITK_MESA_LIB libMesaSR DOC "MESA access library.") + GET_FILENAME_COMPONENT(MITK_MESA_SDK_DIR ${MITK_MESA_LIB} PATH) + SET(MITK_MESA_SDK_DIR ${MITK_MESA_SDK_DIR}/..) + FIND_PATH(MITK_MESA_INCLUDE_DIR libMesaSR.h ${MITK_MESA_SDK_DIR}/include DOC "Include directory of MESA-SDK.") + SET(MITK_TOF_AVAILABLE_CAMERAS ${MITK_TOF_AVAILABLE_CAMERAS},MESA Swissranger 4000) + IF(WIN32) + INSTALL(FILES ${MITK_MESA_SDK_DIR}/bin/libMesaSR.dll DESTINATION bin CONFIGURATIONS Release) + ENDIf(WIN32) +ENDIF(MITK_USE_TOF_MESASR4000) #End MESA SR4000 Hardware -if(WIN32) +IF (WIN32) #Begin PMD O3 hardware -option(MITK_USE_TOF_PMDO3 "Enable support for PMD O3 camera" OFF) +OPTION(MITK_USE_TOF_PMDO3 "Enable support for PMD O3 camera" OFF) # only if PMD O3 is enabled -if(MITK_USE_TOF_PMDO3) - find_library(MITK_PMD_LIB pmdaccess2 DOC "PMD access library.") - get_filename_component(MITK_PMD_SDK_DIR ${MITK_PMD_LIB} PATH) - set(MITK_PMD_SDK_DIR ${MITK_PMD_SDK_DIR}/..) - find_path(MITK_PMD_INCLUDE_DIR pmdsdk2.h ${MITK_PMD_SDK_DIR}/include DOC "Include directory of PMD-SDK.") - set(MITK_TOF_PMD_O3D_SOURCE ${MITK_PMD_SDK_DIR}/plugins/o3d.${_PLATFORM_STRING}.pcp) - set(MITK_TOF_PMD_O3D_PROC ${MITK_PMD_SDK_DIR}/plugins/o3d.${_PLATFORM_STRING}.pcp) - set(MITK_TOF_AVAILABLE_CAMERAS ${MITK_TOF_AVAILABLE_CAMERAS},PMD O3D) +IF(MITK_USE_TOF_PMDO3) + FIND_LIBRARY(MITK_PMD_LIB pmdaccess2 DOC "PMD access library.") + GET_FILENAME_COMPONENT(MITK_PMD_SDK_DIR ${MITK_PMD_LIB} PATH) + SET(MITK_PMD_SDK_DIR ${MITK_PMD_SDK_DIR}/..) + FIND_PATH(MITK_PMD_INCLUDE_DIR pmdsdk2.h ${MITK_PMD_SDK_DIR}/include DOC "Include directory of PMD-SDK.") + SET(MITK_TOF_PMD_O3D_SOURCE ${MITK_PMD_SDK_DIR}/plugins/o3d.${_PLATFORM_STRING}.pcp) + SET(MITK_TOF_PMD_O3D_PROC ${MITK_PMD_SDK_DIR}/plugins/o3d.${_PLATFORM_STRING}.pcp) + SET(MITK_TOF_AVAILABLE_CAMERAS ${MITK_TOF_AVAILABLE_CAMERAS},PMD O3D) -# file(GLOB MITK_TOF_PMD_O3D_SOURCE o3d.${_PLATFORM_STRING}.pcp) -# file(GLOB MITK_TOF_PMD_O3D_PROC o3d.${_PLATFORM_STRING}.pcp) +# FILE(GLOB MITK_TOF_PMD_O3D_SOURCE o3d.${_PLATFORM_STRING}.pcp) +# FILE(GLOB MITK_TOF_PMD_O3D_PROC o3d.${_PLATFORM_STRING}.pcp) MITK_INSTALL(FILES ${MITK_PMD_SDK_DIR}/bin/pmdaccess2.dll CONFIGURATIONS Release) MITK_INSTALL(FILES ${MITK_PMD_SDK_DIR}/plugins/o3d.W32.pcp CONFIGURATIONS Release) -endif(MITK_USE_TOF_PMDO3) +ENDIF(MITK_USE_TOF_PMDO3) #End PMD O3 Hardware -endif(WIN32) +ENDIF(WIN32) -endif(MITK_ENABLE_TOF_HARDWARE) +#Begin Kinect hardware +OPTION(MITK_USE_TOF_KINECT "Enable support for Kinect camera" OFF) +# only if Kinect is enabled +IF(MITK_USE_TOF_KINECT) + FIND_LIBRARY(MITK_KINECT_LIB libOpenNI DOC "Kinect access library.") + FIND_PATH(MITK_KINECT_INCLUDE_DIR XnCppWrapper.h DOC "Include directory of Kinect camera.") + SET(MITK_TOF_AVAILABLE_CAMERAS ${MITK_TOF_AVAILABLE_CAMERAS},Microsoft Kinect) +#TODO Installer specific stuff +# IF(WIN32) +# INSTALL(FILES ${MITK_MESA_SDK_DIR}/bin/libMesaSR.dll DESTINATION bin CONFIGURATIONS Release) +# ENDIf(WIN32) +ENDIF(MITK_USE_TOF_KINECT) +#End Kinect Hardware -configure_file(mitkToFConfig.h.in ${PROJECT_BINARY_DIR}/mitkToFConfig.h @ONLY) +ENDIF(MITK_ENABLE_TOF_HARDWARE) +CONFIGURE_FILE(mitkToFConfig.h.in ${PROJECT_BINARY_DIR}/mitkToFConfig.h @ONLY) diff --git a/Modules/ToFHardware/mitkToFImageCsvWriter.cpp b/Modules/ToFHardware/mitkToFImageCsvWriter.cpp index 6745eeb102..b39691833c 100644 --- a/Modules/ToFHardware/mitkToFImageCsvWriter.cpp +++ b/Modules/ToFHardware/mitkToFImageCsvWriter.cpp @@ -1,124 +1,124 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include namespace mitk { ToFImageCsvWriter::ToFImageCsvWriter(): ToFImageWriter(), m_DistanceOutfile(NULL), m_AmplitudeOutfile(NULL), m_IntensityOutfile(NULL) { this->m_Extension = std::string(".csv"); } ToFImageCsvWriter::~ToFImageCsvWriter() { } void ToFImageCsvWriter::Open() { this->CheckForFileExtension(this->m_DistanceImageFileName); this->CheckForFileExtension(this->m_AmplitudeImageFileName); this->CheckForFileExtension(this->m_IntensityImageFileName); this->m_PixelNumber = this->m_CaptureWidth * this->m_CaptureHeight; this->m_ImageSizeInBytes = this->m_PixelNumber * sizeof(float); if (this->m_DistanceImageSelected) { this->OpenCsvFile(&(this->m_DistanceOutfile), this->m_DistanceImageFileName); } if (this->m_AmplitudeImageSelected) { this->OpenCsvFile(&(this->m_AmplitudeOutfile), this->m_AmplitudeImageFileName); } if (this->m_IntensityImageSelected) { this->OpenCsvFile(&(this->m_IntensityOutfile), this->m_IntensityImageFileName); } this->m_NumOfFrames = 0; } void ToFImageCsvWriter::Close() { if (this->m_DistanceImageSelected) { this->CloseCsvFile(this->m_DistanceOutfile); } if (this->m_AmplitudeImageSelected) { this->CloseCsvFile(this->m_AmplitudeOutfile); } if (this->m_IntensityImageSelected) { this->CloseCsvFile(this->m_IntensityOutfile); } } - void ToFImageCsvWriter::Add(float* distanceFloatData, float* amplitudeFloatData, float* intensityFloatData) + void ToFImageCsvWriter::Add(float* distanceFloatData, float* amplitudeFloatData, float* intensityFloatData, unsigned char* rgbData) { if (this->m_DistanceImageSelected) { this->WriteCsvFile(this->m_DistanceOutfile, distanceFloatData); } if (this->m_AmplitudeImageSelected) { this->WriteCsvFile(this->m_AmplitudeOutfile, amplitudeFloatData); } if (this->m_IntensityImageSelected) { this->WriteCsvFile(this->m_IntensityOutfile, intensityFloatData); } this->m_NumOfFrames++; } void ToFImageCsvWriter::WriteCsvFile(FILE* outfile, float* floatData) { for(int i=0; im_PixelNumber; i++) { if (this->m_NumOfFrames==0 && i==0) { fprintf(outfile, "%f", floatData[i]); } else { fprintf(outfile, ",%f", floatData[i]); } } } void ToFImageCsvWriter::OpenCsvFile(FILE** outfile, std::string outfileName) { (*outfile) = fopen( outfileName.c_str(), "w+" ); if( !outfile ) { MITK_ERROR << "Error opening outfile: " << outfileName; throw std::logic_error("Error opening outfile."); return; } } void ToFImageCsvWriter::CloseCsvFile(FILE* outfile) { if (this->m_NumOfFrames == 0) { fclose(outfile); throw std::logic_error("File is empty."); return; } fclose(outfile); } } diff --git a/Modules/ToFHardware/mitkToFImageCsvWriter.h b/Modules/ToFHardware/mitkToFImageCsvWriter.h index 37fadbe302..458f5a5b39 100644 --- a/Modules/ToFHardware/mitkToFImageCsvWriter.h +++ b/Modules/ToFHardware/mitkToFImageCsvWriter.h @@ -1,88 +1,87 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #ifndef __mitkToFImageCsvWriter_h #define __mitkToFImageCsvWriter_h #include "mitkToFImageWriter.h" #include "mitkToFHardwareExports.h" namespace mitk { /** * @brief CSV writer class for ToF image data * * This writer class allows streaming of ToF data into a CSV file. * Writer can simultaneously save "distance", "intensity" and "amplitude" image data. * Output files are written as 1D CSV data stream. * * @ingroup ToFHardware */ class MITK_TOFHARDWARE_EXPORT ToFImageCsvWriter : public ToFImageWriter { public: /*! \brief standard ctor */ ToFImageCsvWriter(); /*! \brief standard ~ctor */ ~ToFImageCsvWriter(); mitkClassMacro( ToFImageCsvWriter , ToFImageWriter ); itkNewMacro( Self ); /*! \brief Checks for file extensions and opens the output files */ void Open(); /*! \brief Closes the output files */ void Close(); /*! \brief Pushes the image data to the output files \param data from distance, amplitude and intensity images as float values */ - void Add(float* distanceFloatData, float* amplitudeFloatData, float* intensityFloatData); + void Add(float* distanceFloatData, float* amplitudeFloatData, float* intensityFloatData, unsigned char* rgbData=0); protected: Image::Pointer m_MitkImage; ///< mitk image used for pic header creation FILE* m_DistanceOutfile; ///< file for distance image FILE* m_AmplitudeOutfile; ///< file for amplitude image FILE* m_IntensityOutfile; ///< file for intensity image - private: /*! \brief opens CSV output file \param output file, name of the output file */ void OpenCsvFile(FILE** outfile, std::string outfileName); /*! \brief closes CSV output file \param output file */ void CloseCsvFile(FILE* outfile); /*! \brief writes the data to the CSV output file \param output file, data array of float values */ void WriteCsvFile(FILE* outfile, float* floatData); }; } //END mitk namespace #endif // __mitkToFImageCsvWriter_h diff --git a/Modules/ToFHardware/mitkToFImageGrabber.cpp b/Modules/ToFHardware/mitkToFImageGrabber.cpp index 65700cbe47..992d20bc8f 100644 --- a/Modules/ToFHardware/mitkToFImageGrabber.cpp +++ b/Modules/ToFHardware/mitkToFImageGrabber.cpp @@ -1,254 +1,279 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "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_SourceDataArray(NULL) + m_IntensityArray(NULL), m_DistanceArray(NULL), m_AmplitudeArray(NULL), m_SourceDataArray(NULL), m_RgbDataArray(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()); + OutputImageType::Pointer output3 = static_cast(this->MakeOutput(3).GetPointer()); mitk::ImageSource::SetNumberOfRequiredOutputs(3); mitk::ImageSource::SetNthOutput(0, output0.GetPointer()); mitk::ImageSource::SetNthOutput(1, output1.GetPointer()); mitk::ImageSource::SetNthOutput(2, output2.GetPointer()); + mitk::ImageSource::SetNthOutput(3, output3.GetPointer()); } ToFImageGrabber::~ToFImageGrabber() { - if (m_IntensityArray||m_AmplitudeArray||m_DistanceArray) + if (m_IntensityArray||m_AmplitudeArray||m_DistanceArray||m_RgbDataArray) { 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; + unsigned int dimensions[3]; + dimensions[0] = this->m_ToFCameraDevice->GetCaptureWidth(); + dimensions[1] = this->m_ToFCameraDevice->GetCaptureHeight(); + dimensions[2] = 1; + mitk::PixelType FloatType = MakeScalarPixelType(); + // acquire new image data + this->m_ToFCameraDevice->GetAllImages(this->m_DistanceArray, this->m_AmplitudeArray, this->m_IntensityArray, this->m_SourceDataArray, + requiredImageSequence, this->m_ImageSequence, this->m_RgbDataArray ); 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[3]; - dimensions[0] = this->m_ToFCameraDevice->GetCaptureWidth(); - dimensions[1] = this->m_ToFCameraDevice->GetCaptureHeight(); - dimensions[2] = 1; - - mitk::PixelType FloatType = MakeScalarPixelType(); - distanceImage->Initialize(FloatType, 3, dimensions, 1); + } + mitk::Image::Pointer amplitudeImage = this->GetOutput(1); + if (!amplitudeImage->IsInitialized()) + { + amplitudeImage->ReleaseData(); amplitudeImage->Initialize(FloatType, 3, dimensions, 1); + } + mitk::Image::Pointer intensityImage = this->GetOutput(2); + if (!intensityImage->IsInitialized()) + { + intensityImage->ReleaseData(); intensityImage->Initialize(FloatType, 3, dimensions, 1); } - if (m_DistanceArray&&m_AmplitudeArray&&m_IntensityArray) + mitk::Image::Pointer rgbImage = this->GetOutput(3); + if (!rgbImage->IsInitialized()) { - this->m_ToFCameraDevice->GetAllImages(this->m_DistanceArray, this->m_AmplitudeArray, this->m_IntensityArray, this->m_SourceDataArray, - requiredImageSequence, this->m_ImageSequence ); + rgbImage->ReleaseData(); + rgbImage->Initialize(mitk::PixelType(MakePixelType, 3>()),3,dimensions,1); + } - capturedImageSequence = this->m_ImageSequence; + capturedImageSequence = this->m_ImageSequence; + if (m_DistanceArray) + { distanceImage->SetSlice(this->m_DistanceArray, 0, 0, 0); + } + if (m_AmplitudeArray) + { amplitudeImage->SetSlice(this->m_AmplitudeArray, 0, 0, 0); + } + if (m_IntensityArray) + { intensityImage->SetSlice(this->m_IntensityArray, 0, 0, 0); } + if (m_RgbDataArray) + { + rgbImage->SetSlice(this->m_RgbDataArray, 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(); AllocateImageArrays(); } return ok; } bool ToFImageGrabber::DisconnectCamera() { bool success = m_ToFCameraDevice->DisconnectCamera(); 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); + this->m_ToFCameraDevice->GetIntProperty("IntegrationTime",integrationTime); return integrationTime; } int ToFImageGrabber::GetModulationFrequency() { int modulationFrequency = 0; - BaseProperty* property = this->m_ToFCameraDevice->GetProperty("ModulationFrequency"); - this->m_ToFCameraDevice->GetIntProperty(property,modulationFrequency); + this->m_ToFCameraDevice->GetIntProperty("ModulationFrequency",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; } + if (m_RgbDataArray) + { + delete [] m_RgbDataArray; + m_RgbDataArray = 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]; + m_RgbDataArray = new unsigned char[m_PixelNumber*3]; } } diff --git a/Modules/ToFHardware/mitkToFImageGrabber.h b/Modules/ToFHardware/mitkToFImageGrabber.h index a0ccfe395e..71af0d0802 100644 --- a/Modules/ToFHardware/mitkToFImageGrabber.h +++ b/Modules/ToFHardware/mitkToFImageGrabber.h @@ -1,170 +1,171 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #ifndef __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. * * 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 char* m_RgbDataArray; ///< member holding the current rgb 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/ToFHardware/mitkToFImageRecorder.cpp b/Modules/ToFHardware/mitkToFImageRecorder.cpp index 2c64145e93..dde3618564 100644 --- a/Modules/ToFHardware/mitkToFImageRecorder.cpp +++ b/Modules/ToFHardware/mitkToFImageRecorder.cpp @@ -1,247 +1,252 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "mitkToFImageRecorder.h" #include "mitkRealTimeClock.h" #include "itkMultiThreader.h" #include #pragma GCC visibility push(default) #include #pragma GCC visibility pop namespace mitk { ToFImageRecorder::ToFImageRecorder() { this->m_ToFCameraDevice = NULL; this->m_MultiThreader = itk::MultiThreader::New(); this->m_AbortMutex = itk::FastMutexLock::New(); this->m_ThreadID = 0; this->m_NumOfFrames = 0; this->m_ToFImageWriter = NULL; this->m_DistanceImageSelected = true; this->m_AmplitudeImageSelected = true; this->m_IntensityImageSelected = true; + this->m_RGBImageSelected = true; this->m_Abort = true; this->m_CaptureWidth = 0; this->m_CaptureHeight = 0; this->m_FileFormat = ""; this->m_PixelNumber = 0; this->m_SourceDataSize = 0; this->m_ToFImageType = ToFImageWriter::ToFImageType3D; this->m_RecordMode = ToFImageRecorder::PerFrames; this->m_DistanceImageFileName = ""; this->m_AmplitudeImageFileName = ""; this->m_IntensityImageFileName = ""; + this->m_RGBImageFileName = ""; this->m_ImageSequence = 0; this->m_DistanceArray = NULL; this->m_AmplitudeArray = NULL; this->m_IntensityArray = NULL; + this->m_RGBArray = NULL; this->m_SourceDataArray = NULL; } ToFImageRecorder::~ToFImageRecorder() { delete[] m_DistanceArray; delete[] m_AmplitudeArray; delete[] m_IntensityArray; + delete[] m_RGBArray; delete[] m_SourceDataArray; } void ToFImageRecorder::StopRecording() { this->m_AbortMutex->Lock(); this->m_Abort = true; this->m_AbortMutex->Unlock(); } void ToFImageRecorder::StartRecording() { if (this->m_ToFCameraDevice.IsNull()) { throw std::invalid_argument("ToFCameraDevice is NULL."); return; } if (this->m_FileFormat.compare(".csv") == 0) { this->m_ToFImageWriter = ToFImageCsvWriter::New(); } else if(this->m_FileFormat.compare(".nrrd") == 0) { this->m_ToFImageWriter = ToFNrrdImageWriter::New(); this->m_ToFImageWriter->SetExtension(m_FileFormat); } - else if(this->m_FileFormat.compare(".pic") == 0) - { - this->m_ToFImageWriter = ToFPicImageWriter::New(); - this->m_ToFImageWriter->SetExtension(m_FileFormat); - } else { throw std::logic_error("No file format specified!"); } this->m_CaptureWidth = this->m_ToFCameraDevice->GetCaptureWidth(); this->m_CaptureHeight = this->m_ToFCameraDevice->GetCaptureHeight(); this->m_PixelNumber = this->m_CaptureWidth * this->m_CaptureHeight; this->m_SourceDataSize = this->m_ToFCameraDevice->GetSourceDataSize(); // allocate buffer if(m_IntensityArray == NULL) { this->m_IntensityArray = new float[m_PixelNumber]; } if(this->m_DistanceArray == NULL) { this->m_DistanceArray = new float[m_PixelNumber]; } if(this->m_AmplitudeArray == NULL) { this->m_AmplitudeArray = new float[m_PixelNumber]; } + if(this->m_RGBArray == NULL) + { + this->m_RGBArray = new unsigned char[m_PixelNumber*3]; + } if(this->m_SourceDataArray == NULL) { this->m_SourceDataArray = new char[m_SourceDataSize]; } this->m_ToFImageWriter->SetDistanceImageFileName(this->m_DistanceImageFileName); this->m_ToFImageWriter->SetAmplitudeImageFileName(this->m_AmplitudeImageFileName); this->m_ToFImageWriter->SetIntensityImageFileName(this->m_IntensityImageFileName); + this->m_ToFImageWriter->SetRGBImageFileName(this->m_RGBImageFileName); this->m_ToFImageWriter->SetCaptureWidth(this->m_CaptureWidth); this->m_ToFImageWriter->SetCaptureHeight(this->m_CaptureHeight); this->m_ToFImageWriter->SetToFImageType(this->m_ToFImageType); this->m_ToFImageWriter->SetDistanceImageSelected(this->m_DistanceImageSelected); this->m_ToFImageWriter->SetAmplitudeImageSelected(this->m_AmplitudeImageSelected); this->m_ToFImageWriter->SetIntensityImageSelected(this->m_IntensityImageSelected); + this->m_ToFImageWriter->SetRGBImageSelected(this->m_RGBImageSelected); this->m_ToFImageWriter->Open(); this->m_AbortMutex->Lock(); this->m_Abort = false; this->m_AbortMutex->Unlock(); this->m_ThreadID = this->m_MultiThreader->SpawnThread(this->RecordData, this); } ITK_THREAD_RETURN_TYPE ToFImageRecorder::RecordData(void* pInfoStruct) { struct itk::MultiThreader::ThreadInfoStruct * pInfo = (struct itk::MultiThreader::ThreadInfoStruct*)pInfoStruct; if (pInfo == NULL) { return ITK_THREAD_RETURN_VALUE; } if (pInfo->UserData == NULL) { return ITK_THREAD_RETURN_VALUE; } ToFImageRecorder* toFImageRecorder = (ToFImageRecorder*)pInfo->UserData; if (toFImageRecorder!=NULL) { ToFCameraDevice::Pointer toFCameraDevice = toFImageRecorder->GetCameraDevice(); mitk::RealTimeClock::Pointer realTimeClock; realTimeClock = mitk::RealTimeClock::New(); int n = 100; double t1 = 0; double t2 = 0; t1 = realTimeClock->GetCurrentStamp(); bool overflow = false; bool printStatus = false; int requiredImageSequence = 0; int numOfFramesRecorded = 0; bool abort = false; toFImageRecorder->m_AbortMutex->Lock(); abort = toFImageRecorder->m_Abort; toFImageRecorder->m_AbortMutex->Unlock(); while ( !abort ) { if ( ((toFImageRecorder->m_RecordMode == ToFImageRecorder::PerFrames) && (numOfFramesRecorded < toFImageRecorder->m_NumOfFrames)) || (toFImageRecorder->m_RecordMode == ToFImageRecorder::Infinite) ) { toFCameraDevice->GetAllImages(toFImageRecorder->m_DistanceArray, toFImageRecorder->m_AmplitudeArray, - toFImageRecorder->m_IntensityArray, toFImageRecorder->m_SourceDataArray, requiredImageSequence, toFImageRecorder->m_ImageSequence ); + toFImageRecorder->m_IntensityArray, toFImageRecorder->m_SourceDataArray, requiredImageSequence, toFImageRecorder->m_ImageSequence, toFImageRecorder->m_RGBArray ); if (toFImageRecorder->m_ImageSequence >= requiredImageSequence) { if (toFImageRecorder->m_ImageSequence > requiredImageSequence) { MITK_INFO << "Problem! required: " << requiredImageSequence << " captured: " << toFImageRecorder->m_ImageSequence; } requiredImageSequence = toFImageRecorder->m_ImageSequence + 1; toFImageRecorder->m_ToFImageWriter->Add( toFImageRecorder->m_DistanceArray, - toFImageRecorder->m_AmplitudeArray, toFImageRecorder->m_IntensityArray ); + toFImageRecorder->m_AmplitudeArray, toFImageRecorder->m_IntensityArray, toFImageRecorder->m_RGBArray ); numOfFramesRecorded++; if (numOfFramesRecorded % n == 0) { printStatus = true; } if (printStatus) { t2 = realTimeClock->GetCurrentStamp() - t1; MITK_INFO << " Framerate (fps): " << n / (t2/1000) << " Sequence: " << toFImageRecorder->m_ImageSequence; t1 = realTimeClock->GetCurrentStamp(); printStatus = false; } } toFImageRecorder->m_AbortMutex->Lock(); abort = toFImageRecorder->m_Abort; toFImageRecorder->m_AbortMutex->Unlock(); } else { abort = true; } } // end of while loop toFImageRecorder->InvokeEvent(itk::AbortEvent()); toFImageRecorder->m_ToFImageWriter->Close(); } return ITK_THREAD_RETURN_VALUE; } void ToFImageRecorder::SetCameraDevice(ToFCameraDevice* aToFCameraDevice) { this->m_ToFCameraDevice = aToFCameraDevice; } ToFCameraDevice* ToFImageRecorder::GetCameraDevice() { return this->m_ToFCameraDevice; } ToFImageWriter::ToFImageType ToFImageRecorder::GetToFImageType() { return this->m_ToFImageType; } void ToFImageRecorder::SetToFImageType(ToFImageWriter::ToFImageType toFImageType) { this->m_ToFImageType = toFImageType; } ToFImageRecorder::RecordMode ToFImageRecorder::GetRecordMode() { return this->m_RecordMode; } void ToFImageRecorder::SetRecordMode(ToFImageRecorder::RecordMode recordMode) { this->m_RecordMode = recordMode; } } diff --git a/Modules/ToFHardware/mitkToFImageRecorder.h b/Modules/ToFHardware/mitkToFImageRecorder.h index 3f09b6f76c..4cce490a4a 100644 --- a/Modules/ToFHardware/mitkToFImageRecorder.h +++ b/Modules/ToFHardware/mitkToFImageRecorder.h @@ -1,160 +1,166 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #ifndef __mitkToFImageRecorder_h #define __mitkToFImageRecorder_h #include "mitkToFHardwareExports.h" #include "mitkCommon.h" #include "mitkToFCameraDevice.h" -#include "mitkToFPicImageWriter.h" #include "mitkToFImageCsvWriter.h" #include "mitkToFNrrdImageWriter.h" #include "itkObject.h" #include "itkObjectFactory.h" #include "itkFastMutexLock.h" #include "itkCommand.h" namespace mitk { /** * @brief Recorder class for ToF images * * This class represents a recorder for ToF data. A ToFCameraDevice is used to acquire the data. The acquired images * are then added to a ToFImageWriter that performs the actual writing. * * Recording can be performed either frame-based or continuously * * @ingroup ToFHardware */ class MITK_TOFHARDWARE_EXPORT ToFImageRecorder : public itk::Object { public: ToFImageRecorder(); ~ToFImageRecorder(); mitkClassMacro( ToFImageRecorder , itk::Object ); itkNewMacro( Self ); itkGetMacro( DistanceImageFileName, std::string ); itkGetMacro( AmplitudeImageFileName, std::string ); itkGetMacro( IntensityImageFileName, std::string ); + itkGetMacro( RGBImageFileName, std::string ); itkGetMacro( CaptureWidth, int ); itkGetMacro( CaptureHeight, int ); itkGetMacro( DistanceImageSelected, bool ); itkGetMacro( AmplitudeImageSelected, bool ); itkGetMacro( IntensityImageSelected, bool ); + itkGetMacro( RGBImageSelected, bool ); itkGetMacro( NumOfFrames, int ); itkGetMacro( FileFormat, std::string ); itkSetMacro( DistanceImageFileName, std::string ); itkSetMacro( AmplitudeImageFileName, std::string ); itkSetMacro( IntensityImageFileName, std::string ); + itkSetMacro(RGBImageFileName, std::string ); itkSetMacro( DistanceImageSelected, bool ); itkSetMacro( AmplitudeImageSelected, bool ); itkSetMacro( IntensityImageSelected, bool ); + itkSetMacro( RGBImageSelected, bool ); itkSetMacro( NumOfFrames, int ); itkSetMacro( FileFormat, std::string ); enum RecordMode{ PerFrames, Infinite }; /*! \brief Returns the currently set RecordMode \return record mode: PerFrames ("Record specified number of frames"), Infinite ("Record until abort is required") */ ToFImageRecorder::RecordMode GetRecordMode(); /*! \brief Set the RecordMode \param recordMode: PerFrames ("Record specified number of frames"), Infinite ("Record until abort is required") */ void SetRecordMode(ToFImageRecorder::RecordMode recordMode); /*! \brief Set the device used for acquiring ToF images \param aToFCameraDevice ToF camera device used. */ void SetCameraDevice(ToFCameraDevice* aToFCameraDevice); /*! \brief Get the device used for acquiring ToF images \return ToF camera device used. */ ToFCameraDevice* GetCameraDevice(); /*! \brief Get the type of image to be recorded \return ToF image type: ToFImageType3D (0) or ToFImageType2DPlusT (1) */ ToFImageWriter::ToFImageType GetToFImageType(); /*! \brief Set the type of image to be recorded \param toFImageType type of the ToF image: ToFImageType3D (0) or ToFImageType2DPlusT (1) */ void SetToFImageType(ToFImageWriter::ToFImageType toFImageType); /*! \brief Starts the recording by spawning a Thread which streams the data to a file. Aborting of the record process is controlled by the m_Abort flag */ void StartRecording(); /*! \brief Stops the recording by setting the m_Abort flag to false */ void StopRecording(); protected: /*! \brief Thread method acquiring data via the ToFCameraDevice and recording it to file via the ToFImageWriter */ static ITK_THREAD_RETURN_TYPE RecordData(void* pInfoStruct); // data acquisition ToFCameraDevice::Pointer m_ToFCameraDevice; ///< ToFCameraDevice used for acquiring the images int m_CaptureWidth; ///< width (x-dimension) of the images to record. int m_CaptureHeight; ///< height (y-dimension) of the images to record. int m_PixelNumber; ///< number of pixels (widht*height) of the images to record int m_SourceDataSize; ///< size of the source data provided by the device int m_ImageSequence; ///< number of images currently acquired float* m_IntensityArray; ///< array holding the intensity data float* m_DistanceArray; ///< array holding the distance data float* m_AmplitudeArray; ///< array holding the amplitude data + unsigned char* m_RGBArray; ///< array holding the RGB data if available (e.g. for Kinect) char* m_SourceDataArray; ///< array holding the source data // data writing ToFImageWriter::Pointer m_ToFImageWriter; ///< image writer writing the acquired images to a file std::string m_DistanceImageFileName; ///< file name for saving the distance image std::string m_AmplitudeImageFileName; ///< file name for saving the amplitude image std::string m_IntensityImageFileName; ///< file name for saving the intensity image - + std::string m_RGBImageFileName; ///< file name for saving the rgb image + int m_NumOfFrames; ///< number of frames to be recorded by this recorder ToFImageWriter::ToFImageType m_ToFImageType; ///< type of image to be recorded: ToFImageType3D (0) or ToFImageType2DPlusT (1) ToFImageRecorder::RecordMode m_RecordMode; ///< mode of recording the images: specified number of frames (PerFrames) or infinite (Infinite) std::string m_FileFormat; ///< file format for saving images. If .csv is chosen, ToFImageCsvWriter is used bool m_DistanceImageSelected; ///< flag indicating if distance image should be recorded bool m_AmplitudeImageSelected; ///< flag indicating if amplitude image should be recorded bool m_IntensityImageSelected; ///< flag indicating if intensity image should be recorded + bool m_RGBImageSelected; ///< flag indicating if rgb image should be recorded // threading itk::MultiThreader::Pointer m_MultiThreader; ///< member for thread-handling (ITK-based) int m_ThreadID; ///< ID of the thread recording the data itk::FastMutexLock::Pointer m_AbortMutex; ///< mutex for thread-safe data access of abort flag bool m_Abort; ///< flag controlling the abort mechanism of the recording procedure. For thread-safety only use in combination with m_AbortMutex private: }; } //END mitk namespace #endif diff --git a/Modules/ToFHardware/mitkToFImageRecorderFilter.cpp b/Modules/ToFHardware/mitkToFImageRecorderFilter.cpp index 254a3a8f49..1d1a7b34c3 100644 --- a/Modules/ToFHardware/mitkToFImageRecorderFilter.cpp +++ b/Modules/ToFHardware/mitkToFImageRecorderFilter.cpp @@ -1,168 +1,163 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include #include #include #include "mitkToFNrrdImageWriter.h" -#include "mitkToFPicImageWriter.h" #include "mitkToFImageCsvWriter.h" // itk includes #include "itksys/SystemTools.hxx" mitk::ToFImageRecorderFilter::ToFImageRecorderFilter(): m_RecordingStarted(false), m_ToFImageWriter(0) { m_FileExtension = ""; } mitk::ToFImageRecorderFilter::~ToFImageRecorderFilter() { } void mitk::ToFImageRecorderFilter::SetFileName(std::string fileName) { std::string name = fileName; m_FileExtension = itksys::SystemTools::GetFilenameLastExtension( fileName ); if(m_FileExtension == ".nrrd") { m_ToFImageWriter = mitk::ToFNrrdImageWriter::New(); } - else if(m_FileExtension == ".pic") - { - m_ToFImageWriter = mitk::ToFPicImageWriter::New(); - } else if(m_FileExtension == ".csv") { m_ToFImageWriter = mitk::ToFImageCsvWriter::New(); } else { throw std::logic_error("The specified file type is not supported, standard file type is .nrrd!"); } int pos = name.find_last_of("."); name.insert(pos,"_DistanceImage"); m_ToFImageWriter->SetDistanceImageFileName(name); name = fileName; name.insert(pos,"_AmplitudeImage"); m_ToFImageWriter->SetAmplitudeImageFileName(name); name = fileName; name.insert(pos,"_IntensityImage"); m_ToFImageWriter->SetIntensityImageFileName(name); } void mitk::ToFImageRecorderFilter::SetImageType(mitk::ToFImageWriter::ToFImageType tofImageType) { m_ToFImageWriter->SetToFImageType(tofImageType); } void mitk::ToFImageRecorderFilter::GenerateData() { mitk::Image::Pointer distanceImageInput = this->GetInput(0); assert(distanceImageInput); mitk::Image::Pointer amplitudeImageInput = this->GetInput(1); assert(amplitudeImageInput); mitk::Image::Pointer intensityImageInput = this->GetInput(2); assert(intensityImageInput); // add current data to file stream float* distanceFloatData = (float*)distanceImageInput->GetSliceData(0, 0, 0)->GetData(); float* amplitudeFloatData = (float*)amplitudeImageInput->GetSliceData(0, 0, 0)->GetData(); float* intensityFloatData = (float*)intensityImageInput->GetSliceData(0, 0, 0)->GetData(); if (m_RecordingStarted) { m_ToFImageWriter->Add(distanceFloatData,amplitudeFloatData,intensityFloatData); } // set outputs to inputs this->SetNthOutput(0,distanceImageInput); this->SetNthOutput(1,amplitudeImageInput); this->SetNthOutput(2,intensityImageInput); } void mitk::ToFImageRecorderFilter::StartRecording() { if(m_ToFImageWriter.IsNull()) { throw std::logic_error("ToFImageWriter is unitialized, set filename first!"); return; } m_ToFImageWriter->Open(); m_RecordingStarted = true; } void mitk::ToFImageRecorderFilter::StopRecording() { m_ToFImageWriter->Close(); m_RecordingStarted = false; } mitk::ToFImageWriter::Pointer mitk::ToFImageRecorderFilter::GetToFImageWriter() { return m_ToFImageWriter; } void mitk::ToFImageRecorderFilter::SetToFImageWriter(mitk::ToFImageWriter::Pointer tofImageWriter) { m_ToFImageWriter = tofImageWriter; } void mitk::ToFImageRecorderFilter::SetInput( mitk::Image* input ) { this->SetInput(0,input); } void mitk::ToFImageRecorderFilter::SetInput( unsigned int idx, mitk::Image* input ) { if ((input == NULL) && (idx == this->GetNumberOfInputs() - 1)) // if the last input is set to NULL, reduce the number of inputs by one { this->SetNumberOfInputs(this->GetNumberOfInputs() - 1); } else { this->ProcessObject::SetNthInput(idx, input); // Process object is not const-correct so the const_cast is required here unsigned int xDim = input->GetDimension(0); unsigned int yDim = input->GetDimension(1); m_ToFImageWriter->SetCaptureWidth(xDim); m_ToFImageWriter->SetCaptureWidth(yDim); } this->CreateOutputsForAllInputs(); } mitk::Image* mitk::ToFImageRecorderFilter::GetInput() { return this->GetInput(0); } mitk::Image* mitk::ToFImageRecorderFilter::GetInput( unsigned int idx ) { if (this->GetNumberOfInputs() < 1) return NULL; return static_cast< mitk::Image*>(this->ProcessObject::GetInput(idx)); } void mitk::ToFImageRecorderFilter::CreateOutputsForAllInputs() { this->SetNumberOfOutputs(this->GetNumberOfInputs()); // create outputs for all inputs for (unsigned int idx = 0; idx < this->GetNumberOfOutputs(); ++idx) if (this->GetOutput(idx) == NULL) { DataObjectPointer newOutput = this->MakeOutput(idx); this->SetNthOutput(idx, newOutput); } this->Modified(); } diff --git a/Modules/ToFHardware/mitkToFImageWriter.cpp b/Modules/ToFHardware/mitkToFImageWriter.cpp index e44513e6fd..cde6276aa2 100644 --- a/Modules/ToFHardware/mitkToFImageWriter.cpp +++ b/Modules/ToFHardware/mitkToFImageWriter.cpp @@ -1,65 +1,65 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include #include // itk includes #include "itksys/SystemTools.hxx" namespace mitk { ToFImageWriter::ToFImageWriter():m_Extension(".nrrd"), - m_DistanceImageFileName(), m_AmplitudeImageFileName(), m_IntensityImageFileName(), + m_DistanceImageFileName(), m_AmplitudeImageFileName(), m_IntensityImageFileName(), m_RGBImageFileName(), m_NumOfFrames(0), m_DistanceImageSelected(true), m_AmplitudeImageSelected(true), - m_IntensityImageSelected(true),m_CaptureWidth(200),m_CaptureHeight(200), + m_IntensityImageSelected(true), m_RGBImageSelected(true), m_CaptureWidth(200),m_CaptureHeight(200), m_PixelNumber(0), m_ImageSizeInBytes(0), m_ToFImageType(ToFImageWriter::ToFImageType3D) { } ToFImageWriter::~ToFImageWriter() { } void ToFImageWriter::CheckForFileExtension(std::string& fileName) { std::string baseFilename = itksys::SystemTools::GetFilenameWithoutLastExtension( fileName ); std::string extension = itksys::SystemTools::GetFilenameLastExtension( fileName ); if( extension.length() != 0 && extension != this->m_Extension) { MITK_ERROR << "Wrong file extension! The default extension is " << this->m_Extension.c_str() << ", currently the requested file extension is " << extension.c_str() <<"!"; this->m_Extension = extension; } size_t found = fileName.find( this->m_Extension ); // !!! HAS to be at the very end of the filename (not somewhere in the middle) if( found == std::string::npos) { fileName.append(this->m_Extension); } } ToFImageWriter::ToFImageType ToFImageWriter::GetToFImageType() { return this->m_ToFImageType; } void ToFImageWriter::SetToFImageType(ToFImageWriter::ToFImageType toFImageType) { this->m_ToFImageType = toFImageType; } } // end namespace mitk diff --git a/Modules/ToFHardware/mitkToFImageWriter.h b/Modules/ToFHardware/mitkToFImageWriter.h index 5b01bfc83d..ccf139354b 100644 --- a/Modules/ToFHardware/mitkToFImageWriter.h +++ b/Modules/ToFHardware/mitkToFImageWriter.h @@ -1,122 +1,128 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #ifndef __mitkToFImageWriter_h #define __mitkToFImageWriter_h #include "mitkToFHardwareExports.h" #include "mitkCommon.h" #include "mitkToFImageGrabber.h" #include "itkObject.h" #include "itkObjectFactory.h" namespace mitk { /** * @brief Writer class for ToF images * * This writer class allows streaming of ToF data into a file. The .pic file format is used for writing the data. * Image information is included in the header of the pic file. * Writer can simultaneously save "distance", "intensity" and "amplitude" image. * Images can be written as 3D volume (ToFImageType::ToFImageType3D) or temporal image stack (ToFImageType::ToFImageType2DPlusT) * * @ingroup ToFHardware */ class MITK_TOFHARDWARE_EXPORT ToFImageWriter : public itk::Object { public: ToFImageWriter(); ~ToFImageWriter(); mitkClassMacro( ToFImageWriter , itk::Object ); itkNewMacro( Self ); itkGetMacro( DistanceImageFileName, std::string ); itkGetMacro( AmplitudeImageFileName, std::string ); itkGetMacro( IntensityImageFileName, std::string ); + itkGetMacro( RGBImageFileName, std::string ); itkGetMacro( Extension, std::string ); itkGetMacro( CaptureWidth, int ); itkGetMacro( CaptureHeight, int ); itkGetMacro( DistanceImageSelected, bool ); itkGetMacro( AmplitudeImageSelected, bool ); itkGetMacro( IntensityImageSelected, bool ); + itkGetMacro( RGBImageSelected, bool ); itkSetMacro( DistanceImageFileName, std::string ); itkSetMacro( AmplitudeImageFileName, std::string ); itkSetMacro( IntensityImageFileName, std::string ); + itkSetMacro( RGBImageFileName, std::string ); itkSetMacro( Extension, std::string ); itkSetMacro( CaptureWidth, int ); itkSetMacro( CaptureHeight, int ); itkSetMacro( DistanceImageSelected, bool ); itkSetMacro( AmplitudeImageSelected, bool ); itkSetMacro( IntensityImageSelected, bool ); + itkSetMacro( RGBImageSelected, bool ); enum ToFImageType{ ToFImageType3D, ToFImageType2DPlusT }; /*! \brief Get the type of image to be written \return ToF image type: ToFImageType3D (0) or ToFImageType2DPlusT (1) */ ToFImageWriter::ToFImageType GetToFImageType(); /*! \brief Set the type of image to be written \param toFImageType type of the ToF image: ToFImageType3D (0) or ToFImageType2DPlusT (1) */ void SetToFImageType(ToFImageWriter::ToFImageType toFImageType); /*! \brief Open file(s) for writing */ virtual void Open(){}; /*! \brief Close file(s) add .pic header and write */ virtual void Close(){}; /*! \brief Add new data to file. */ - virtual void Add(float* distanceFloatData, float* amplitudeFloatData, float* intensityFloatData){}; + virtual void Add(float* distanceFloatData, float* amplitudeFloatData, float* intensityFloatData, unsigned char* rgbData=0){}; protected: /*! \brief Checks file name if file extension exists. If not an error message is returned */ void CheckForFileExtension(std::string& fileName); // member variables std::string m_DistanceImageFileName; ///< file name for saving the distance image std::string m_AmplitudeImageFileName; ///< file name for saving the amplitude image std::string m_IntensityImageFileName; ///< file name for saving the intensity image + std::string m_RGBImageFileName; ///< file name for saving the RGB image std::string m_Extension; ///< file extension used for saving images int m_CaptureWidth; ///< width (x-dimension) of the images to record. int m_CaptureHeight; ///< height (y-dimension) of the images to record. int m_PixelNumber; ///< number of pixels (widht*height) of the images to record int m_ImageSizeInBytes; ///< size of the image to save in bytes int m_NumOfFrames; ///< number of frames written to the image. Used for pic header. ToFImageWriter::ToFImageType m_ToFImageType; ///< type of image to be recorded: ToFImageType3D (0) or ToFImageType2DPlusT (1) bool m_DistanceImageSelected; ///< flag indicating if distance image should be recorded bool m_AmplitudeImageSelected; ///< flag indicating if amplitude image should be recorded bool m_IntensityImageSelected; ///< flag indicating if intensity image should be recorded + bool m_RGBImageSelected; ///< flag indicating if RGB image should be recorded private: }; } //END mitk namespace #endif // __mitkToFImageWriter_h diff --git a/Modules/ToFHardware/mitkToFNrrdImageWriter.cpp b/Modules/ToFHardware/mitkToFNrrdImageWriter.cpp index 9fe767263b..864090dc7c 100644 --- a/Modules/ToFHardware/mitkToFNrrdImageWriter.cpp +++ b/Modules/ToFHardware/mitkToFNrrdImageWriter.cpp @@ -1,206 +1,251 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ // mitk includes #include // itk includes #include "itksys/SystemTools.hxx" #include "itkNrrdImageIO.h" namespace mitk { ToFNrrdImageWriter::ToFNrrdImageWriter(): ToFImageWriter(), m_DistanceOutfile(), m_AmplitudeOutfile(), m_IntensityOutfile() { m_Extension = std::string(".nrrd"); } ToFNrrdImageWriter::~ToFNrrdImageWriter() { } void ToFNrrdImageWriter::Open() { this->CheckForFileExtension(this->m_DistanceImageFileName); this->CheckForFileExtension(this->m_AmplitudeImageFileName); this->CheckForFileExtension(this->m_IntensityImageFileName); + this->CheckForFileExtension(this->m_RGBImageFileName); this->m_PixelNumber = this->m_CaptureWidth * this->m_CaptureHeight; this->m_ImageSizeInBytes = this->m_PixelNumber * sizeof(float); if (this->m_DistanceImageSelected) { this->OpenStreamFile( this->m_DistanceOutfile, this->m_DistanceImageFileName); } if (this->m_AmplitudeImageSelected) { this->OpenStreamFile(this->m_AmplitudeOutfile, this->m_AmplitudeImageFileName); } if (this->m_IntensityImageSelected) { this->OpenStreamFile(this->m_IntensityOutfile, this->m_IntensityImageFileName); } + if (this->m_RGBImageSelected) + { + this->OpenStreamFile(this->m_RGBOutfile, this->m_RGBImageFileName); + } this->m_NumOfFrames = 0; } void ToFNrrdImageWriter::Close() { if (this->m_DistanceImageSelected) { this->CloseStreamFile(this->m_DistanceOutfile, this->m_DistanceImageFileName); } if (this->m_AmplitudeImageSelected) { this->CloseStreamFile(this->m_AmplitudeOutfile, this->m_AmplitudeImageFileName); } if (this->m_IntensityImageSelected) { this->CloseStreamFile(this->m_IntensityOutfile, this->m_IntensityImageFileName); } + if (this->m_RGBImageSelected) + { + this->CloseStreamFile(this->m_RGBOutfile, this->m_RGBImageFileName); + } } - void ToFNrrdImageWriter::Add(float* distanceFloatData, float* amplitudeFloatData, float* intensityFloatData) + void ToFNrrdImageWriter::Add(float* distanceFloatData, float* amplitudeFloatData, float* intensityFloatData, unsigned char* rgbData) { if (this->m_DistanceImageSelected) { this->m_DistanceOutfile.write( (char*) distanceFloatData, this->m_ImageSizeInBytes); } if (this->m_AmplitudeImageSelected) { this->m_AmplitudeOutfile.write( (char*)amplitudeFloatData, this->m_ImageSizeInBytes); } if (this->m_IntensityImageSelected) { this->m_IntensityOutfile.write(( char* )intensityFloatData, this->m_ImageSizeInBytes); } + if (this->m_RGBImageSelected) + { + this->m_RGBOutfile.write(( char* )rgbData, this->m_PixelNumber*3 * sizeof(unsigned char)); + } this->m_NumOfFrames++; } void ToFNrrdImageWriter::OpenStreamFile( std::ofstream &outfile, std::string outfileName ) { outfile.open(outfileName.c_str(), std::ofstream::binary); if(!outfile.is_open()) { MITK_ERROR << "Error opening outfile: " << outfileName; throw std::logic_error("Error opening outfile."); return; } } void ToFNrrdImageWriter::CloseStreamFile( std::ofstream &outfile, std::string fileName ) { if (this->m_NumOfFrames == 0) { outfile.close(); throw std::logic_error("File is empty."); return; } // flush the last data to the file and convert the stream data to nrrd file outfile.flush(); this->ConvertStreamToNrrdFormat( fileName ); outfile.close(); } void ToFNrrdImageWriter::ConvertStreamToNrrdFormat( std::string fileName ) { - - float* floatData = new float[this->m_PixelNumber]; - for(int i=0; im_PixelNumber; i++) - { - floatData[i] = i + 0.0; - } - Image::Pointer imageTemplate = Image::New(); int dimension ; unsigned int* dimensions; if(m_ToFImageType == ToFImageType2DPlusT) { dimension = 4; dimensions = new unsigned int[dimension]; dimensions[0] = this->m_CaptureWidth; dimensions[1] = this->m_CaptureHeight; dimensions[2] = 1; dimensions[3] = this->m_NumOfFrames; } else if( m_ToFImageType == ToFImageType3D) { dimension = 3; dimensions = new unsigned int[dimension]; dimensions[0] = this->m_CaptureWidth; dimensions[1] = this->m_CaptureHeight; dimensions[2] = this->m_NumOfFrames; } else { throw std::logic_error("No image type set, please choose between 2D+t and 3D!"); } + float* floatData; + unsigned char* rgbData; + if (fileName==this->m_RGBImageFileName) + { + rgbData = new unsigned char[this->m_PixelNumber*3]; + for(int i=0; im_PixelNumber*3; i++) + { + rgbData[i] = i + 0.0; + } + mitk::PixelType RGBType = MakePixelType, 3>(); + imageTemplate->Initialize( RGBType,dimension, dimensions, 1); + imageTemplate->SetSlice(rgbData, 0, 0, 0); + } + else + { + floatData = new float[this->m_PixelNumber]; + for(int i=0; im_PixelNumber; i++) + { + floatData[i] = i + 0.0; + } + mitk::PixelType FloatType = MakeScalarPixelType(); + imageTemplate->Initialize( FloatType,dimension, dimensions, 1); + imageTemplate->SetSlice(floatData, 0, 0, 0); + } - mitk::PixelType FloatType = MakeScalarPixelType(); - imageTemplate->Initialize( FloatType,dimension, dimensions, 1); - imageTemplate->SetSlice(floatData, 0, 0, 0); - - itk::NrrdImageIO::Pointer nrrdWriter = itk::NrrdImageIO::New(); nrrdWriter->SetNumberOfDimensions(dimension); nrrdWriter->SetPixelTypeInfo(imageTemplate->GetPixelType().GetTypeId()); if(imageTemplate->GetPixelType().GetNumberOfComponents() > 1) { nrrdWriter->SetNumberOfComponents(imageTemplate->GetPixelType().GetNumberOfComponents()); } itk::ImageIORegion ioRegion( dimension ); mitk::Vector3D spacing = imageTemplate->GetGeometry()->GetSpacing(); mitk::Point3D origin = imageTemplate->GetGeometry()->GetOrigin(); for(unsigned int i = 0; i < dimension; i++) { nrrdWriter->SetDimensions(i,dimensions[i]); nrrdWriter->SetSpacing(i,spacing[i]); nrrdWriter->SetOrigin(i,origin[i]); mitk::Vector3D direction; direction.Set_vnl_vector(imageTemplate->GetGeometry()->GetIndexToWorldTransform()->GetMatrix().GetVnlMatrix().get_column(i)); vnl_vector< double > axisDirection(dimension); for(unsigned int j = 0; j < dimension; j++) { axisDirection[j] = direction[j]/spacing[i]; } nrrdWriter->SetDirection( i, axisDirection ); ioRegion.SetSize(i, imageTemplate->GetLargestPossibleRegion().GetSize(i) ); ioRegion.SetIndex(i, imageTemplate->GetLargestPossibleRegion().GetIndex(i) ); } nrrdWriter->SetIORegion(ioRegion); nrrdWriter->SetFileName(fileName); nrrdWriter->SetUseStreamedWriting(true); std::ifstream stream(fileName.c_str(), std::ifstream::binary); - unsigned int size = this->m_PixelNumber * this->m_NumOfFrames; - unsigned int sizeInBytes = size * sizeof(float); - float* data = new float[size]; - stream.read((char*)data, sizeInBytes); - nrrdWriter->Write(data); - stream.close(); - - delete[] data; + if (fileName==m_RGBImageFileName) + { + unsigned int size = this->m_PixelNumber*3 * this->m_NumOfFrames; + unsigned int sizeInBytes = size * sizeof(unsigned char); + unsigned char* data = new unsigned char[size]; + stream.read((char*)data, sizeInBytes); + nrrdWriter->Write(data); + stream.close(); + delete[] data; + } + else + { + unsigned int size = this->m_PixelNumber * this->m_NumOfFrames; + unsigned int sizeInBytes = size * sizeof(float); + float* data = new float[size]; + stream.read((char*)data, sizeInBytes); + nrrdWriter->Write(data); + stream.close(); + delete[] data; + } + delete[] dimensions; - delete[] floatData; + if (fileName==m_RGBImageFileName) + { + delete[] rgbData; + } + else + { + delete[] floatData; + } } } // end namespace mitk diff --git a/Modules/ToFHardware/mitkToFNrrdImageWriter.h b/Modules/ToFHardware/mitkToFNrrdImageWriter.h index 5ef689bfcd..96aa8b2b58 100644 --- a/Modules/ToFHardware/mitkToFNrrdImageWriter.h +++ b/Modules/ToFHardware/mitkToFNrrdImageWriter.h @@ -1,79 +1,80 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #ifndef __mitkToFNrrdImageWriter_h #define __mitkToFNrrdImageWriter_h #include "mitkToFHardwareExports.h" #include "mitkToFImageWriter.h" #include namespace mitk { /** * @brief Writer class for ToF nrrd images * * This writer class allows streaming of ToF data into a nrrd file. This class uses the itkNrrdImageIO class * Writer can simultaneously save "distance", "intensity" and "amplitude" image. * Images can be written as 3D volume (ToFImageType::ToFImageType3D) or temporal image stack (ToFImageType::ToFImageType2DPlusT) * * @ingroup ToFHardware */ class MITK_TOFHARDWARE_EXPORT ToFNrrdImageWriter : public ToFImageWriter { public: mitkClassMacro( ToFNrrdImageWriter , ToFImageWriter ); itkNewMacro( Self ); /*! \brief Open file(s) for writing */ void Open(); /*! \brief Close file(s) add .pic header and write */ void Close(); /*! \brief Add new data to file. */ - void Add(float* distanceFloatData, float* amplitudeFloatData, float* intensityFloatData); + void Add(float* distanceFloatData, float* amplitudeFloatData, float* intensityFloatData, unsigned char* rgbData=0); protected: std::ofstream m_DistanceOutfile; ///< file for distance image std::ofstream m_AmplitudeOutfile; ///< file for amplitude image std::ofstream m_IntensityOutfile; ///< file for intensity image + std::ofstream m_RGBOutfile; ///< file for intensity image private: ToFNrrdImageWriter(); ~ToFNrrdImageWriter(); /*! \brief Open file by filename to gain write access to it. */ void OpenStreamFile(std::ofstream &outfile, std::string outfileName); /*! \brief Close file after work on it is finished. */ void CloseStreamFile(std::ofstream &outfile, std::string fileName); /*! \brief Write image information to the NrrdFile. */ void ConvertStreamToNrrdFormat( std::string fileName ); }; } //END mitk namespace #endif // __mitkToFNrrdImageWriter_h diff --git a/Modules/ToFHardware/mitkToFOpenCVImageGrabber.cpp b/Modules/ToFHardware/mitkToFOpenCVImageGrabber.cpp index 704f47e112..ab42edbac6 100644 --- a/Modules/ToFHardware/mitkToFOpenCVImageGrabber.cpp +++ b/Modules/ToFHardware/mitkToFOpenCVImageGrabber.cpp @@ -1,179 +1,180 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "mitkToFOpenCVImageGrabber.h" // mitk includes #include "mitkImageDataItem.h" +#include #include "vtkSmartPointer.h" #include "vtkColorTransferFunction.h" #include "vtkFloatArray.h" namespace mitk { ToFOpenCVImageGrabber::ToFOpenCVImageGrabber() { m_CurrentOpenCVIntensityImage = NULL; m_CurrentOpenCVAmplitudeImage = NULL; m_CurrentOpenCVDistanceImage = NULL; m_ImageType = 0; m_ImageDepth = IPL_DEPTH_32F; m_ImageGrabber = NULL; } ToFOpenCVImageGrabber::~ToFOpenCVImageGrabber() { } cv::Mat ToFOpenCVImageGrabber::GetImage() { m_ImageGrabber->Update(); unsigned int numOfPixel = m_ImageGrabber->GetCaptureWidth()*m_ImageGrabber->GetCaptureHeight(); // copy current mitk images unsigned int dimensions[4]; dimensions[0] = this->m_ImageGrabber->GetCaptureWidth(); dimensions[1] = this->m_ImageGrabber->GetCaptureHeight(); dimensions[2] = 1; dimensions[3] = 1; // create single component float pixel type mitk::PixelType FloatType = MakeScalarPixelType(); mitk::Image::Pointer currentMITKIntensityImage = mitk::Image::New(); currentMITKIntensityImage->Initialize(FloatType, 2, dimensions); currentMITKIntensityImage->SetSlice((float*)m_ImageGrabber->GetOutput(2)->GetSliceData()->GetData(),0,0,0); mitk::Image::Pointer currentMITKAmplitudeImage = mitk::Image::New(); currentMITKAmplitudeImage->Initialize(FloatType, 2, dimensions); currentMITKAmplitudeImage->SetSlice((float*)m_ImageGrabber->GetOutput(1)->GetSliceData()->GetData(),0,0,0); mitk::Image::Pointer currentMITKDistanceImage = mitk::Image::New(); currentMITKDistanceImage->Initialize(FloatType, 2, dimensions); currentMITKDistanceImage->SetSlice((float*)m_ImageGrabber->GetOutput(0)->GetSliceData()->GetData(),0,0,0); // copy mitk images to OpenCV images if (m_ImageDepth==IPL_DEPTH_32F) { if (m_ImageType==1) { float* amplitudeFloatData = (float*)currentMITKAmplitudeImage->GetSliceData(0, 0, 0)->GetData(); memcpy(m_CurrentOpenCVAmplitudeImage->imageData,(unsigned char*)amplitudeFloatData,numOfPixel*sizeof(float)); cv::Mat image(m_CurrentOpenCVAmplitudeImage); return image; } else if (m_ImageType==2) { float* intensityFloatData = (float*)currentMITKIntensityImage->GetSliceData(0, 0, 0)->GetData(); memcpy(m_CurrentOpenCVIntensityImage->imageData,(unsigned char*)intensityFloatData,numOfPixel*sizeof(float)); cv::Mat image(m_CurrentOpenCVIntensityImage); return image; } else { float* distanceFloatData = (float*)currentMITKDistanceImage->GetSliceData(0, 0, 0)->GetData(); memcpy(m_CurrentOpenCVDistanceImage->imageData,(unsigned char*)distanceFloatData,numOfPixel*sizeof(float)); cv::Mat image(m_CurrentOpenCVDistanceImage); return image; } } else { if (m_ImageType==1) { this->MapScalars(currentMITKAmplitudeImage, m_CurrentOpenCVAmplitudeImage); cv::Mat image(m_CurrentOpenCVAmplitudeImage); return image; } else if (m_ImageType==2) { this->MapScalars(currentMITKIntensityImage, m_CurrentOpenCVIntensityImage); cv::Mat image(m_CurrentOpenCVIntensityImage); return image; } else { this->MapScalars(currentMITKDistanceImage, m_CurrentOpenCVDistanceImage); cv::Mat image(m_CurrentOpenCVDistanceImage); return image; } } } void ToFOpenCVImageGrabber::SetImageType(unsigned int imageType) { m_ImageType = imageType; } void ToFOpenCVImageGrabber::SetImageDepth(unsigned int imageDepth) { m_ImageDepth = imageDepth; } void ToFOpenCVImageGrabber::SetToFImageGrabber(ToFImageGrabber::Pointer imageGrabber) { m_ImageGrabber = imageGrabber; //initialize OpenCV images m_CurrentOpenCVIntensityImage = cvCreateImage(cvSize(m_ImageGrabber->GetCaptureWidth(), m_ImageGrabber->GetCaptureHeight()), m_ImageDepth, 1); m_CurrentOpenCVAmplitudeImage = cvCreateImage(cvSize(m_ImageGrabber->GetCaptureWidth(), m_ImageGrabber->GetCaptureHeight()), m_ImageDepth, 1); m_CurrentOpenCVDistanceImage = cvCreateImage(cvSize(m_ImageGrabber->GetCaptureWidth(), m_ImageGrabber->GetCaptureHeight()), m_ImageDepth, 1); } ToFImageGrabber::Pointer ToFOpenCVImageGrabber::GetToFImageGrabber() { return m_ImageGrabber; } void ToFOpenCVImageGrabber::StartCapturing() { if (m_ImageGrabber.IsNotNull()) { m_ImageGrabber->ConnectCamera(); m_ImageGrabber->StartCamera(); } } void ToFOpenCVImageGrabber::StopCapturing() { if (m_ImageGrabber.IsNotNull()) { m_ImageGrabber->StopCamera(); m_ImageGrabber->DisconnectCamera(); } } void ToFOpenCVImageGrabber::MapScalars( mitk::Image::Pointer mitkImage, IplImage* openCVImage) { unsigned int numOfPixel = m_ImageGrabber->GetCaptureWidth()*m_ImageGrabber->GetCaptureHeight(); float* floatData = (float*)mitkImage->GetSliceData(0, 0, 0)->GetData(); vtkSmartPointer colorTransferFunction = vtkColorTransferFunction::New(); vtkSmartPointer floatArrayInt; floatArrayInt = vtkFloatArray::New(); floatArrayInt->Initialize(); floatArrayInt->SetArray(floatData, numOfPixel, 0); - mitk::ScalarType min = mitkImage->GetScalarValueMin(); - mitk::ScalarType max = mitkImage->GetScalarValueMaxNoRecompute(); + mitk::ScalarType min = mitkImage->GetStatistics()->GetScalarValueMin(); + mitk::ScalarType max = mitkImage->GetStatistics()->GetScalarValueMaxNoRecompute(); MITK_INFO<<"Minimum: "<RemoveAllPoints(); colorTransferFunction->AddRGBPoint(min, 0, 0, 0); colorTransferFunction->AddRGBPoint(max, 1, 1, 1); colorTransferFunction->SetColorSpaceToHSV(); //TODO other depth values colorTransferFunction->MapScalarsThroughTable(floatArrayInt, (unsigned char*)openCVImage->imageData, VTK_LUMINANCE); } } diff --git a/Modules/ToFHardware/mitkToFPicImageWriter.cpp b/Modules/ToFHardware/mitkToFPicImageWriter.cpp deleted file mode 100644 index 3ff34395b4..0000000000 --- a/Modules/ToFHardware/mitkToFPicImageWriter.cpp +++ /dev/null @@ -1,203 +0,0 @@ -/*=================================================================== - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center, -Division of Medical and Biological Informatics. -All rights reserved. - -This software is distributed WITHOUT ANY WARRANTY; without -even the implied warranty of MERCHANTABILITY or FITNESS FOR -A PARTICULAR PURPOSE. - -See LICENSE.txt or http://www.mitk.org for details. - -===================================================================*/ -#include -#include -#include - -// deprecated support of mitkIpPic -#include - -// itk includes -#include "itksys/SystemTools.hxx" - -extern "C" -{ -size_t _mitkIpPicFWrite( const void *ptr, size_t size, size_t nitems, mitkIpPicFile_t stream); -} - -namespace mitk -{ - ToFPicImageWriter::ToFPicImageWriter(): ToFImageWriter(), m_DistanceOutfile(NULL), - m_AmplitudeOutfile(NULL), m_IntensityOutfile(NULL) - { - m_Extension = std::string(".pic"); - } - - ToFPicImageWriter::~ToFPicImageWriter() - { - } - - void ToFPicImageWriter::Open() - { - this->CheckForFileExtension(this->m_DistanceImageFileName); - this->CheckForFileExtension(this->m_AmplitudeImageFileName); - this->CheckForFileExtension(this->m_IntensityImageFileName); - - this->m_PixelNumber = this->m_CaptureWidth * this->m_CaptureHeight; - this->m_ImageSizeInBytes = this->m_PixelNumber * sizeof(float); - float* floatData = new float[this->m_PixelNumber]; - for(int i=0; im_PixelNumber; i++) - { - floatData[i] = i + 0.0; - } - - this->m_MitkImage = Image::New(); - unsigned int dimensions[4]; - dimensions[0] = this->m_CaptureWidth; - dimensions[1] = this->m_CaptureHeight; - - mitk::PixelType FloatType = MakeScalarPixelType(); - if (this->m_ToFImageType == ToFImageWriter::ToFImageType2DPlusT) - { - dimensions[2] = 1; - dimensions[3] = 2; - this->m_MitkImage->Initialize( FloatType, 4, dimensions, 1); - } - else - { - dimensions[2] = 2; - dimensions[3] = 1; - this->m_MitkImage->Initialize( FloatType, 3, dimensions, 1); - } - this->m_MitkImage->SetSlice(floatData, 0, 0, 0); - - mitkIpPicDescriptor* pic = mitkIpPicNew(); - CastToIpPicDescriptor( this->m_MitkImage, pic); - - if (this->m_DistanceImageSelected) - { - this->OpenPicFile(&(this->m_DistanceOutfile), this->m_DistanceImageFileName); - this->WritePicFileHeader(this->m_DistanceOutfile, pic); - } - if (this->m_AmplitudeImageSelected) - { - this->OpenPicFile(&(this->m_AmplitudeOutfile), this->m_AmplitudeImageFileName); - this->WritePicFileHeader(this->m_AmplitudeOutfile, pic); - } - if (this->m_IntensityImageSelected) - { - this->OpenPicFile(&(this->m_IntensityOutfile), this->m_IntensityImageFileName); - this->WritePicFileHeader(this->m_IntensityOutfile, pic); - } - this->m_NumOfFrames = 0; - delete[] floatData; - } - - void ToFPicImageWriter::Close() - { - if (this->m_DistanceImageSelected) - { - this->ClosePicFile(this->m_DistanceOutfile); - } - if (this->m_AmplitudeImageSelected) - { - this->ClosePicFile(this->m_AmplitudeOutfile); - } - if (this->m_IntensityImageSelected) - { - this->ClosePicFile(this->m_IntensityOutfile); - } - } - - void ToFPicImageWriter::Add(float* distanceFloatData, float* amplitudeFloatData, float* intensityFloatData) - { - if (this->m_DistanceImageSelected) - { - fwrite( distanceFloatData, this->m_ImageSizeInBytes, 1, this->m_DistanceOutfile ); - } - if (this->m_AmplitudeImageSelected) - { - fwrite( amplitudeFloatData, this->m_ImageSizeInBytes, 1, this->m_AmplitudeOutfile ); - } - if (this->m_IntensityImageSelected) - { - fwrite( intensityFloatData, this->m_ImageSizeInBytes, 1, this->m_IntensityOutfile ); - } - this->m_NumOfFrames++; - } - - void ToFPicImageWriter::OpenPicFile(FILE** outfile,std::string outfileName) - { - (*outfile) = fopen( outfileName.c_str(), "w+b" ); - if( !outfile ) // if fopen_s was not successful! - { - MITK_ERROR << "Error opening outfile: " << outfileName; - throw std::logic_error("Error opening outfile."); - return; - } - } - - void ToFPicImageWriter::ClosePicFile(FILE* outfile) - { - if (this->m_NumOfFrames == 0) - { - fclose(outfile); - throw std::logic_error("File is empty."); - return; - } - this->ReplacePicFileHeader(outfile); - fclose(outfile); - } - - void ToFPicImageWriter::ReplacePicFileHeader(FILE* outfile) - { - mitkIpPicDescriptor* pic = mitkIpPicNew(); - CastToIpPicDescriptor( this->m_MitkImage, pic); - - if (this->m_ToFImageType == ToFImageWriter::ToFImageType2DPlusT) - { - pic->dim = 4; - pic->n[2] = 1; - pic->n[3] = this->m_NumOfFrames; - } - else - { - pic->dim = 3; - pic->n[2] = this->m_NumOfFrames; - pic->n[3] = 1; - } - - fseek ( outfile, 0, SEEK_SET ); - - this->WritePicFileHeader( outfile, pic ); - } - - void ToFPicImageWriter::WritePicFileHeader(FILE* outfile, mitkIpPicDescriptor* pic) - { - mitkIpUInt4_t len; - mitkIpUInt4_t tagsLen; - - tagsLen = _mitkIpPicTagsSize( pic->info->tags_head ); - len = tagsLen + 3 * sizeof(mitkIpUInt4_t) + pic->dim * sizeof(mitkIpUInt4_t); - /* write oufile */ - if( mitkIpPicEncryptionType(pic) == ' ' ) - mitkIpPicFWrite( mitkIpPicVERSION, 1, sizeof(mitkIpPicTag_t), outfile ); - else - mitkIpPicFWrite( pic->info->version, 1, sizeof(mitkIpPicTag_t), outfile ); - - mitkIpPicFWriteLE( &len, sizeof(mitkIpUInt4_t), 1, outfile ); - - mitkIpPicFWriteLE( &(pic->type), sizeof(mitkIpUInt4_t), 1, outfile ); - mitkIpPicFWriteLE( &(pic->bpe), sizeof(mitkIpUInt4_t), 1, outfile ); - mitkIpPicFWriteLE( &(pic->dim), sizeof(mitkIpUInt4_t), 1, outfile ); - - mitkIpPicFWriteLE( pic->n, sizeof(mitkIpUInt4_t), pic->dim, outfile ); - - _mitkIpPicWriteTags( pic->info->tags_head, outfile, mitkIpPicEncryptionType(pic) ); - pic->info->pixel_start_in_file = ftell( outfile ); - } - -} // end namespace mitk diff --git a/Modules/ToFHardware/mitkToFPicImageWriter.h b/Modules/ToFHardware/mitkToFPicImageWriter.h deleted file mode 100644 index c762e14106..0000000000 --- a/Modules/ToFHardware/mitkToFPicImageWriter.h +++ /dev/null @@ -1,89 +0,0 @@ -/*=================================================================== - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center, -Division of Medical and Biological Informatics. -All rights reserved. - -This software is distributed WITHOUT ANY WARRANTY; without -even the implied warranty of MERCHANTABILITY or FITNESS FOR -A PARTICULAR PURPOSE. - -See LICENSE.txt or http://www.mitk.org for details. - -===================================================================*/ -#ifndef __mitkToFPicImageWriter_h -#define __mitkToFPicImageWriter_h - -#include "mitkToFHardwareExports.h" -#include "mitkToFImageWriter.h" - -#include - -namespace mitk -{ - /** - * @brief Writer class for ToF images - * - * This writer class allows streaming of ToF data into a file. The .pic file format is used for writing the data. - * Image information is included in the header of the pic file. - * Writer can simultaneously save "distance", "intensity" and "amplitude" image. - * Images can be written as 3D volume (ToFImageType::ToFImageType3D) or temporal image stack (ToFImageType::ToFImageType2DPlusT) - * - * @ingroup ToFHardware - */ - class MITK_TOFHARDWARE_EXPORT ToFPicImageWriter : public ToFImageWriter - { - public: - - ToFPicImageWriter(); - - ~ToFPicImageWriter(); - - mitkClassMacro( ToFPicImageWriter , ToFImageWriter ); - itkNewMacro( Self ); - - /*! - \brief Open file(s) for writing - */ - void Open(); - /*! - \brief Close file(s) add .pic header and write - */ - void Close(); - /*! - \brief Add new data to file. - */ - void Add(float* distanceFloatData, float* amplitudeFloatData, float* intensityFloatData); - - protected: - - Image::Pointer m_MitkImage; ///< mitk image used for pic header creation - FILE* m_DistanceOutfile; ///< file for distance image - FILE* m_AmplitudeOutfile; ///< file for amplitude image - FILE* m_IntensityOutfile; ///< file for intensity image - - - private: - - /*! - \brief Open file by filename to gain write access to it. - */ - void OpenPicFile(FILE** outfile, std::string outfileName); - /*! - \brief Close file after work on it is finished. - */ - void ClosePicFile(FILE* outfile); - /*! - \brief Replace current PicFileHeader information. - */ - void ReplacePicFileHeader(FILE* outfile); - /*! - \brief Write image information to the PicFileHeader. - */ - void WritePicFileHeader(FILE* outfile, mitkIpPicDescriptor* pic); - - }; -} //END mitk namespace -#endif // __mitkToFPicImageWriter_h diff --git a/Modules/ToFUI/Qmitk/QmitkKinectParameterWidget.cpp b/Modules/ToFUI/Qmitk/QmitkKinectParameterWidget.cpp new file mode 100644 index 0000000000..f36ea96cad --- /dev/null +++ b/Modules/ToFUI/Qmitk/QmitkKinectParameterWidget.cpp @@ -0,0 +1,90 @@ +/*========================================================================= + +Program: Medical Imaging & Interaction Toolkit +Module: $RCSfile$ +Language: C++ +Date: $Date: 2009-05-20 13:35:09 +0200 (Mi, 20 Mai 2009) $ +Version: $Revision: 17332 $ + +Copyright (c) German Cancer Research Center, Division of Medical and +Biological Informatics. All rights reserved. +See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. + +This software is distributed WITHOUT ANY WARRANTY; without even +the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the above copyright notices for more information. + +=========================================================================*/ + +#include + +const std::string QmitkKinectParameterWidget::VIEW_ID = "org.mitk.views.qmitkkinectparameterwidget"; + +QmitkKinectParameterWidget::QmitkKinectParameterWidget(QWidget* p, Qt::WindowFlags f): QWidget(p, f) +{ + m_ToFImageGrabber = NULL; + m_Controls = NULL; + CreateQtPartControl(this); +} + +QmitkKinectParameterWidget::~QmitkKinectParameterWidget() +{ +} + +void QmitkKinectParameterWidget::CreateQtPartControl(QWidget *parent) +{ + if (!m_Controls) + { + // create GUI widgets + m_Controls = new Ui::QmitkKinectParameterWidgetControls; + m_Controls->setupUi(parent); + + this->CreateConnections(); + } +} + +void QmitkKinectParameterWidget::CreateConnections() +{ + if ( m_Controls ) + { + connect( m_Controls->m_RGB, SIGNAL(toggled(bool)), this, SLOT(OnAcquisitionModeChanged()) ); + connect( m_Controls->m_IR, SIGNAL(toggled(bool)), this, SLOT(OnAcquisitionModeChanged()) ); + } +} + +mitk::ToFImageGrabber* QmitkKinectParameterWidget::GetToFImageGrabber() +{ + return this->m_ToFImageGrabber; +} + +void QmitkKinectParameterWidget::SetToFImageGrabber(mitk::ToFImageGrabber* aToFImageGrabber) +{ + this->m_ToFImageGrabber = aToFImageGrabber; +} + +void QmitkKinectParameterWidget::ActivateAllParameters() +{ + this->OnAcquisitionModeChanged(); +} + +void QmitkKinectParameterWidget::OnAcquisitionModeChanged() +{ + if (m_ToFImageGrabber.IsNotNull()) + { + // stop camera if active + bool active = m_ToFImageGrabber->IsCameraActive(); + if (active) + { + m_ToFImageGrabber->StopCamera(); + m_ToFImageGrabber->DisconnectCamera(); + } + this->m_ToFImageGrabber->SetBoolProperty("RGB", m_Controls->m_RGB->isChecked()); + this->m_ToFImageGrabber->SetBoolProperty("IR", m_Controls->m_IR->isChecked()); + if (active) + { + m_ToFImageGrabber->ConnectCamera(); + m_ToFImageGrabber->StartCamera(); + } + } +} + diff --git a/Modules/ToFUI/Qmitk/QmitkKinectParameterWidget.h b/Modules/ToFUI/Qmitk/QmitkKinectParameterWidget.h new file mode 100644 index 0000000000..d46b43b63b --- /dev/null +++ b/Modules/ToFUI/Qmitk/QmitkKinectParameterWidget.h @@ -0,0 +1,80 @@ +/*========================================================================= + +Program: Medical Imaging & Interaction Toolkit +Module: $RCSfile$ +Language: C++ +Date: $Date: 2009-05-20 13:35:09 +0200 (Mi, 20 Mai 2009) $ +Version: $Revision: 17332 $ + +Copyright (c) German Cancer Research Center, Division of Medical and +Biological Informatics. All rights reserved. +See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. + +This software is distributed WITHOUT ANY WARRANTY; without even +the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the above copyright notices for more information. + +=========================================================================*/ + +#ifndef _QMITKKINECTPARAMETERWIDGET_H_INCLUDED +#define _QMITKKINECTPARAMETERWIDGET_H_INCLUDED + +#include "mitkTOFUIExports.h" +#include "ui_QmitkKinectParameterWidgetControls.h" + +//mitk headers +#include + +#include + +/** +* @brief Widget for configuring the Kinect device +* +* @ingroup ToFUI +*/ +class mitkTOFUI_EXPORT QmitkKinectParameterWidget :public QWidget +{ + //this is needed for all Qt objects that should have a MOC object (everything that derives from QObject) + Q_OBJECT + + public: + + static const std::string VIEW_ID; + + QmitkKinectParameterWidget(QWidget* p = 0, Qt::WindowFlags f = 0); + virtual ~QmitkKinectParameterWidget(); + + /* @brief This method is part of the widget an needs not to be called seperately. */ + virtual void CreateQtPartControl(QWidget *parent); + /* @brief This method is part of the widget an needs not to be called seperately. (Creation of the connections of main and control widget.)*/ + virtual void CreateConnections(); + + /*! + \brief returns the ToFImageGrabber + \return ToFImageGrabber currently used by the widget + */ + mitk::ToFImageGrabber* GetToFImageGrabber(); + + /*! + \brief sets the ToFImageGrabber + */ + void SetToFImageGrabber(mitk::ToFImageGrabber* aToFImageGrabber); + + /*! + \brief activate camera settings according to the parameters from GUI + */ + void ActivateAllParameters(); + + protected slots: + void OnAcquisitionModeChanged(); + + protected: + + Ui::QmitkKinectParameterWidgetControls* m_Controls; ///< member holding the UI elements of this widget + + mitk::ToFImageGrabber::Pointer m_ToFImageGrabber; ///< image grabber object to be configured by the widget + + private: +}; + +#endif // _QmitkKinectParameterWIDGET_H_INCLUDED diff --git a/Modules/ToFUI/Qmitk/QmitkKinectParameterWidgetControls.ui b/Modules/ToFUI/Qmitk/QmitkKinectParameterWidgetControls.ui new file mode 100644 index 0000000000..02ff87e5d0 --- /dev/null +++ b/Modules/ToFUI/Qmitk/QmitkKinectParameterWidgetControls.ui @@ -0,0 +1,73 @@ + + + QmitkKinectParameterWidgetControls + + + + 0 + 0 + 425 + 76 + + + + + 0 + 0 + + + + QmitkToFMESAParameter + + + + + + + 0 + 0 + + + + Kinect Camera Parameter + + + + + + Acquisition mode: + + + + + + + Acquire RGB and range image + + + RGB + + + true + + + + + + + Acquire infrared (IR) and range image + + + IR + + + + + + + + + + + + diff --git a/Modules/ToFUI/Qmitk/QmitkToFConnectionWidget.cpp b/Modules/ToFUI/Qmitk/QmitkToFConnectionWidget.cpp index d5b510deeb..0c9bb8caaf 100644 --- a/Modules/ToFUI/Qmitk/QmitkToFConnectionWidget.cpp +++ b/Modules/ToFUI/Qmitk/QmitkToFConnectionWidget.cpp @@ -1,350 +1,344 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ //#define _USE_MATH_DEFINES #include //QT headers #include #include #include //mitk headers #include "mitkToFConfig.h" #include "mitkToFCameraPMDCamCubeDevice.h" #include "mitkToFCameraPMDRawDataCamCubeDevice.h" #include "mitkToFCameraPMDCamBoardDevice.h" #include "mitkToFCameraPMDRawDataCamBoardDevice.h" #include "mitkToFCameraPMDO3Device.h" #include "mitkToFCameraPMDPlayerDevice.h" #include "mitkToFCameraPMDMITKPlayerDevice.h" #include "mitkToFCameraMITKPlayerDevice.h" #include "mitkToFCameraMESASR4000Device.h" +#include "mitkKinectDevice.h" //itk headers #include const std::string QmitkToFConnectionWidget::VIEW_ID = "org.mitk.views.qmitktofconnectionwidget"; QmitkToFConnectionWidget::QmitkToFConnectionWidget(QWidget* parent, Qt::WindowFlags f): QWidget(parent, f) { this->m_IntegrationTime = 0; this->m_ModulationFrequency = 0; this->m_ToFImageGrabber = mitk::ToFImageGrabber::New(); m_Controls = NULL; CreateQtPartControl(this); } QmitkToFConnectionWidget::~QmitkToFConnectionWidget() { } void QmitkToFConnectionWidget::CreateQtPartControl(QWidget *parent) { if (!m_Controls) { // create GUI widgets m_Controls = new Ui::QmitkToFConnectionWidgetControls; m_Controls->setupUi(parent); this->CreateConnections(); // set available cameras to combo box QString string(MITK_TOF_CAMERAS); string.replace(";"," "); QStringList list = string.split(","); m_Controls->m_SelectCameraCombobox->addItems(list); ShowParameterWidget(); } } void QmitkToFConnectionWidget::CreateConnections() { if ( m_Controls ) { connect( (QObject*)(m_Controls->m_ConnectCameraButton), SIGNAL(clicked()),(QObject*) this, SLOT(OnConnectCamera()) ); connect( m_Controls->m_SelectCameraCombobox, SIGNAL(currentIndexChanged(const QString)), this, SLOT(OnSelectCamera(const QString)) ); connect( m_Controls->m_SelectCameraCombobox, SIGNAL(activated(const QString)), this, SLOT(OnSelectCamera(const QString)) ); connect( m_Controls->m_SelectCameraCombobox, SIGNAL(activated(const QString)), this, SIGNAL(ToFCameraSelected(const QString)) ); } } void QmitkToFConnectionWidget::ShowParameterWidget() { QString selectedCamera = m_Controls->m_SelectCameraCombobox->currentText(); - if ((selectedCamera == "PMD CamCube 2.0/3.0")||(selectedCamera == "PMD CamBoard")||(selectedCamera=="PMD O3D")|| - (selectedCamera=="PMD CamBoardRaw")||(selectedCamera=="PMD CamCubeRaw") ) - { - ShowPMDParameterWidget(); - } - else if (selectedCamera=="MESA Swissranger 4000") - { - ShowMESAParameterWidget(); - } - else - { - this->m_Controls->m_PMDParameterWidget->hide(); - this->m_Controls->m_MESAParameterWidget->hide(); - } -} - -void QmitkToFConnectionWidget::ShowPMDParameterWidget() -{ - this->m_Controls->m_PMDParameterWidget->show(); - this->m_Controls->m_MESAParameterWidget->hide(); -} - -void QmitkToFConnectionWidget::ShowMESAParameterWidget() -{ - this->m_Controls->m_PMDParameterWidget->hide(); - this->m_Controls->m_MESAParameterWidget->show(); -} - -void QmitkToFConnectionWidget::ShowPlayerParameterWidget() -{ - this->m_Controls->m_PMDParameterWidget->hide(); - this->m_Controls->m_MESAParameterWidget->hide(); + this->OnSelectCamera(selectedCamera); } mitk::ToFImageGrabber* QmitkToFConnectionWidget::GetToFImageGrabber() { return m_ToFImageGrabber; } -void QmitkToFConnectionWidget::OnSelectCamera(const QString selectedText) +void QmitkToFConnectionWidget::OnSelectCamera(const QString selectedCamera) { - if (selectedText == "PMD CamCube 2.0/3.0" || selectedText == "PMD CamCubeRaw 2.0/3.0" ) // PMD camcube 2 - { - ShowPMDParameterWidget(); - } - else if (selectedText == "PMD CamBoard" || selectedText == "PMD CamBoardRaw" ) // pmd camboard - { - ShowPMDParameterWidget(); - } - else if (selectedText == "PMD O3D") // pmd O3d - { - ShowPMDParameterWidget(); - } - else if (selectedText == "MESA Swissranger 4000") // MESA 4000 + if ((selectedCamera == "PMD CamCube 2.0/3.0")||(selectedCamera == "PMD CamBoard")||(selectedCamera=="PMD O3D")|| + (selectedCamera=="PMD CamBoardRaw")||(selectedCamera=="PMD CamCubeRaw 2.0/3.0") ) { - ShowMESAParameterWidget(); + this->m_Controls->m_PMDParameterWidget->show(); + this->m_Controls->m_MESAParameterWidget->hide(); + this->m_Controls->m_KinectParameterWidget->hide(); } - else if (selectedText == "PMD Player") // pmd file player + else if (selectedCamera=="MESA Swissranger 4000") { - ShowPlayerParameterWidget(); + this->m_Controls->m_PMDParameterWidget->hide(); + this->m_Controls->m_MESAParameterWidget->show(); + this->m_Controls->m_KinectParameterWidget->hide(); } - else if (selectedText == "PMD Raw Data Player") // pmd raw data player + else if (selectedCamera=="Microsoft Kinect") { - ShowPlayerParameterWidget(); + this->m_Controls->m_PMDParameterWidget->hide(); + this->m_Controls->m_MESAParameterWidget->hide(); + this->m_Controls->m_KinectParameterWidget->show(); } - else if (selectedText == "MITK Player") // mitk player + else { - ShowPlayerParameterWidget(); + this->m_Controls->m_PMDParameterWidget->hide(); + this->m_Controls->m_MESAParameterWidget->hide(); + this->m_Controls->m_KinectParameterWidget->hide(); } } void QmitkToFConnectionWidget::OnConnectCamera() { bool playerMode = false; if (m_Controls->m_ConnectCameraButton->text()=="Connect") { //reset the status of the GUI buttons m_Controls->m_ConnectCameraButton->setEnabled(false); m_Controls->m_SelectCameraCombobox->setEnabled(false); //repaint the widget this->repaint(); QString tmpFileName(""); QString fileFilter(""); //select the camera to connect with QString selectedCamera = m_Controls->m_SelectCameraCombobox->currentText(); if (selectedCamera == "PMD CamCube 2.0/3.0") { //PMD CamCube this->m_ToFImageGrabber->SetCameraDevice(mitk::ToFCameraPMDCamCubeDevice::New()); } else if (selectedCamera == "PMD CamCubeRaw 2.0/3.0") { //PMD CamCube this->m_ToFImageGrabber->SetCameraDevice(mitk::ToFCameraPMDRawDataCamCubeDevice::New()); } else if (selectedCamera == "PMD CamBoard") { //PMD CamBoard this->m_ToFImageGrabber->SetCameraDevice(mitk::ToFCameraPMDCamBoardDevice::New()); } else if (selectedCamera == "PMD CamBoardRaw") { //PMD CamBoard this->m_ToFImageGrabber->SetCameraDevice(mitk::ToFCameraPMDRawDataCamBoardDevice::New()); } else if (selectedCamera == "PMD O3D") {//PMD O3 this->m_ToFImageGrabber->SetCameraDevice(mitk::ToFCameraPMDO3Device::New()); } else if (selectedCamera == "MESA Swissranger 4000") {//MESA SR4000 this->m_ToFImageGrabber->SetCameraDevice(mitk::ToFCameraMESASR4000Device::New()); - } + } + else if (selectedCamera == "Microsoft Kinect") + {//KINECT + this->m_ToFImageGrabber->SetCameraDevice(mitk::KinectDevice::New()); + } else if (selectedCamera == "PMD Player") {//PMD player playerMode = true; fileFilter.append("PMD Files (*.pmd)"); this->m_ToFImageGrabber->SetCameraDevice(mitk::ToFCameraPMDPlayerDevice::New()); } else if (selectedCamera == "PMD Raw Data Player") {//PMD MITK player playerMode = true; fileFilter.append("NRRD Images (*.nrrd);;PIC Images - deprecated (*.pic)"); this->m_ToFImageGrabber->SetCameraDevice(mitk::ToFCameraPMDRawDataDevice::New()); } else if (selectedCamera == "MITK Player") {//MITK player playerMode = true; fileFilter.append("NRRD Images (*.nrrd);;PIC Images - deprecated (*.pic)"); this->m_ToFImageGrabber->SetCameraDevice(mitk::ToFCameraMITKPlayerDevice::New()); } // if a player was selected ... if (playerMode) { //... open a QFileDialog to chose the corresponding file from the disc tmpFileName = QFileDialog::getOpenFileName(NULL, "Play Image From...", "", fileFilter); if (tmpFileName.isEmpty()) { m_Controls->m_ConnectCameraButton->setChecked(false); m_Controls->m_ConnectCameraButton->setEnabled(true); m_Controls->m_SelectCameraCombobox->setEnabled(true); this->OnSelectCamera(m_Controls->m_SelectCameraCombobox->currentText()); QMessageBox::information( this, "Template functionality", "Please select a valid image before starting some action."); return; } if(selectedCamera == "PMD Player") { //set the PMD file name this->m_ToFImageGrabber->SetStringProperty("PMDFileName", tmpFileName.toStdString().c_str() ); } if (selectedCamera == "PMD Raw Data Player" || selectedCamera == "MITK Player") { std::string msg = ""; try { //get 3 corresponding file names std::string dir = itksys::SystemTools::GetFilenamePath( tmpFileName.toStdString() ); std::string baseFilename = itksys::SystemTools::GetFilenameWithoutLastExtension( tmpFileName.toStdString() ); std::string extension = itksys::SystemTools::GetFilenameLastExtension( tmpFileName.toStdString() ); if (extension != ".pic" && extension != ".nrrd") { msg = msg + "Invalid file format, please select a \".nrrd\"-file"; throw std::logic_error(msg.c_str()); } int found = baseFilename.rfind("_DistanceImage"); if (found == std::string::npos) { found = baseFilename.rfind("_AmplitudeImage"); } if (found == std::string::npos) { found = baseFilename.rfind("_IntensityImage"); } if (found == std::string::npos) { - msg = msg + "Input file name must end with \"_DistanceImage.pic\", \"_AmplitudeImage.pic\" or \"_IntensityImage.pic\"!"; + found = baseFilename.rfind("_RGBImage"); + } + if (found == std::string::npos) + { + msg = msg + "Input file name must end with \"_DistanceImage\", \"_AmplitudeImage\", \"_IntensityImage\" or \"_RGBImage\"!"; throw std::logic_error(msg.c_str()); } std::string baseFilenamePrefix = baseFilename.substr(0,found); std::string distanceImageFileName = dir + "/" + baseFilenamePrefix + "_DistanceImage" + extension; std::string amplitudeImageFileName = dir + "/" + baseFilenamePrefix + "_AmplitudeImage" + extension; std::string intensityImageFileName = dir + "/" + baseFilenamePrefix + "_IntensityImage" + extension; + std::string rgbImageFileName = dir + "/" + baseFilenamePrefix + "_RGBImage" + extension; if (!itksys::SystemTools::FileExists(distanceImageFileName.c_str(), true)) { - msg = msg + "Inputfile not exist! " + distanceImageFileName; - throw std::logic_error(msg.c_str()); + this->m_ToFImageGrabber->SetStringProperty("DistanceImageFileName", ""); + } + else + { + this->m_ToFImageGrabber->SetStringProperty("DistanceImageFileName", distanceImageFileName.c_str()); } if (!itksys::SystemTools::FileExists(amplitudeImageFileName.c_str(), true)) { - msg = msg + "Inputfile not exist! " + amplitudeImageFileName; - throw std::logic_error(msg.c_str()); + this->m_ToFImageGrabber->SetStringProperty("AmplitudeImageFileName", ""); + } + else + { + this->m_ToFImageGrabber->SetStringProperty("AmplitudeImageFileName", amplitudeImageFileName.c_str()); } if (!itksys::SystemTools::FileExists(intensityImageFileName.c_str(), true)) { - msg = msg + "Inputfile not exist! " + intensityImageFileName; - throw std::logic_error(msg.c_str()); + this->m_ToFImageGrabber->SetStringProperty("IntensityImageFileName", ""); + } + else + { + this->m_ToFImageGrabber->SetStringProperty("IntensityImageFileName", intensityImageFileName.c_str()); + } + if (!itksys::SystemTools::FileExists(rgbImageFileName.c_str(), true)) + { + this->m_ToFImageGrabber->SetStringProperty("RGBImageFileName", ""); + } + else + { + this->m_ToFImageGrabber->SetStringProperty("RGBImageFileName", rgbImageFileName.c_str()); } - //set the file names - this->m_ToFImageGrabber->SetStringProperty("DistanceImageFileName", distanceImageFileName.c_str()); - this->m_ToFImageGrabber->SetStringProperty("AmplitudeImageFileName", amplitudeImageFileName.c_str()); - this->m_ToFImageGrabber->SetStringProperty("IntensityImageFileName", intensityImageFileName.c_str()); - } catch (std::exception &e) { MITK_ERROR << e.what(); QMessageBox::critical( this, "Error", e.what() ); m_Controls->m_ConnectCameraButton->setChecked(false); m_Controls->m_ConnectCameraButton->setEnabled(true); m_Controls->m_SelectCameraCombobox->setEnabled(true); this->OnSelectCamera(m_Controls->m_SelectCameraCombobox->currentText()); return; } } } - //if a connection could be established - if (this->m_ToFImageGrabber->ConnectCamera()) - { - this->m_Controls->m_PMDParameterWidget->SetToFImageGrabber(this->m_ToFImageGrabber); - this->m_Controls->m_MESAParameterWidget->SetToFImageGrabber(this->m_ToFImageGrabber); - if ((selectedCamera == "PMD CamCube 2.0/3.0")||(selectedCamera == "PMD CamBoard")||(selectedCamera=="PMD O3D")|| + this->m_Controls->m_PMDParameterWidget->SetToFImageGrabber(this->m_ToFImageGrabber); + this->m_Controls->m_MESAParameterWidget->SetToFImageGrabber(this->m_ToFImageGrabber); + this->m_Controls->m_KinectParameterWidget->SetToFImageGrabber(this->m_ToFImageGrabber); + + if ((selectedCamera == "PMD CamCube 2.0/3.0")||(selectedCamera == "PMD CamBoard")||(selectedCamera=="PMD O3D")|| (selectedCamera=="PMD CamBoardRaw")||(selectedCamera=="PMD CamCubeRaw 2.0/3.0")) - { - this->m_Controls->m_PMDParameterWidget->ActivateAllParameters(); - } - else if (selectedCamera=="MESA Swissranger 4000") - { - this->m_Controls->m_MESAParameterWidget->ActivateAllParameters(); - } - m_Controls->m_ConnectCameraButton->setText("Disconnect"); + { + this->m_Controls->m_PMDParameterWidget->ActivateAllParameters(); + } + else if (selectedCamera=="MESA Swissranger 4000") + { + this->m_Controls->m_MESAParameterWidget->ActivateAllParameters(); + } + else if (selectedCamera=="Microsoft Kinect") + { + this->m_Controls->m_KinectParameterWidget->ActivateAllParameters(); + } + m_Controls->m_ConnectCameraButton->setText("Disconnect"); + //if a connection could be established + if (this->m_ToFImageGrabber->ConnectCamera()) + { // send connect signal to the caller functionality emit ToFCameraConnected(); } else { QMessageBox::critical( this, "Error", "Connection failed. Check if you have installed the latest driver for your system." ); m_Controls->m_ConnectCameraButton->setChecked(false); m_Controls->m_ConnectCameraButton->setEnabled(true); m_Controls->m_SelectCameraCombobox->setEnabled(true); this->OnSelectCamera(m_Controls->m_SelectCameraCombobox->currentText()); return; } m_Controls->m_ConnectCameraButton->setEnabled(true); } else if (m_Controls->m_ConnectCameraButton->text()=="Disconnect") { this->m_ToFImageGrabber->StopCamera(); this->m_ToFImageGrabber->DisconnectCamera(); m_Controls->m_ConnectCameraButton->setText("Connect"); m_Controls->m_SelectCameraCombobox->setEnabled(true); this->OnSelectCamera(m_Controls->m_SelectCameraCombobox->currentText()); // send disconnect signal to the caller functionality emit ToFCameraDisconnected(); } } diff --git a/Modules/ToFUI/Qmitk/QmitkToFConnectionWidget.h b/Modules/ToFUI/Qmitk/QmitkToFConnectionWidget.h index e37f61abb9..44a546bb21 100644 --- a/Modules/ToFUI/Qmitk/QmitkToFConnectionWidget.h +++ b/Modules/ToFUI/Qmitk/QmitkToFConnectionWidget.h @@ -1,109 +1,104 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #ifndef _QMITKTOFCONNECTIONWIDGET_H_INCLUDED #define _QMITKTOFCONNECTIONWIDGET_H_INCLUDED #include "mitkTOFUIExports.h" #include "ui_QmitkToFConnectionWidgetControls.h" //QT headers #include //mitk headers #include "mitkToFImageGrabber.h" /** * @brief Widget allowing to connect to different ToF / range cameras (located in module ToFProcessing) * * The widget basically allows to connect/disconnect to different ToF cameras * * @ingroup ToFUI */ class mitkTOFUI_EXPORT QmitkToFConnectionWidget :public QWidget { //this is needed for all Qt objects that should have a MOC object (everything that derives from QObject) Q_OBJECT public: static const std::string VIEW_ID; QmitkToFConnectionWidget(QWidget* p = 0, Qt::WindowFlags f1 = 0); virtual ~QmitkToFConnectionWidget(); /* @brief This method is part of the widget an needs not to be called seperately. */ virtual void CreateQtPartControl(QWidget *parent); /* @brief This method is part of the widget an needs not to be called seperately. (Creation of the connections of main and control widget.)*/ virtual void CreateConnections(); /*! \brief returns the ToFImageGrabber which was configured after selecting a camera / player \return ToFImageGrabber currently used by the widget */ mitk::ToFImageGrabber* GetToFImageGrabber(); signals: /*! \brief This signal is sent if the user has connected the TOF camera. * The ToFImageGrabber is now availiable if the method GetToFImageGrabber() is called. */ void ToFCameraConnected(); /*! \brief This signal is sent if the user has disconnect the TOF camera. */ void ToFCameraDisconnected(); /*! \brief signal that is emitted when a ToF camera is selected in the combo box */ void ToFCameraSelected(const QString selectedText); protected slots: /*! \brief slot called when the "Connect Camera" button was pressed * According to the selection in the camera combo box, the widget provides * the desired instance of the ToFImageGrabber */ void OnConnectCamera(); /*! \brief slot updating the GUI elements after the selection of the camera combo box has changed */ - void OnSelectCamera(const QString selectedText); + void OnSelectCamera(const QString selectedCamera); protected: Ui::QmitkToFConnectionWidgetControls* m_Controls; ///< member holding the UI elements of this widget mitk::ToFImageGrabber::Pointer m_ToFImageGrabber; ///< member holding the current ToFImageGrabber int m_IntegrationTime; ///< member for the current integration time of the ToF device int m_ModulationFrequency; ///< member for the current modulation frequency of the ToF device private: void ShowParameterWidget(); - void ShowPMDParameterWidget(); - - void ShowMESAParameterWidget(); - - void ShowPlayerParameterWidget(); }; #endif // _QMITKTOFCONNECTIONWIDGET_H_INCLUDED diff --git a/Modules/ToFUI/Qmitk/QmitkToFConnectionWidgetControls.ui b/Modules/ToFUI/Qmitk/QmitkToFConnectionWidgetControls.ui index d43807972c..6110dd201b 100644 --- a/Modules/ToFUI/Qmitk/QmitkToFConnectionWidgetControls.ui +++ b/Modules/ToFUI/Qmitk/QmitkToFConnectionWidgetControls.ui @@ -1,133 +1,142 @@ QmitkToFConnectionWidgetControls 0 0 405 - 124 + 139 0 0 QmitkToFConnection 11 ToF camera connection 0 0 0 50 10 -1 7 QComboBox::InsertAtBottom QComboBox::AdjustToContents true 0 50 10 Connect to camera Connect :/images/powerRed.png :/images/powerGreen.png:/images/powerRed.png 30 30 true + + + QmitkToFPMDParameterWidget QWidget
QmitkToFPMDParameterWidget.h
1
QmitkToFMESAParameterWidget QWidget
QmitkToFMESAParameterWidget.h
1
+ + QmitkKinectParameterWidget + QWidget +
QmitkKinectParameterWidget.h
+ 1 +
diff --git a/Modules/ToFUI/Qmitk/QmitkToFRecorderWidget.cpp b/Modules/ToFUI/Qmitk/QmitkToFRecorderWidget.cpp index 57efe61547..ccac7fe49f 100644 --- a/Modules/ToFUI/Qmitk/QmitkToFRecorderWidget.cpp +++ b/Modules/ToFUI/Qmitk/QmitkToFRecorderWidget.cpp @@ -1,396 +1,409 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #define _USE_MATH_DEFINES #include "QmitkToFRecorderWidget.h" //QT headers #include #include #include #include #include #include //mitk headers #include //itk headers #pragma GCC visibility push(default) #include #pragma GCC visibility pop #include struct QFileDialogArgs; class QFileDialogPrivate; const std::string QmitkToFRecorderWidget::VIEW_ID = "org.mitk.views.qmitktofrecorderwidget"; QmitkToFRecorderWidget::QmitkToFRecorderWidget(QWidget* parent, Qt::WindowFlags f): QWidget(parent, f) { this->m_ToFImageRecorder = NULL; this->m_ToFImageGrabber = NULL; this->m_RecordMode = mitk::ToFImageRecorder::PerFrames; this-> m_Controls = NULL; CreateQtPartControl(this); } QmitkToFRecorderWidget::~QmitkToFRecorderWidget() { } void QmitkToFRecorderWidget::CreateQtPartControl(QWidget *parent) { if (!m_Controls) { // create GUI widgets this->m_Controls = new Ui::QmitkToFRecorderWidgetControls; this->m_Controls->setupUi(parent); this->CreateConnections(); } } void QmitkToFRecorderWidget::CreateConnections() { if ( m_Controls ) { connect( (QObject*)(m_Controls->m_PlayButton), SIGNAL(clicked()),(QObject*) this, SLOT(OnPlay()) ); connect( (QObject*)(m_Controls->m_StopButton), SIGNAL(clicked()),(QObject*) this, SLOT(OnStop()) ); connect( (QObject*)(m_Controls->m_StartRecordingButton), SIGNAL(clicked()),(QObject*) this, SLOT(OnStartRecorder()) ); connect( (QObject*)(m_Controls->m_RecordModeComboBox), SIGNAL(currentIndexChanged(int)),(QObject*) this, SLOT(OnChangeRecordModeComboBox(int)) ); connect(this, SIGNAL(RecordingStopped()), this, SLOT(OnRecordingStopped()), Qt::BlockingQueuedConnection); } } void QmitkToFRecorderWidget::SetParameter(mitk::ToFImageGrabber* toFImageGrabber, mitk::ToFImageRecorder* toFImageRecorder) { this->m_ToFImageGrabber = toFImageGrabber; this->m_ToFImageRecorder = toFImageRecorder; this->m_StopRecordingCommand = CommandType::New(); this->m_StopRecordingCommand->SetCallbackFunction(this, &QmitkToFRecorderWidget::StopRecordingCallback); this->m_ToFImageRecorder->RemoveAllObservers(); this->m_ToFImageRecorder->AddObserver(itk::AbortEvent(), this->m_StopRecordingCommand); m_Controls->m_PlayButton->setChecked(false); m_Controls->m_PlayButton->setEnabled(true); m_Controls->m_StartRecordingButton->setChecked(false); m_Controls->m_RecorderGroupBox->setEnabled(true); } void QmitkToFRecorderWidget::StopRecordingCallback() { emit RecordingStopped(); } void QmitkToFRecorderWidget::ResetGUIToInitial() { m_Controls->m_PlayButton->setChecked(false); m_Controls->m_PlayButton->setEnabled(true); m_Controls->m_RecorderGroupBox->setEnabled(false); } void QmitkToFRecorderWidget::OnRecordingStopped() { m_Controls->m_StartRecordingButton->setChecked(false); m_Controls->m_RecorderGroupBox->setEnabled(true); } void QmitkToFRecorderWidget::OnStop() { StopCamera(); StopRecorder(); ResetGUIToInitial(); emit ToFCameraStopped(); } void QmitkToFRecorderWidget::OnPlay() { m_Controls->m_PlayButton->setChecked(true); m_Controls->m_PlayButton->setEnabled(false); m_Controls->m_RecorderGroupBox->setEnabled(true); this->repaint(); StartCamera(); emit ToFCameraStarted(); } void QmitkToFRecorderWidget::StartCamera() { bool ok = false; if (!m_ToFImageGrabber->IsCameraActive()) { m_ToFImageGrabber->StartCamera(); } } void QmitkToFRecorderWidget::StopCamera() { if( m_ToFImageGrabber.IsNotNull() ) m_ToFImageGrabber->StopCamera(); } void QmitkToFRecorderWidget::StopRecorder() { if( m_ToFImageRecorder.IsNotNull() ) { this->m_ToFImageRecorder->StopRecording(); } } void QmitkToFRecorderWidget::OnStartRecorder() { m_Controls->m_StartRecordingButton->setChecked(true); m_Controls->m_RecorderGroupBox->setEnabled(false); this->repaint(); int numOfFrames = m_Controls->m_NumOfFramesSpinBox->value(); try { bool fileOK = true; bool distanceImageSelected = true; bool amplitudeImageSelected = true; bool intensityImageSelected = true; + bool rgbImageSelected = true; bool rawDataSelected = false; QString tmpFileName(""); QString selectedFilter(""); QString imageFileName(""); mitk::ToFImageWriter::ToFImageType tofImageType; tmpFileName = QmitkToFRecorderWidget::getSaveFileName(tofImageType, - distanceImageSelected, amplitudeImageSelected, intensityImageSelected, rawDataSelected, + distanceImageSelected, amplitudeImageSelected, intensityImageSelected, rgbImageSelected, rawDataSelected, NULL, "Save Image To...", imageFileName, "NRRD Images (*.nrrd);;PIC Images - deprecated (*.pic);;Text (*.csv)", &selectedFilter); if (tmpFileName.isEmpty()) { fileOK = false; } else { imageFileName = tmpFileName; } if (fileOK) { std::string dir = itksys::SystemTools::GetFilenamePath( imageFileName.toStdString() ); std::string baseFilename = itksys::SystemTools::GetFilenameWithoutLastExtension( imageFileName.toStdString() ); std::string extension = itksys::SystemTools::GetFilenameLastExtension( imageFileName.toStdString() ); int integrationTime = this->m_ToFImageGrabber->GetIntegrationTime(); int modulationFreq = this->m_ToFImageGrabber->GetModulationFrequency(); QString integrationTimeStr; integrationTimeStr.setNum(integrationTime); QString modulationFreqStr; modulationFreqStr.setNum(modulationFreq); QString numOfFramesStr(""); if (this->m_RecordMode == mitk::ToFImageRecorder::PerFrames) { numOfFramesStr.setNum(numOfFrames); } std::string distImageFileName = prepareFilename(dir, baseFilename, modulationFreqStr.toStdString(), integrationTimeStr.toStdString(), numOfFramesStr.toStdString(), extension, "_DistanceImage"); MITK_INFO << "Save distance data to: " << distImageFileName; std::string amplImageFileName = prepareFilename(dir, baseFilename, modulationFreqStr.toStdString(), integrationTimeStr.toStdString(), numOfFramesStr.toStdString(), extension, "_AmplitudeImage"); MITK_INFO << "Save amplitude data to: " << amplImageFileName; - std::string intenImageFileName = prepareFilename(dir, baseFilename, modulationFreqStr.toStdString(), + std::string intenImageFileName = prepareFilename(dir, baseFilename, modulationFreqStr.toStdString(), integrationTimeStr.toStdString(), numOfFramesStr.toStdString(), extension, "_IntensityImage"); MITK_INFO << "Save intensity data to: " << intenImageFileName; + std::string rgbImageFileName = prepareFilename(dir, baseFilename, modulationFreqStr.toStdString(), + integrationTimeStr.toStdString(), numOfFramesStr.toStdString(), extension, "_RGBImage"); + MITK_INFO << "Save intensity data to: " << rgbImageFileName; + if (selectedFilter.compare("Text (*.csv)") == 0) { this->m_ToFImageRecorder->SetFileFormat(".csv"); } else if (selectedFilter.compare("PIC Images - deprecated (*.pic)") == 0) { //default this->m_ToFImageRecorder->SetFileFormat(".pic"); QMessageBox::warning(NULL, "Deprecated File Format!", "Please note that *.pic file format is deprecated and not longer supported! The suggested file format for images is *.nrrd!"); } else if (selectedFilter.compare("NRRD Images (*.nrrd)") == 0) { this->m_ToFImageRecorder->SetFileFormat(".nrrd"); } else { QMessageBox::warning(NULL, "Unsupported file format!", "Please specify one of the supported file formats *.nrrd, *.csv!"); return; } numOfFrames = m_Controls->m_NumOfFramesSpinBox->value(); this->m_ToFImageRecorder->SetDistanceImageFileName(distImageFileName); this->m_ToFImageRecorder->SetAmplitudeImageFileName(amplImageFileName); this->m_ToFImageRecorder->SetIntensityImageFileName(intenImageFileName); + this->m_ToFImageRecorder->SetRGBImageFileName(rgbImageFileName); this->m_ToFImageRecorder->SetToFImageType(tofImageType); this->m_ToFImageRecorder->SetDistanceImageSelected(distanceImageSelected); this->m_ToFImageRecorder->SetAmplitudeImageSelected(amplitudeImageSelected); this->m_ToFImageRecorder->SetIntensityImageSelected(intensityImageSelected); + this->m_ToFImageRecorder->SetRGBImageSelected(rgbImageSelected); this->m_ToFImageRecorder->SetRecordMode(this->m_RecordMode); this->m_ToFImageRecorder->SetNumOfFrames(numOfFrames); emit RecordingStarted(); this->m_ToFImageRecorder->StartRecording(); } else { this->OnRecordingStopped(); } } catch(std::exception& e) { QMessageBox::critical(NULL, "Error", QString(e.what())); this->OnRecordingStopped(); } } QString QmitkToFRecorderWidget::getSaveFileName(mitk::ToFImageWriter::ToFImageType& tofImageType, bool& distanceImageSelected, bool& amplitudeImageSelected, bool& intensityImageSelected, + bool& rgbImageSelected, bool& rawDataSelected, QWidget *parent, const QString &caption, const QString &dir, const QString &filter, QString *selectedFilter, QFileDialog::Options options ) { QString selectedFileName = ""; QComboBox* combo = new QComboBox; combo->addItem("3D"); combo->addItem("2D + t"); QHBoxLayout* checkBoxGroup = new QHBoxLayout(); QCheckBox* distanceImageCheckBox = new QCheckBox; distanceImageCheckBox->setText("Distance image"); distanceImageCheckBox->setChecked(true); QCheckBox* amplitudeImageCheckBox = new QCheckBox; amplitudeImageCheckBox->setText("Amplitude image"); amplitudeImageCheckBox->setChecked(true); QCheckBox* intensityImageCheckBox = new QCheckBox; intensityImageCheckBox->setText("Intensity image"); intensityImageCheckBox->setChecked(true); + QCheckBox* rgbImageCheckBox = new QCheckBox; + rgbImageCheckBox->setText("RGB image"); + rgbImageCheckBox->setChecked(true); QCheckBox* rawDataCheckBox = new QCheckBox; rawDataCheckBox->setText("Raw data"); rawDataCheckBox->setChecked(false); rawDataCheckBox->setEnabled(false); checkBoxGroup->addWidget(distanceImageCheckBox); checkBoxGroup->addWidget(amplitudeImageCheckBox); checkBoxGroup->addWidget(intensityImageCheckBox); + checkBoxGroup->addWidget(rgbImageCheckBox); checkBoxGroup->addWidget(rawDataCheckBox); QFileDialog* fileDialog = new QFileDialog(parent, caption, dir, filter); QLayout* layout = fileDialog->layout(); QGridLayout* gridbox = qobject_cast(layout); if (gridbox) { gridbox->addWidget(new QLabel("ToF-Image type:")); gridbox->addWidget(combo); int lastRow = gridbox->rowCount(); gridbox->addLayout(checkBoxGroup, lastRow, 0, 1, -1); } fileDialog->setLayout(gridbox); fileDialog->setAcceptMode(QFileDialog::AcceptSave); if (selectedFilter) { fileDialog->selectNameFilter(*selectedFilter); } if (fileDialog->exec() == QDialog::Accepted) { if (selectedFilter) { *selectedFilter = fileDialog->selectedFilter(); } if (combo->currentIndex() == 0) { tofImageType = mitk::ToFImageWriter::ToFImageType3D; } else { tofImageType = mitk::ToFImageWriter::ToFImageType2DPlusT; } distanceImageSelected = distanceImageCheckBox->isChecked(); amplitudeImageSelected = amplitudeImageCheckBox->isChecked(); intensityImageSelected = intensityImageCheckBox->isChecked(); + rgbImageSelected = rgbImageCheckBox->isChecked(); rawDataSelected = rawDataCheckBox->isChecked(); selectedFileName = fileDialog->selectedFiles().value(0); } delete fileDialog; return selectedFileName; } std::string QmitkToFRecorderWidget::prepareFilename(std::string dir, std::string baseFilename, std::string modulationFreq, std::string integrationTime, std::string numOfFrames, std::string extension, std::string imageType) { std::string filenName(""); filenName.append(dir); filenName.append("/"); filenName.append(baseFilename); filenName.append("_MF"); filenName.append(modulationFreq); filenName.append("_IT"); filenName.append(integrationTime); filenName.append("_"); filenName.append(numOfFrames); filenName.append("Images"); filenName.append(imageType); filenName.append(extension); return filenName; } void QmitkToFRecorderWidget::OnChangeRecordModeComboBox(int index) { if (index == 0) { this->m_RecordMode = mitk::ToFImageRecorder::PerFrames; m_Controls->m_NumOfFramesSpinBox->setEnabled(true); } else { this->m_RecordMode = mitk::ToFImageRecorder::Infinite; m_Controls->m_NumOfFramesSpinBox->setEnabled(false); } } diff --git a/Modules/ToFUI/Qmitk/QmitkToFRecorderWidget.h b/Modules/ToFUI/Qmitk/QmitkToFRecorderWidget.h index 2d17e76314..4ba1048a28 100644 --- a/Modules/ToFUI/Qmitk/QmitkToFRecorderWidget.h +++ b/Modules/ToFUI/Qmitk/QmitkToFRecorderWidget.h @@ -1,188 +1,189 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #ifndef _QMITKTOFRECORDERWIDGET_H_INCLUDED #define _QMITKTOFRECORDERWIDGET_H_INCLUDED #include #include //QT headers #include #include #include #include //itk headers #include "itkCommand.h" //mitk headers #include #include class QmitkStdMultiWidget; struct QFileDialogArgs; class QFileIconProvider; class QFileDialogPrivate; /** * @brief Widget allowing to play / record ToF data * * @ingroup ToFUI */ class mitkTOFUI_EXPORT QmitkToFRecorderWidget :public QWidget { //this is needed for all Qt objects that should have a MOC object (everything that derives from QObject) Q_OBJECT public: static const std::string VIEW_ID; QmitkToFRecorderWidget(QWidget* p = 0, Qt::WindowFlags f1 = 0); virtual ~QmitkToFRecorderWidget(); /* @brief This method is part of the widget an needs not to be called seperately. */ virtual void CreateQtPartControl(QWidget *parent); /* @brief This method is part of the widget an needs not to be called seperately. (Creation of the connections of main and control widget.)*/ virtual void CreateConnections(); /*! \brief Set the parameters used for this widget \param ToFImageGrabber image grabber providing images from a ToF device \param tofImageRecorder image recorder allowing to record ToF images */ void SetParameter(mitk::ToFImageGrabber* ToFImageGrabber, mitk::ToFImageRecorder* toFImageRecorder); /*! \brief resets the GUI elements to the initial state. Play button: enabled, Stop button: disabled, Recording box: disabled */ void ResetGUIToInitial(); signals: /*! \brief signal emitted when "Play" button is pressed */ void ToFCameraStarted(); /*! \brief signal emitted when "Stop" button is pressed */ void ToFCameraStopped(); /*! \brief signal emitted when recording is started */ void RecordingStarted(); /*! \brief signal emitted AbortEvent() in ToFImageRecorder is observed */ void RecordingStopped(); public slots: /*! \brief slot invoking to start the camera. Calls StartCamera() and emits ToFCameraStarted signal */ void OnPlay(); /*! \brief slot invoking to stop the camera and the recorder. Calls StopCamera() and StopRecorder and emits ToFCameraStarted signal. Resets GUI to initial state. */ void OnStop(); /*! \brief slot invoking to start the recording After letting the user chose a file location for the record, m_ImageRecorder->StartRecording() is inoved. */ void OnStartRecorder(); /*! \brief slot resetting the GUI elements of the recording box */ void OnRecordingStopped(); /*! \brief slot activating/deactivating "number of frames" spin box dependent on recording mode (PerFrame / Infinite) */ void OnChangeRecordModeComboBox(int index); protected: /*! \brief starts the camera by calling ToFImageGrabber::StartCamera() */ void StartCamera(); /*! \brief stops the camera by calling ToFImageGrabber::StopCamera() */ void StopCamera(); /*! \brief stops the recording by calling ToFImageRecorder::StopRecording() */ void StopRecorder(); /*! \brief emits RecordingStopped signal. */ void StopRecordingCallback(); /*! \brief adapted version of QFileDialog::getSaveFileName() The user is now asked to choose which images he wants to save (Distance and/or Intensity and/or Amplitude image) and which type the saved image should have (3D, 2D+t). */ static QString getSaveFileName(mitk::ToFImageWriter::ToFImageType& tofImageType, bool& distanceImageSelected, bool& amplitudeImageSelected, bool& intensityImageSelected, + bool& rgbImageSelected, bool& rawDataSelected, QWidget *parent = 0, const QString &caption = QString(), const QString &dir = QString(), const QString &filter = QString(), QString *selectedFilter = 0, QFileDialog::Options options = 0 ); /*! \brief method creating a filename from the given information \param dir directory to save the file \param baseFilename base file name entered by the user \param modulationFreq modulation frequency of the camera \param integrationTime integration time of the camera \param numOfFrames number of frames recorded \param extension file extension \param imageType type of image (DistanceImage, IntensityImage, AmplitudeImage) \return dir+"/"+baseFilename+"_MF"+modulationFreq+"_IT"+integrationTime+"_"+numOfFrames+"Images"+imageType+extension */ std::string prepareFilename(std::string dir, std::string baseFilename, std::string modulationFreq, std::string integrationTime, std::string numOfFrames, std::string extension, std::string imageType); Ui::QmitkToFRecorderWidgetControls* m_Controls; ///< member holding the UI elements of this widget mitk::ToFImageGrabber::Pointer m_ToFImageGrabber; ///< member holding the ToFImageGrabber for acquiring ToF images mitk::ToFImageRecorder::Pointer m_ToFImageRecorder; ///< member holding the recorder for ToF images mitk::ToFImageRecorder::RecordMode m_RecordMode; ///< member holding the RecordMode of the recorder (PerFrame / Infinite) typedef itk::SimpleMemberCommand CommandType; CommandType::Pointer m_StopRecordingCommand; ///< itkCommand for abort of recording private: }; #endif // _QMITKTOFRECORDERWIDGET_H_INCLUDED diff --git a/Modules/ToFUI/Qmitk/QmitkToFVisualisationSettingsWidget.cpp b/Modules/ToFUI/Qmitk/QmitkToFVisualisationSettingsWidget.cpp index 2cb454e029..cbcea58a39 100644 --- a/Modules/ToFUI/Qmitk/QmitkToFVisualisationSettingsWidget.cpp +++ b/Modules/ToFUI/Qmitk/QmitkToFVisualisationSettingsWidget.cpp @@ -1,359 +1,382 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "QmitkToFVisualisationSettingsWidget.h" +#include +#include +#include + //QT headers #include #include const std::string QmitkToFVisualisationSettingsWidget::VIEW_ID = "org.mitk.views.qmitktofvisualisationsettingswidget"; QmitkToFVisualisationSettingsWidget::QmitkToFVisualisationSettingsWidget(QWidget* parent, Qt::WindowFlags f): QWidget(parent, f) , m_Controls(NULL) , m_RangeSliderMin(0) , m_RangeSliderMax(0) -, m_MitkDistanceImage(NULL) -, m_MitkAmplitudeImage(NULL) -, m_MitkIntensityImage(NULL) +, m_MitkDistanceImageNode(NULL) +, m_MitkAmplitudeImageNode(NULL) +, m_MitkIntensityImageNode(NULL) , m_Widget1ColorTransferFunction(NULL) , m_Widget2ColorTransferFunction(NULL) , m_Widget3ColorTransferFunction(NULL) , m_Widget1TransferFunctionType(1) , m_Widget2TransferFunctionType(0) , m_Widget3TransferFunctionType(0) { CreateQtPartControl(this); } QmitkToFVisualisationSettingsWidget::~QmitkToFVisualisationSettingsWidget() { } void QmitkToFVisualisationSettingsWidget::CreateQtPartControl(QWidget *parent) { if (!m_Controls) { // create GUI widgets m_Controls = new Ui::QmitkToFVisualisationSettingsWidgetControls; m_Controls->setupUi(parent); this->CreateConnections(); } } void QmitkToFVisualisationSettingsWidget::CreateConnections() { if ( m_Controls ) { connect( (QObject*)(m_Controls->m_SelectWidgetCombobox), SIGNAL(currentIndexChanged(int)),(QObject*) this, SLOT(OnWidgetSelected(int)) ); connect( (QObject*)(m_Controls->m_SelectTransferFunctionTypeCombobox), SIGNAL(currentIndexChanged(int)),(QObject*) this, SLOT(OnTransferFunctionTypeSelected(int)) ); connect( (QObject*)(m_Controls->m_TransferFunctionResetButton), SIGNAL(clicked()),(QObject*) this, SLOT(OnTransferFunctionReset()) ); connect(m_Controls->m_XEditColor, SIGNAL(returnPressed()), this, SLOT(OnSetXValueColor())); connect(m_Controls->m_RangeSliderMaxEdit, SIGNAL(returnPressed()), this, SLOT(OnRangeSliderMaxChanged())); connect(m_Controls->m_RangeSliderMinEdit, SIGNAL(returnPressed()), this, SLOT(OnRangeSliderMinChanged())); connect(m_Controls->m_RangeSliderReset, SIGNAL(pressed()), this, SLOT(OnResetSlider())); connect(m_Controls->m_RangeSlider, SIGNAL(spanChanged(int, int) ),this, SLOT( OnSpanChanged(int , int ) )); QPlastiqueStyle *sliderStyle = new QPlastiqueStyle(); m_Controls->m_RangeSlider->setMaximum(2048); m_Controls->m_RangeSlider->setMinimum(-2048); m_Controls->m_RangeSlider->setHandleMovementMode(QxtSpanSlider::NoOverlapping); m_Controls->m_RangeSlider->setStyle(sliderStyle); m_Controls->m_ColorTransferFunctionCanvas->SetQLineEdits(m_Controls->m_XEditColor, 0); m_Controls->m_ColorTransferFunctionCanvas->SetTitle(""/*"Value -> Grayscale/Color"*/); } } void QmitkToFVisualisationSettingsWidget::OnSetXValueColor() { m_Controls->m_ColorTransferFunctionCanvas->SetX(m_Controls->m_XEditColor->text().toFloat()); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } void QmitkToFVisualisationSettingsWidget::OnRangeSliderMaxChanged() { m_Controls->m_RangeSlider->setMaximum(m_Controls->m_RangeSliderMaxEdit->text().toInt()); UpdateRanges(); m_Controls->m_ColorTransferFunctionCanvas->update(); } void QmitkToFVisualisationSettingsWidget::OnRangeSliderMinChanged() { m_Controls->m_RangeSlider->setMinimum(m_Controls->m_RangeSliderMinEdit->text().toInt()); UpdateRanges(); m_Controls->m_ColorTransferFunctionCanvas->update(); } void QmitkToFVisualisationSettingsWidget::OnSpanChanged(int /*lower*/, int /*upper*/) { UpdateRanges(); m_Controls->m_ColorTransferFunctionCanvas->update(); } void QmitkToFVisualisationSettingsWidget::OnResetSlider() { m_Controls->m_RangeSlider->setUpperValue(m_RangeSliderMax); m_Controls->m_RangeSlider->setLowerValue(m_RangeSliderMin); UpdateRanges(); m_Controls->m_ColorTransferFunctionCanvas->update(); } void QmitkToFVisualisationSettingsWidget::UpdateRanges() { int lower = m_Controls->m_RangeSlider->lowerValue(); int upper = m_Controls->m_RangeSlider->upperValue(); m_Controls->m_ColorTransferFunctionCanvas->SetMin(lower); m_Controls->m_ColorTransferFunctionCanvas->SetMax(upper); } -void QmitkToFVisualisationSettingsWidget::Initialize(mitk::Image* distanceImage, mitk::Image* amplitudeImage, mitk::Image* intensityImage) +void QmitkToFVisualisationSettingsWidget::Initialize(mitk::DataNode* distanceImageNode, mitk::DataNode* amplitudeImageNode, mitk::DataNode* intensityImageNode) { - this->m_MitkDistanceImage = distanceImage; - this->m_MitkAmplitudeImage = amplitudeImage; - this->m_MitkIntensityImage = intensityImage; - - if (!m_MitkDistanceImage && !m_MitkAmplitudeImage && !m_MitkIntensityImage) + this->m_MitkDistanceImageNode = distanceImageNode; + this->m_MitkAmplitudeImageNode = amplitudeImageNode; + this->m_MitkIntensityImageNode = intensityImageNode; + + // Initialize transfer functions for image DataNodes such that: + // Widget1 (Distance): color from red (2nd min) to blue (max) + // Widget2 (Amplitude): grey value from black (2nd min) to white (max) + // Widget3 (Intensity): grey value from black (2nd min) to white (max) + if (!m_MitkDistanceImageNode && !m_MitkAmplitudeImageNode && !m_MitkIntensityImageNode) { m_Controls->m_ColorTransferFunctionCanvas->setEnabled(false); } else { m_Controls->m_ColorTransferFunctionCanvas->setEnabled(true); int numberOfImages = 0; - if (m_MitkDistanceImage) + if (m_MitkDistanceImageNode) { - m_RangeSliderMin = distanceImage->GetScalarValueMin(); - m_RangeSliderMax = distanceImage->GetScalarValueMax(); - m_Widget1ColorTransferFunction = vtkColorTransferFunction::New(); this->m_Widget1TransferFunctionType = 1; m_Controls->m_SelectTransferFunctionTypeCombobox->setCurrentIndex(this->m_Widget1TransferFunctionType); - ResetTransferFunction(this->m_Widget1ColorTransferFunction, this->m_Widget1TransferFunctionType ,distanceImage->GetScalarValueMin(), distanceImage->GetScalarValueMax()); - UpdateCanvas(); - - int border = (m_RangeSliderMax - m_RangeSliderMin) * 0.1; - m_Controls->m_RangeSlider->setMinimum(m_RangeSliderMin - border); - m_Controls->m_RangeSlider->setMaximum(m_RangeSliderMax + border); - m_Controls->m_RangeSliderMinEdit->setText(QString("").setNum(m_RangeSliderMin - border)); - m_Controls->m_RangeSliderMaxEdit->setText(QString("").setNum(m_RangeSliderMax + border)); - m_Controls->m_RangeSlider->setSpan( m_RangeSliderMin, m_RangeSliderMax); - - UpdateRanges(); numberOfImages++; } - if (m_MitkAmplitudeImage) + if (m_MitkAmplitudeImageNode) { m_Widget2ColorTransferFunction = vtkColorTransferFunction::New(); this->m_Widget2TransferFunctionType = 0; - ResetTransferFunction(this->m_Widget2ColorTransferFunction, this->m_Widget2TransferFunctionType, amplitudeImage->GetScalarValueMin(), amplitudeImage->GetScalarValueMax()); numberOfImages++; } - if (m_MitkIntensityImage) + if (m_MitkIntensityImageNode) { m_Widget3ColorTransferFunction = vtkColorTransferFunction::New(); this->m_Widget3TransferFunctionType = 0; - ResetTransferFunction(this->m_Widget3ColorTransferFunction, this->m_Widget3TransferFunctionType, intensityImage->GetScalarValueMin(), intensityImage->GetScalarValueMax()); numberOfImages++; } m_Controls->m_SelectWidgetCombobox->setMaxCount(numberOfImages); } + this->ReinitTransferFunction(0,1); + this->ReinitTransferFunction(1,0); + this->ReinitTransferFunction(2,0); } void QmitkToFVisualisationSettingsWidget::UpdateCanvas() { m_Controls->m_ColorTransferFunctionCanvas->SetColorTransferFunction( this->GetSelectedColorTransferFunction() ); UpdateRanges(); m_Controls->m_ColorTransferFunctionCanvas->update(); } void QmitkToFVisualisationSettingsWidget::OnTransferFunctionTypeSelected(int index) { int currentWidgetIndex = m_Controls->m_SelectWidgetCombobox->currentIndex(); if (currentWidgetIndex == 0) { this->m_Widget1TransferFunctionType = index; } else if (currentWidgetIndex == 1) { this->m_Widget2TransferFunctionType = index; } else if (currentWidgetIndex == 2) { this->m_Widget3TransferFunctionType = index; } else { return; } } void QmitkToFVisualisationSettingsWidget::OnWidgetSelected(int index) { int currentWidgetIndex = m_Controls->m_SelectWidgetCombobox->currentIndex(); double valMin[6]; double valMax[6]; int numPoints; if (currentWidgetIndex == 0) { m_Controls->m_SelectTransferFunctionTypeCombobox->setCurrentIndex(this->m_Widget1TransferFunctionType); numPoints = this->m_Widget1ColorTransferFunction->GetSize(); this->m_Widget1ColorTransferFunction->GetNodeValue( 0, valMin ); this->m_Widget1ColorTransferFunction->GetNodeValue( numPoints-1, valMax ); m_Controls->m_ColorTransferFunctionCanvas->SetColorTransferFunction( this->m_Widget1ColorTransferFunction ); } else if (currentWidgetIndex == 1) { m_Controls->m_SelectTransferFunctionTypeCombobox->setCurrentIndex(this->m_Widget2TransferFunctionType); numPoints = this->m_Widget2ColorTransferFunction->GetSize(); this->m_Widget2ColorTransferFunction->GetNodeValue( 0, valMin ); this->m_Widget2ColorTransferFunction->GetNodeValue( numPoints-1, valMax ); m_Controls->m_ColorTransferFunctionCanvas->SetColorTransferFunction( this->m_Widget2ColorTransferFunction ); } else if (currentWidgetIndex == 2) { m_Controls->m_SelectTransferFunctionTypeCombobox->setCurrentIndex(this->m_Widget3TransferFunctionType); numPoints = this->m_Widget3ColorTransferFunction->GetSize(); this->m_Widget3ColorTransferFunction->GetNodeValue( 0, valMin ); this->m_Widget3ColorTransferFunction->GetNodeValue( numPoints-1, valMax ); m_Controls->m_ColorTransferFunctionCanvas->SetColorTransferFunction( this->m_Widget3ColorTransferFunction ); } else if (currentWidgetIndex == 3) { } else { return; } m_RangeSliderMin = valMin[0]; m_RangeSliderMax = valMax[0]; int border = (m_RangeSliderMax - m_RangeSliderMin) * 0.1; m_Controls->m_RangeSlider->setMinimum(m_RangeSliderMin - border); m_Controls->m_RangeSlider->setMaximum(m_RangeSliderMax + border); m_Controls->m_RangeSliderMinEdit->setText(QString("").setNum(m_RangeSliderMin - border)); m_Controls->m_RangeSliderMaxEdit->setText(QString("").setNum(m_RangeSliderMax + border)); m_Controls->m_RangeSlider->setSpan( m_RangeSliderMin, m_RangeSliderMax); UpdateRanges(); m_Controls->m_ColorTransferFunctionCanvas->update(); } void QmitkToFVisualisationSettingsWidget::ResetTransferFunction(vtkColorTransferFunction* colorTransferFunction, int type, double min, double max) { colorTransferFunction->RemoveAllPoints(); if (type == 0) { colorTransferFunction->AddRGBPoint(min, 0, 0, 0); colorTransferFunction->AddRGBPoint(max, 1, 1, 1); } else { if (min>0.01) { colorTransferFunction->AddRGBPoint(0.0, 0, 0, 0); colorTransferFunction->AddRGBPoint(min-0.01, 0, 0, 0); } colorTransferFunction->AddRGBPoint(min, 1, 0, 0); colorTransferFunction->AddRGBPoint(min+(max-min)/2, 1, 1, 0); colorTransferFunction->AddRGBPoint(max, 0, 0, 1); } colorTransferFunction->SetColorSpaceToHSV(); } -void QmitkToFVisualisationSettingsWidget::OnTransferFunctionReset() +void QmitkToFVisualisationSettingsWidget::ReinitTransferFunction(int widget, int type) { - int currentTransferFunctionTypeIndex = m_Controls->m_SelectTransferFunctionTypeCombobox->currentIndex(); - int currentWidgetIndex = m_Controls->m_SelectWidgetCombobox->currentIndex(); - - if (currentWidgetIndex == 0) + switch (widget) + { + case 0: { + mitk::Image::Pointer distanceImage = dynamic_cast(m_MitkDistanceImageNode->GetData()); // use second minimum to draw 0 values (that are usually segmented) black - m_RangeSliderMin = this->m_MitkDistanceImage->GetScalarValue2ndMin(); - m_RangeSliderMax = this->m_MitkDistanceImage->GetScalarValueMaxNoRecompute(); - ResetTransferFunction(this->m_Widget1ColorTransferFunction, currentTransferFunctionTypeIndex, this->m_RangeSliderMin, this->m_RangeSliderMax); + m_RangeSliderMin = distanceImage->GetStatistics()->GetScalarValue2ndMin(); + m_RangeSliderMax = distanceImage->GetStatistics()->GetScalarValueMax(); + MITK_INFO<<"Distance Min: "<m_Widget1ColorTransferFunction, type, this->m_RangeSliderMin, this->m_RangeSliderMax); m_Controls->m_ColorTransferFunctionCanvas->SetColorTransferFunction( this->m_Widget1ColorTransferFunction ); + mitk::TransferFunction::Pointer tf1 = mitk::TransferFunction::New(); + tf1->SetColorTransferFunction( m_Widget1ColorTransferFunction ); + m_MitkDistanceImageNode->SetProperty("Image Rendering.Transfer Function",mitk::TransferFunctionProperty::New(tf1)); + break; } - else if (currentWidgetIndex == 1) + case 1: { - m_RangeSliderMin = this->m_MitkAmplitudeImage->GetScalarValueMin(); - m_RangeSliderMax = this->m_MitkAmplitudeImage->GetScalarValueMaxNoRecompute(); - ResetTransferFunction(this->m_Widget2ColorTransferFunction, currentTransferFunctionTypeIndex, this->m_RangeSliderMin, this->m_RangeSliderMax); + mitk::Image::Pointer amplitudeImage = dynamic_cast(m_MitkAmplitudeImageNode->GetData()); + m_RangeSliderMin = amplitudeImage->GetStatistics()->GetScalarValueMin(); + m_RangeSliderMax = amplitudeImage->GetStatistics()->GetScalarValueMax(); + MITK_INFO<<"Amplitude Min: "<m_Widget2ColorTransferFunction, type, this->m_RangeSliderMin, this->m_RangeSliderMax); m_Controls->m_ColorTransferFunctionCanvas->SetColorTransferFunction( this->m_Widget2ColorTransferFunction ); + mitk::TransferFunction::Pointer tf2 = mitk::TransferFunction::New(); + tf2->SetColorTransferFunction( m_Widget2ColorTransferFunction ); + m_MitkAmplitudeImageNode->SetProperty("Image Rendering.Transfer Function",mitk::TransferFunctionProperty::New(tf2)); + break; } - else if (currentWidgetIndex == 2) + case 2: { - m_RangeSliderMin = this->m_MitkIntensityImage->GetScalarValueMin(); - m_RangeSliderMax = this->m_MitkIntensityImage->GetScalarValueMaxNoRecompute(); - ResetTransferFunction(this->m_Widget3ColorTransferFunction, currentTransferFunctionTypeIndex, this->m_RangeSliderMin, this->m_RangeSliderMax); + mitk::Image::Pointer intensityImage = dynamic_cast(m_MitkIntensityImageNode->GetData()); + m_RangeSliderMin = intensityImage->GetStatistics()->GetScalarValueMin(); + m_RangeSliderMax = intensityImage->GetStatistics()->GetScalarValueMax(); + MITK_INFO<<"Intensity Min: "<m_Widget3ColorTransferFunction, type, this->m_RangeSliderMin, this->m_RangeSliderMax); m_Controls->m_ColorTransferFunctionCanvas->SetColorTransferFunction( this->m_Widget3ColorTransferFunction ); + mitk::TransferFunction::Pointer tf3 = mitk::TransferFunction::New(); + tf3->SetColorTransferFunction( m_Widget3ColorTransferFunction ); + m_MitkIntensityImageNode->SetProperty("Image Rendering.Transfer Function",mitk::TransferFunctionProperty::New(tf3)); + break; } - else - { - return; + default: + break; } +} + +void QmitkToFVisualisationSettingsWidget::OnTransferFunctionReset() +{ + int currentTransferFunctionTypeIndex = m_Controls->m_SelectTransferFunctionTypeCombobox->currentIndex(); + int currentWidgetIndex = m_Controls->m_SelectWidgetCombobox->currentIndex(); + + this->ReinitTransferFunction(currentWidgetIndex,currentTransferFunctionTypeIndex); + int border = (m_RangeSliderMax - m_RangeSliderMin) * 0.1; m_Controls->m_RangeSlider->setMinimum(m_RangeSliderMin - border); m_Controls->m_RangeSlider->setMaximum(m_RangeSliderMax + border); m_Controls->m_RangeSliderMinEdit->setText(QString("").setNum(m_RangeSliderMin - border)); m_Controls->m_RangeSliderMaxEdit->setText(QString("").setNum(m_RangeSliderMax + border)); m_Controls->m_RangeSlider->setSpan( m_RangeSliderMin, m_RangeSliderMax); UpdateRanges(); m_Controls->m_ColorTransferFunctionCanvas->update(); } vtkColorTransferFunction* QmitkToFVisualisationSettingsWidget::GetWidget1ColorTransferFunction() { return this->m_Widget1ColorTransferFunction; } vtkColorTransferFunction* QmitkToFVisualisationSettingsWidget::GetWidget2ColorTransferFunction() { return this->m_Widget2ColorTransferFunction; } vtkColorTransferFunction* QmitkToFVisualisationSettingsWidget::GetWidget3ColorTransferFunction() { return this->m_Widget3ColorTransferFunction; } vtkColorTransferFunction* QmitkToFVisualisationSettingsWidget::GetSelectedColorTransferFunction() { int currentWidgetIndex = m_Controls->m_SelectWidgetCombobox->currentIndex(); if (currentWidgetIndex==0) { return this->m_Widget1ColorTransferFunction; } else if (currentWidgetIndex==1) { return this->m_Widget2ColorTransferFunction; } else if (currentWidgetIndex==2) { return this->m_Widget3ColorTransferFunction; } else { return this->m_Widget3ColorTransferFunction; } } int QmitkToFVisualisationSettingsWidget::GetSelectedImageIndex() { return this->m_Controls->m_SelectWidgetCombobox->currentIndex(); } diff --git a/Modules/ToFUI/Qmitk/QmitkToFVisualisationSettingsWidget.h b/Modules/ToFUI/Qmitk/QmitkToFVisualisationSettingsWidget.h index 5296777615..0454362bf3 100644 --- a/Modules/ToFUI/Qmitk/QmitkToFVisualisationSettingsWidget.h +++ b/Modules/ToFUI/Qmitk/QmitkToFVisualisationSettingsWidget.h @@ -1,159 +1,166 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #ifndef _QMITKTOFVISUALISATIONSETTINGSWIDGET_H_INCLUDED #define _QMITKTOFVISUALISATIONSETTINGSWIDGET_H_INCLUDED #include "mitkTOFUIExports.h" #include "ui_QmitkToFVisualisationSettingsWidgetControls.h" +#include "mitkDataNode.h" // QT headers #include // vtk includes #include class QmitkStdMultiWidget; /** Documentation: * Widget controlling the visualization of Time-of-Flight image data. A color transfer function can be configured for * a given distance, amplitude and intensity image. The pre-configured vtkColorTransferFunctions can be accessed as * an output of the widget. * * \ingroup ToFUI */ class mitkTOFUI_EXPORT QmitkToFVisualisationSettingsWidget :public QWidget { //this is needed for all Qt objects that should have a MOC object (everything that derives from QObject) Q_OBJECT public: static const std::string VIEW_ID; QmitkToFVisualisationSettingsWidget (QWidget* p = 0, Qt::WindowFlags f1 = 0); virtual ~QmitkToFVisualisationSettingsWidget (); /* @brief This method is part of the widget an needs not to be called seperately. */ virtual void CreateQtPartControl(QWidget *parent); /* @brief This method is part of the widget an needs not to be called seperately. (Creation of the connections of main and control widget.)*/ virtual void CreateConnections(); /*! \brief initialize the widget with the images to be shown \param distanceImage image holding the range image of a ToF camera \param amplitudeImage image holding the amplitude image of a ToF camera \param intensityImage image holding the intensity image of a ToF camera */ - void Initialize(mitk::Image* distanceImage=NULL, mitk::Image* amplitudeImage=NULL, mitk::Image* intensityImage=NULL); + void Initialize(mitk::DataNode* distanceImageNode=NULL, mitk::DataNode* amplitudeImageNode=NULL, mitk::DataNode* intensityImageNode=NULL); /*! \brief Access the color transfer function of widget 1 (distance image) \return vtkColorTransferFunction that can be used to define a TransferFunctionProperty */ vtkColorTransferFunction* GetWidget1ColorTransferFunction(); /*! \brief Access the color transfer function of widget 2 (distance image) \return vtkColorTransferFunction that can be used to define a TransferFunctionProperty */ vtkColorTransferFunction* GetWidget2ColorTransferFunction(); /*! \brief Access the color transfer function of widget 3 (distance image) \return vtkColorTransferFunction that can be used to define a TransferFunctionProperty */ vtkColorTransferFunction* GetWidget3ColorTransferFunction(); /*! \brief Access the color transfer of the currently selected widget \return vtkColorTransferFunction that can be used to define a TransferFunctionProperty */ vtkColorTransferFunction* GetSelectedColorTransferFunction(); /*! \brief Return the index of the selected image: 0 = Distance, 1 = Amplitude, 2 = Intensity */ int GetSelectedImageIndex(); protected slots: void OnSetXValueColor(); /*! \brief Slot invoking a reset of the RangeSlider to the minimal and maximal values of the according image */ void OnResetSlider(); /*! \brief Slot called when the range span has changed. */ void OnSpanChanged (int lower, int upper); /*! \brief Resets the transfer function according to the currently selected widget / image */ void OnTransferFunctionReset(); /*! \brief Updates the GUI according to the widget / image selection */ void OnWidgetSelected(int index); /*! \brief Slot called when the line edit of the maximal value of the range slider has changed. Leads to an update of the range slider. */ void OnRangeSliderMaxChanged(); /*! \brief Slot called when the line edit of the minimal value of the range slider has changed. Leads to an update of the range slider. */ void OnRangeSliderMinChanged(); /*! \brief Sets the TransferFunctionType members according to the selection of the widget and the transfer type. */ void OnTransferFunctionTypeSelected(int index); protected: /*! \brief Invokes an update of the ColorTransferFunctionCanvas. Called when the ColorTransferFunction has changed */ void UpdateCanvas(); /*! \brief Resets the ColorTransferFunctionCanvas according to the lower and upper value of the RangeSlider */ void UpdateRanges(); Ui::QmitkToFVisualisationSettingsWidgetControls* m_Controls; int m_RangeSliderMin; ///< Minimal value of the transfer function range. Initialized to the minimal value of the corresponding image. int m_RangeSliderMax; ///< Maximal value of the transfer function range. Initialized to the maximal value of the corresponding image. - mitk::Image::Pointer m_MitkDistanceImage; ///< Range image of the ToF camera as set by Initialize() - mitk::Image::Pointer m_MitkAmplitudeImage; ///< Amplitud image of the ToF camera as set by Initialize() - mitk::Image::Pointer m_MitkIntensityImage; ///< Intensity image of the ToF camera as set by Initialize() + mitk::DataNode::Pointer m_MitkDistanceImageNode; ///< DataNode holding the range image of the ToF camera as set by Initialize() + mitk::DataNode::Pointer m_MitkAmplitudeImageNode; ///< DataNode holding the amplitude image of the ToF camera as set by Initialize() + mitk::DataNode::Pointer m_MitkIntensityImageNode; ///< DataNode holding the intensity image of the ToF camera as set by Initialize() vtkColorTransferFunction* m_Widget1ColorTransferFunction; ///< vtkColorTransferFunction of widget 1 (distance) that can be used to define a TransferFunctionProperty vtkColorTransferFunction* m_Widget2ColorTransferFunction; ///< vtkColorTransferFunction of widget 2 (amplitude) that can be used to define a TransferFunctionProperty vtkColorTransferFunction* m_Widget3ColorTransferFunction; ///< vtkColorTransferFunction of widget 3 (intensity) that can be used to define a TransferFunctionProperty int m_Widget1TransferFunctionType; ///< member holding the type of the transfer function applied to the image shown in widget 1 (distance image): 0 = gray scale, 1 = color int m_Widget2TransferFunctionType; ///< member holding the type of the transfer function applied to the image shown in widget 2 (amplitude image): 0 = gray scale, 1 = color int m_Widget3TransferFunctionType; ///< member holding the type of the transfer function applied to the image shown in widget 3 (intensity image): 0 = gray scale, 1 = color private: /*! \brief Reset the color transfer function to the given type and range \param colorTransferFunction vtkColorTransferfunction to be resetted \param type type of the transfer function: 0 = gray scale, 1 = color \param min minimal value to be set to the transfer function \param max maximal value to be set to the transfer function */ void ResetTransferFunction(vtkColorTransferFunction* colorTransferFunction, int type, double min, double max); + /*! + \brief Reset the color transfer function for the given widget + \param widget 0: transversal, 1: coronal, 2: sagittal + \param type: type of the transfer function: 0 = gray scale, 1 = color + */ + void ReinitTransferFunction(int widget, int type); }; #endif // _QMITKTOFVISUALISATIONSETTINGSWIDGET_H_INCLUDED diff --git a/Modules/ToFUI/files.cmake b/Modules/ToFUI/files.cmake index 084141cd52..c5dfc410c2 100644 --- a/Modules/ToFUI/files.cmake +++ b/Modules/ToFUI/files.cmake @@ -1,34 +1,36 @@ - -set(CPP_FILES +SET(CPP_FILES + Qmitk/QmitkKinectParameterWidget.cpp Qmitk/QmitkToFConnectionWidget.cpp Qmitk/QmitkToFPointSetWidget.cpp Qmitk/QmitkToFRecorderWidget.cpp Qmitk/QmitkToFVisualisationSettingsWidget.cpp Qmitk/QmitkToFCompositeFilterWidget.cpp Qmitk/QmitkToFPMDParameterWidget.cpp Qmitk/QmitkToFMESAParameterWidget.cpp ) -set(UI_FILES +SET(UI_FILES + Qmitk/QmitkKinectParameterWidgetControls.ui Qmitk/QmitkToFConnectionWidgetControls.ui Qmitk/QmitkToFPointSetWidgetControls.ui Qmitk/QmitkToFRecorderWidgetControls.ui Qmitk/QmitkToFVisualisationSettingsWidgetControls.ui Qmitk/QmitkToFCompositeFilterWidgetControls.ui Qmitk/QmitkToFPMDParameterWidgetControls.ui Qmitk/QmitkToFMESAParameterWidgetControls.ui ) -set(MOC_H_FILES +SET(MOC_H_FILES + Qmitk/QmitkKinectParameterWidget.h Qmitk/QmitkToFConnectionWidget.h Qmitk/QmitkToFPointSetWidget.h Qmitk/QmitkToFRecorderWidget.h Qmitk/QmitkToFVisualisationSettingsWidget.h Qmitk/QmitkToFCompositeFilterWidget.h Qmitk/QmitkToFPMDParameterWidget.h Qmitk/QmitkToFMESAParameterWidget.h ) # uncomment the following line if you want to use Qt resources set(QRC_FILES resources/QmitkToFUtilWidget.qrc ) diff --git a/Plugins/org.mitk.gui.qt.tofutil/src/internal/QmitkToFUtilView.cpp b/Plugins/org.mitk.gui.qt.tofutil/src/internal/QmitkToFUtilView.cpp index 51127b9dc8..6c566e25a3 100644 --- a/Plugins/org.mitk.gui.qt.tofutil/src/internal/QmitkToFUtilView.cpp +++ b/Plugins/org.mitk.gui.qt.tofutil/src/internal/QmitkToFUtilView.cpp @@ -1,520 +1,525 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ // Qmitk #include "QmitkToFUtilView.h" #include #include // Qt #include #include // MITK #include #include #include #include #include #include // VTK #include // ITK #include const std::string QmitkToFUtilView::VIEW_ID = "org.mitk.views.tofutil"; QmitkToFUtilView::QmitkToFUtilView() : QmitkFunctionality() , m_Controls(NULL), m_MultiWidget( NULL ) , m_MitkDistanceImage(NULL), m_MitkAmplitudeImage(NULL), m_MitkIntensityImage(NULL), m_Surface(NULL) - , m_DistanceImageNode(NULL), m_AmplitudeImageNode(NULL), m_IntensityImageNode(NULL), m_SurfaceNode(NULL) + , m_DistanceImageNode(NULL), m_AmplitudeImageNode(NULL), m_IntensityImageNode(NULL), m_RGBImageNode(NULL), m_SurfaceNode(NULL) , m_ToFImageRecorder(NULL), m_ToFImageGrabber(NULL), m_ToFDistanceImageToSurfaceFilter(NULL), m_ToFCompositeFilter(NULL) , m_SurfaceDisplayCount(0), m_2DDisplayCount(0) , m_RealTimeClock(NULL) , m_StepsForFramerate(100) , m_2DTimeBefore(0.0) , m_2DTimeAfter(0.0) , m_VideoEnabled(false) { this->m_Frametimer = new QTimer(this); this->m_ToFDistanceImageToSurfaceFilter = mitk::ToFDistanceImageToSurfaceFilter::New(); this->m_ToFCompositeFilter = mitk::ToFCompositeFilter::New(); this->m_ToFImageRecorder = mitk::ToFImageRecorder::New(); this->m_ToFSurfaceVtkMapper3D = mitk::ToFSurfaceVtkMapper3D::New(); } QmitkToFUtilView::~QmitkToFUtilView() { OnToFCameraStopped(); OnToFCameraDisconnected(); } void QmitkToFUtilView::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::QmitkToFUtilViewControls; m_Controls->setupUi( parent ); connect(m_Frametimer, SIGNAL(timeout()), this, SLOT(OnUpdateCamera())); connect( (QObject*)(m_Controls->m_ToFConnectionWidget), SIGNAL(ToFCameraConnected()), this, SLOT(OnToFCameraConnected()) ); connect( (QObject*)(m_Controls->m_ToFConnectionWidget), SIGNAL(ToFCameraDisconnected()), this, SLOT(OnToFCameraDisconnected()) ); connect( (QObject*)(m_Controls->m_ToFConnectionWidget), SIGNAL(ToFCameraSelected(const QString)), this, SLOT(OnToFCameraSelected(const QString)) ); connect( (QObject*)(m_Controls->m_ToFRecorderWidget), SIGNAL(ToFCameraStarted()), this, SLOT(OnToFCameraStarted()) ); connect( (QObject*)(m_Controls->m_ToFRecorderWidget), SIGNAL(ToFCameraStopped()), this, SLOT(OnToFCameraStopped()) ); connect( (QObject*)(m_Controls->m_ToFRecorderWidget), SIGNAL(RecordingStarted()), this, SLOT(OnToFCameraStopped()) ); connect( (QObject*)(m_Controls->m_ToFRecorderWidget), SIGNAL(RecordingStopped()), this, SLOT(OnToFCameraStarted()) ); connect( (QObject*)(m_Controls->m_TextureCheckBox), SIGNAL(toggled(bool)), this, SLOT(OnTextureCheckBoxChecked(bool)) ); connect( (QObject*)(m_Controls->m_VideoTextureCheckBox), SIGNAL(toggled(bool)), this, SLOT(OnVideoTextureCheckBoxChecked(bool)) ); } } void QmitkToFUtilView::StdMultiWidgetAvailable (QmitkStdMultiWidget &stdMultiWidget) { m_MultiWidget = &stdMultiWidget; } void QmitkToFUtilView::StdMultiWidgetNotAvailable() { m_MultiWidget = NULL; } void QmitkToFUtilView::Activated() { QmitkFunctionality::Activated(); // configure views m_MultiWidget->SetWidgetPlanesVisibility(false); m_MultiWidget->mitkWidget1->GetSliceNavigationController()->SetDefaultViewDirection(mitk::SliceNavigationController::Transversal); m_MultiWidget->mitkWidget1->GetSliceNavigationController()->SliceLockedOn(); m_MultiWidget->mitkWidget2->GetSliceNavigationController()->SetDefaultViewDirection(mitk::SliceNavigationController::Transversal); m_MultiWidget->mitkWidget2->GetSliceNavigationController()->SliceLockedOn(); m_MultiWidget->mitkWidget3->GetSliceNavigationController()->SetDefaultViewDirection(mitk::SliceNavigationController::Transversal); m_MultiWidget->mitkWidget3->GetSliceNavigationController()->SliceLockedOn(); m_MultiWidget->ResetCrosshair(); mitk::RenderingManager::GetInstance()->InitializeViews(); this->UseToFVisibilitySettings(true); m_Controls->m_ToFCompositeFilterWidget->SetToFCompositeFilter(this->m_ToFCompositeFilter); m_Controls->m_ToFCompositeFilterWidget->SetDataStorage(this->GetDefaultDataStorage()); if (this->m_ToFImageGrabber.IsNull()) { m_Controls->m_ToFRecorderWidget->setEnabled(false); m_Controls->m_ToFVisualisationSettingsWidget->setEnabled(false); } } void QmitkToFUtilView::Deactivated() { m_MultiWidget->SetWidgetPlanesVisibility(true); m_MultiWidget->mitkWidget1->GetSliceNavigationController()->SetDefaultViewDirection(mitk::SliceNavigationController::Transversal); m_MultiWidget->mitkWidget1->GetSliceNavigationController()->SliceLockedOff(); m_MultiWidget->mitkWidget2->GetSliceNavigationController()->SetDefaultViewDirection(mitk::SliceNavigationController::Sagittal); m_MultiWidget->mitkWidget2->GetSliceNavigationController()->SliceLockedOff(); m_MultiWidget->mitkWidget3->GetSliceNavigationController()->SetDefaultViewDirection(mitk::SliceNavigationController::Frontal); m_MultiWidget->mitkWidget3->GetSliceNavigationController()->SliceLockedOff(); m_MultiWidget->ResetCrosshair(); this->UseToFVisibilitySettings(false); mitk::RenderingManager::GetInstance()->InitializeViews(); QmitkFunctionality::Deactivated(); } void QmitkToFUtilView::OnToFCameraConnected() { this->m_SurfaceDisplayCount = 0; this->m_2DDisplayCount = 0; this->m_ToFImageGrabber = m_Controls->m_ToFConnectionWidget->GetToFImageGrabber(); this->m_ToFImageRecorder->SetCameraDevice(this->m_ToFImageGrabber->GetCameraDevice()); m_Controls->m_ToFRecorderWidget->SetParameter(this->m_ToFImageGrabber, this->m_ToFImageRecorder); m_Controls->m_ToFRecorderWidget->setEnabled(true); m_Controls->m_ToFRecorderWidget->ResetGUIToInitial(); m_Controls->m_ToFVisualisationSettingsWidget->setEnabled(true); //TODO this->m_RealTimeClock = mitk::RealTimeClock::New(); this->m_2DTimeBefore = this->m_RealTimeClock->GetCurrentStamp(); try { this->m_VideoSource = mitk::OpenCVVideoSource::New(); this->m_VideoSource->SetVideoCameraInput(0, false); this->m_VideoSource->StartCapturing(); if(!this->m_VideoSource->IsCapturingEnabled()) { MITK_INFO << "unable to initialize video grabbing/playback"; this->m_VideoEnabled = false; m_Controls->m_VideoTextureCheckBox->setEnabled(false); } else { this->m_VideoEnabled = true; m_Controls->m_VideoTextureCheckBox->setEnabled(true); } if (this->m_VideoEnabled) { this->m_VideoSource->FetchFrame(); this->m_VideoCaptureHeight = this->m_VideoSource->GetImageHeight(); this->m_VideoCaptureWidth = this->m_VideoSource->GetImageWidth(); int videoTexSize = this->m_VideoCaptureWidth * this->m_VideoCaptureHeight * 3; // for each pixel three values for rgb are needed!! this->m_VideoTexture = this->m_VideoSource->GetVideoTexture(); unsigned int dimensions[2]; dimensions[0] = this->m_VideoCaptureWidth; dimensions[1] = this->m_VideoCaptureHeight; this->m_ToFDistanceImageToSurfaceFilter->SetTextureImageWidth(this->m_VideoCaptureWidth); this->m_ToFDistanceImageToSurfaceFilter->SetTextureImageHeight(this->m_VideoCaptureHeight); this->m_ToFSurfaceVtkMapper3D->SetTextureWidth(this->m_VideoCaptureWidth); this->m_ToFSurfaceVtkMapper3D->SetTextureHeight(this->m_VideoCaptureHeight); } m_MultiWidget->DisableGradientBackground(); } catch (std::logic_error& e) { QMessageBox::warning(NULL, "Warning", QString(e.what())); MITK_ERROR << e.what(); return; } mitk::RenderingManager::GetInstance()->ForceImmediateUpdateAll(); } void QmitkToFUtilView::OnToFCameraDisconnected() { m_Controls->m_ToFRecorderWidget->OnStop(); m_Controls->m_ToFRecorderWidget->setEnabled(false); m_Controls->m_ToFVisualisationSettingsWidget->setEnabled(false); if(this->m_VideoSource) { this->m_VideoSource->StopCapturing(); this->m_VideoSource = NULL; } mitk::RenderingManager::GetInstance()->ForceImmediateUpdateAll(); } void QmitkToFUtilView::OnToFCameraStarted() { - if (m_ToFImageGrabber.IsNotNull()) + if (m_ToFImageGrabber.IsNotNull()) + { + // initial update of image grabber + this->m_ToFImageGrabber->Update(); + + this->m_ToFCompositeFilter->SetInput(0,this->m_ToFImageGrabber->GetOutput(0)); + this->m_ToFCompositeFilter->SetInput(1,this->m_ToFImageGrabber->GetOutput(1)); + this->m_ToFCompositeFilter->SetInput(2,this->m_ToFImageGrabber->GetOutput(2)); + + // initial update of composite filter + this->m_ToFCompositeFilter->Update(); + this->m_MitkDistanceImage = m_ToFCompositeFilter->GetOutput(0); + this->m_DistanceImageNode = ReplaceNodeData("Distance image",m_MitkDistanceImage); + this->m_MitkAmplitudeImage = m_ToFCompositeFilter->GetOutput(1); + this->m_AmplitudeImageNode = ReplaceNodeData("Amplitude image",m_MitkAmplitudeImage); + this->m_MitkIntensityImage = m_ToFCompositeFilter->GetOutput(2); + this->m_IntensityImageNode = ReplaceNodeData("Intensity image",m_MitkIntensityImage); + + std::string rgbFileName; + m_ToFImageGrabber->GetCameraDevice()->GetStringProperty("RGBImageFileName",rgbFileName); + if ((m_SelectedCamera=="Microsoft Kinect")||(rgbFileName!="")) { - // initial update of image grabber - this->m_ToFImageGrabber->Update(); - - this->m_ToFCompositeFilter->SetInput(0,this->m_ToFImageGrabber->GetOutput(0)); - this->m_ToFCompositeFilter->SetInput(1,this->m_ToFImageGrabber->GetOutput(1)); - this->m_ToFCompositeFilter->SetInput(2,this->m_ToFImageGrabber->GetOutput(2)); - // initial update of composite filter - this->m_ToFCompositeFilter->Update(); - this->m_MitkDistanceImage = m_ToFCompositeFilter->GetOutput(0); - this->m_DistanceImageNode = ReplaceNodeData("Distance image",m_MitkDistanceImage); - this->m_MitkAmplitudeImage = m_ToFCompositeFilter->GetOutput(1); - this->m_AmplitudeImageNode = ReplaceNodeData("Amplitude image",m_MitkAmplitudeImage); - this->m_MitkIntensityImage = m_ToFCompositeFilter->GetOutput(2); - this->m_IntensityImageNode = ReplaceNodeData("Intensity image",m_MitkIntensityImage); - - this->m_ToFDistanceImageToSurfaceFilter->SetInput(0,m_MitkDistanceImage); - this->m_ToFDistanceImageToSurfaceFilter->SetInput(1,m_MitkAmplitudeImage); - this->m_ToFDistanceImageToSurfaceFilter->SetInput(2,m_MitkIntensityImage); - this->m_Surface = this->m_ToFDistanceImageToSurfaceFilter->GetOutput(0); - this->m_SurfaceNode = ReplaceNodeData("Surface",m_Surface); - - this->UseToFVisibilitySettings(true); - - this->m_Frametimer->start(0); - - m_Controls->m_ToFCompositeFilterWidget->UpdateFilterParameter(); - // initialize visualization widget - m_Controls->m_ToFVisualisationSettingsWidget->Initialize(this->m_MitkDistanceImage, this->m_MitkAmplitudeImage, this->m_MitkIntensityImage); - - if (m_Controls->m_TextureCheckBox->isChecked()) - { - OnTextureCheckBoxChecked(true); - } - if (m_Controls->m_VideoTextureCheckBox->isChecked()) - { - OnVideoTextureCheckBoxChecked(true); - } + this->m_RGBImageNode = ReplaceNodeData("RGB image",this->m_ToFImageGrabber->GetOutput(3)); } - m_Controls->m_TextureCheckBox->setEnabled(true); - // initialize point set measurement - m_Controls->tofMeasurementWidget->InitializeWidget(m_MultiWidget,this->GetDefaultDataStorage(),m_MitkDistanceImage); + else + { + this->m_RGBImageNode = NULL; + } + + this->m_ToFDistanceImageToSurfaceFilter->SetInput(0,m_MitkDistanceImage); + this->m_ToFDistanceImageToSurfaceFilter->SetInput(1,m_MitkAmplitudeImage); + this->m_ToFDistanceImageToSurfaceFilter->SetInput(2,m_MitkIntensityImage); + this->m_Surface = this->m_ToFDistanceImageToSurfaceFilter->GetOutput(0); + this->m_SurfaceNode = ReplaceNodeData("Surface",m_Surface); + + this->UseToFVisibilitySettings(true); + + m_Controls->m_ToFCompositeFilterWidget->UpdateFilterParameter(); + // initialize visualization widget + m_Controls->m_ToFVisualisationSettingsWidget->Initialize(this->m_DistanceImageNode, this->m_AmplitudeImageNode, this->m_IntensityImageNode); + + this->m_Frametimer->start(0); + + if (m_Controls->m_TextureCheckBox->isChecked()) + { + OnTextureCheckBoxChecked(true); + } + if (m_Controls->m_VideoTextureCheckBox->isChecked()) + { + OnVideoTextureCheckBoxChecked(true); + } + } + m_Controls->m_TextureCheckBox->setEnabled(true); + // initialize point set measurement + m_Controls->tofMeasurementWidget->InitializeWidget(m_MultiWidget,this->GetDefaultDataStorage(),m_MitkDistanceImage); } void QmitkToFUtilView::OnToFCameraStopped() { - this->m_Frametimer->stop(); + this->m_Frametimer->stop(); } void QmitkToFUtilView::OnToFCameraSelected(const QString selected) { - if ((selected=="PMD CamBoard")||(selected=="PMD O3D")) - { - MITK_INFO<<"Surface representation currently not available for CamBoard and O3. Intrinsic parameters missing."; - this->m_Controls->m_SurfaceCheckBox->setEnabled(false); - this->m_Controls->m_TextureCheckBox->setEnabled(false); - this->m_Controls->m_VideoTextureCheckBox->setEnabled(false); - this->m_Controls->m_SurfaceCheckBox->setChecked(false); - this->m_Controls->m_TextureCheckBox->setChecked(false); + m_SelectedCamera = selected; + if ((selected=="PMD CamBoard")||(selected=="PMD O3D")) + { + MITK_INFO<<"Surface representation currently not available for CamBoard and O3. Intrinsic parameters missing."; + this->m_Controls->m_SurfaceCheckBox->setEnabled(false); + this->m_Controls->m_TextureCheckBox->setEnabled(false); + this->m_Controls->m_VideoTextureCheckBox->setEnabled(false); + this->m_Controls->m_SurfaceCheckBox->setChecked(false); + this->m_Controls->m_TextureCheckBox->setChecked(false); this->m_Controls->m_VideoTextureCheckBox->setChecked(false); } else { this->m_Controls->m_SurfaceCheckBox->setEnabled(true); this->m_Controls->m_TextureCheckBox->setEnabled(true); // TODO enable when bug 8106 is solved this->m_Controls->m_VideoTextureCheckBox->setEnabled(true); } } void QmitkToFUtilView::OnUpdateCamera() { if (m_Controls->m_VideoTextureCheckBox->isChecked() && this->m_VideoEnabled && this->m_VideoSource) { this->m_VideoTexture = this->m_VideoSource->GetVideoTexture(); ProcessVideoTransform(); } - vtkColorTransferFunction* colorTransferFunction1; - colorTransferFunction1 = m_Controls->m_ToFVisualisationSettingsWidget->GetWidget1ColorTransferFunction(); - mitk::TransferFunction::Pointer tf1 = mitk::TransferFunction::New(); - tf1->SetColorTransferFunction( colorTransferFunction1 ); - m_DistanceImageNode->SetProperty("Image Rendering.Transfer Function",mitk::TransferFunctionProperty::New(tf1)); - vtkColorTransferFunction* colorTransferFunction2; - colorTransferFunction2 = m_Controls->m_ToFVisualisationSettingsWidget->GetWidget2ColorTransferFunction(); - mitk::TransferFunction::Pointer tf2 = mitk::TransferFunction::New(); - tf2->SetColorTransferFunction( colorTransferFunction2 ); - m_AmplitudeImageNode->SetProperty("Image Rendering.Transfer Function",mitk::TransferFunctionProperty::New(tf2)); - vtkColorTransferFunction* colorTransferFunction3; - colorTransferFunction3 = m_Controls->m_ToFVisualisationSettingsWidget->GetWidget3ColorTransferFunction(); - mitk::TransferFunction::Pointer tf3 = mitk::TransferFunction::New(); - tf3->SetColorTransferFunction( colorTransferFunction3 ); - m_IntensityImageNode->SetProperty("Image Rendering.Transfer Function",mitk::TransferFunctionProperty::New(tf3)); - if (m_Controls->m_SurfaceCheckBox->isChecked()) { // update surface m_ToFDistanceImageToSurfaceFilter->SetTextureIndex(m_Controls->m_ToFVisualisationSettingsWidget->GetSelectedImageIndex()); this->m_Surface->Update(); vtkColorTransferFunction* colorTransferFunction = m_Controls->m_ToFVisualisationSettingsWidget->GetSelectedColorTransferFunction(); this->m_ToFSurfaceVtkMapper3D->SetVtkScalarsToColors(colorTransferFunction); if (this->m_SurfaceDisplayCount<2) { this->m_SurfaceNode->SetData(this->m_Surface); this->m_SurfaceNode->SetMapper(mitk::BaseRenderer::Standard3D, m_ToFSurfaceVtkMapper3D); mitk::RenderingManager::GetInstance()->InitializeViews( this->m_Surface->GetTimeSlicedGeometry(), mitk::RenderingManager::REQUEST_UPDATE_3DWINDOWS, true); mitk::Point3D surfaceCenter= this->m_Surface->GetGeometry()->GetCenter(); m_MultiWidget->mitkWidget4->GetRenderer()->GetVtkRenderer()->GetActiveCamera()->SetPosition(0,0,-50); m_MultiWidget->mitkWidget4->GetRenderer()->GetVtkRenderer()->GetActiveCamera()->SetViewUp(0,-1,0); m_MultiWidget->mitkWidget4->GetRenderer()->GetVtkRenderer()->GetActiveCamera()->SetFocalPoint(0,0,surfaceCenter[2]); m_MultiWidget->mitkWidget4->GetRenderer()->GetVtkRenderer()->GetActiveCamera()->SetViewAngle(40); m_MultiWidget->mitkWidget4->GetRenderer()->GetVtkRenderer()->GetActiveCamera()->SetClippingRange(1, 10000); } this->m_SurfaceDisplayCount++; } else { // update pipeline this->m_MitkDistanceImage->Update(); } mitk::RenderingManager::GetInstance()->RequestUpdateAll(); this->m_2DDisplayCount++; if ((this->m_2DDisplayCount % this->m_StepsForFramerate) == 0) { this->m_2DTimeAfter = this->m_RealTimeClock->GetCurrentStamp() - this->m_2DTimeBefore; MITK_INFO << " 2D-Display-framerate (fps): " << this->m_StepsForFramerate / (this->m_2DTimeAfter/1000); this->m_2DTimeBefore = this->m_RealTimeClock->GetCurrentStamp(); } } void QmitkToFUtilView::ProcessVideoTransform() { IplImage *src, *dst; src = cvCreateImageHeader(cvSize(this->m_VideoCaptureWidth, this->m_VideoCaptureHeight), IPL_DEPTH_8U, 3); src->imageData = (char*)this->m_VideoTexture; CvPoint2D32f srcTri[3], dstTri[3]; CvMat* rot_mat = cvCreateMat(2,3,CV_32FC1); CvMat* warp_mat = cvCreateMat(2,3,CV_32FC1); dst = cvCloneImage(src); dst->origin = src->origin; cvZero( dst ); int xOffset = 0;//m_Controls->m_XOffsetSpinBox->value(); int yOffset = 0;//m_Controls->m_YOffsetSpinBox->value(); int zoom = 0;//m_Controls->m_ZoomSpinBox->value(); // Compute warp matrix srcTri[0].x = 0 + zoom; srcTri[0].y = 0 + zoom; srcTri[1].x = src->width - 1 - zoom; srcTri[1].y = 0 + zoom; srcTri[2].x = 0 + zoom; srcTri[2].y = src->height - 1 - zoom; dstTri[0].x = 0; dstTri[0].y = 0; dstTri[1].x = src->width - 1; dstTri[1].y = 0; dstTri[2].x = 0; dstTri[2].y = src->height - 1; cvGetAffineTransform( srcTri, dstTri, warp_mat ); cvWarpAffine( src, dst, warp_mat ); cvCopy ( dst, src ); // Compute warp matrix srcTri[0].x = 0; srcTri[0].y = 0; srcTri[1].x = src->width - 1; srcTri[1].y = 0; srcTri[2].x = 0; srcTri[2].y = src->height - 1; dstTri[0].x = srcTri[0].x + xOffset; dstTri[0].y = srcTri[0].y + yOffset; dstTri[1].x = srcTri[1].x + xOffset; dstTri[1].y = srcTri[1].y + yOffset; dstTri[2].x = srcTri[2].x + xOffset; dstTri[2].y = srcTri[2].y + yOffset; cvGetAffineTransform( srcTri, dstTri, warp_mat ); cvWarpAffine( src, dst, warp_mat ); cvCopy ( dst, src ); src->imageData = NULL; cvReleaseImage( &src ); cvReleaseImage( &dst ); cvReleaseMat( &rot_mat ); cvReleaseMat( &warp_mat ); } void QmitkToFUtilView::OnTextureCheckBoxChecked(bool checked) { if(m_SurfaceNode.IsNotNull()) { if (checked) { this->m_SurfaceNode->SetBoolProperty("scalar visibility", true); } else { this->m_SurfaceNode->SetBoolProperty("scalar visibility", false); } } } void QmitkToFUtilView::OnVideoTextureCheckBoxChecked(bool checked) { if (checked) { if (this->m_VideoEnabled) { this->m_ToFSurfaceVtkMapper3D->SetTexture(this->m_VideoTexture); } else { this->m_ToFSurfaceVtkMapper3D->SetTexture(NULL); } } else { this->m_ToFSurfaceVtkMapper3D->SetTexture(NULL); } } mitk::DataNode::Pointer QmitkToFUtilView::ReplaceNodeData( std::string nodeName, mitk::BaseData* data ) { mitk::DataNode::Pointer node = this->GetDefaultDataStorage()->GetNamedNode(nodeName); if (node.IsNull()) { node = mitk::DataNode::New(); node->SetData(data); node->SetName(nodeName); + node->SetBoolProperty("binary",false); this->GetDefaultDataStorage()->Add(node); } else { node->SetData(data); } return node; } void QmitkToFUtilView::UseToFVisibilitySettings(bool useToF) { // set node properties if (m_DistanceImageNode.IsNotNull()) { this->m_DistanceImageNode->SetProperty( "visible" , mitk::BoolProperty::New( true )); this->m_DistanceImageNode->SetVisibility( !useToF, mitk::BaseRenderer::GetInstance(GetActiveStdMultiWidget()->mitkWidget2->GetRenderWindow() ) ); this->m_DistanceImageNode->SetVisibility( !useToF, mitk::BaseRenderer::GetInstance(GetActiveStdMultiWidget()->mitkWidget3->GetRenderWindow() ) ); this->m_DistanceImageNode->SetVisibility( !useToF, mitk::BaseRenderer::GetInstance(GetActiveStdMultiWidget()->mitkWidget4->GetRenderWindow() ) ); this->m_DistanceImageNode->SetBoolProperty("use color",!useToF); this->m_DistanceImageNode->GetPropertyList()->DeleteProperty("LookupTable"); } if (m_AmplitudeImageNode.IsNotNull()) { this->m_AmplitudeImageNode->SetProperty( "visible" , mitk::BoolProperty::New( true )); this->m_AmplitudeImageNode->SetVisibility( !useToF, mitk::BaseRenderer::GetInstance(GetActiveStdMultiWidget()->mitkWidget1->GetRenderWindow() ) ); this->m_AmplitudeImageNode->SetVisibility( !useToF, mitk::BaseRenderer::GetInstance(GetActiveStdMultiWidget()->mitkWidget3->GetRenderWindow() ) ); this->m_AmplitudeImageNode->SetVisibility( !useToF, mitk::BaseRenderer::GetInstance(GetActiveStdMultiWidget()->mitkWidget4->GetRenderWindow() ) ); this->m_AmplitudeImageNode->SetBoolProperty("use color",!useToF); this->m_AmplitudeImageNode->GetPropertyList()->DeleteProperty("LookupTable"); } if (m_IntensityImageNode.IsNotNull()) { this->m_IntensityImageNode->SetProperty( "visible" , mitk::BoolProperty::New( true )); this->m_IntensityImageNode->SetVisibility( !useToF, mitk::BaseRenderer::GetInstance(GetActiveStdMultiWidget()->mitkWidget1->GetRenderWindow() ) ); this->m_IntensityImageNode->SetVisibility( !useToF, mitk::BaseRenderer::GetInstance(GetActiveStdMultiWidget()->mitkWidget2->GetRenderWindow() ) ); this->m_IntensityImageNode->SetVisibility( !useToF, mitk::BaseRenderer::GetInstance(GetActiveStdMultiWidget()->mitkWidget4->GetRenderWindow() ) ); this->m_IntensityImageNode->SetBoolProperty("use color",!useToF); this->m_IntensityImageNode->GetPropertyList()->DeleteProperty("LookupTable"); } + if ((m_RGBImageNode.IsNotNull())) + { + this->m_RGBImageNode->SetProperty( "visible" , mitk::BoolProperty::New( true )); + this->m_RGBImageNode->SetVisibility( !useToF, mitk::BaseRenderer::GetInstance(GetActiveStdMultiWidget()->mitkWidget1->GetRenderWindow() ) ); + this->m_RGBImageNode->SetVisibility( !useToF, mitk::BaseRenderer::GetInstance(GetActiveStdMultiWidget()->mitkWidget2->GetRenderWindow() ) ); + this->m_RGBImageNode->SetVisibility( !useToF, mitk::BaseRenderer::GetInstance(GetActiveStdMultiWidget()->mitkWidget4->GetRenderWindow() ) ); + } // initialize images if (m_MitkDistanceImage.IsNotNull()) { mitk::RenderingManager::GetInstance()->InitializeViews( this->m_MitkDistanceImage->GetTimeSlicedGeometry(), mitk::RenderingManager::REQUEST_UPDATE_2DWINDOWS, true); } } diff --git a/Plugins/org.mitk.gui.qt.tofutil/src/internal/QmitkToFUtilView.h b/Plugins/org.mitk.gui.qt.tofutil/src/internal/QmitkToFUtilView.h index fde34de736..170c091911 100644 --- a/Plugins/org.mitk.gui.qt.tofutil/src/internal/QmitkToFUtilView.h +++ b/Plugins/org.mitk.gui.qt.tofutil/src/internal/QmitkToFUtilView.h @@ -1,169 +1,172 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #ifndef QmitkToFUtilView_h #define QmitkToFUtilView_h #include #include #include #include #include #include #include #include #include #include #include #include /*! \brief QmitkToFUtilView Application that allows simple playing, recording, visualization, processing and measurement of Time-of-Flight (ToF) data. Currently the following features are implemented:
  • Connecting and showing ToF data from various cameras (PMD CamCube 2/3, PMD CamBoard, PMD O3, MESA SwissRanger)
  • Recording and playing of ToF data
  • Color coded visualization of ToF images
  • Preprocessing of the distance data: Threshold, median, average and bilateral filtering; surface generation
  • Simple measurement and PointSet definition
\sa QmitkFunctionality \ingroup Functionalities */ class QmitkToFUtilView : public QmitkFunctionality { // this is needed for all Qt objects that should have a Qt meta-object // (everything that derives from QObject and wants to have signal/slots) Q_OBJECT public: static const std::string VIEW_ID; QmitkToFUtilView(); ~QmitkToFUtilView(); virtual void CreateQtPartControl(QWidget *parent); /// \brief Called when the functionality is activated virtual void Activated(); /// \brief Called when the functionality is deactivated virtual void Deactivated(); virtual void StdMultiWidgetAvailable (QmitkStdMultiWidget &stdMultiWidget); virtual void StdMultiWidgetNotAvailable(); protected slots: /*! \brief Slot triggered from the timer to update the images and visualization */ void OnUpdateCamera(); /*! \brief Slot called when the "Connect" button of the ConnectionWidget is pressed */ void OnToFCameraConnected(); /*! \brief Slot called when the "Disconnect" button of the ConnectionWidget is pressed */ void OnToFCameraDisconnected(); /*! \brief Slot called when the camera selection in the ConnectionWidget has changed */ void OnToFCameraSelected(const QString selected); /*! \brief Slot called when the "Start" button of the RecorderWidget is pressed */ void OnToFCameraStarted(); /*! \brief Slot called when the "Stop" button of the RecorderWidget is pressed */ void OnToFCameraStopped(); /*! \brief Slot invoked when the texture checkbox is checked. Enables the scalar visibility of the surface */ void OnTextureCheckBoxChecked(bool checked); /*! \brief Slot invoked when the video texture checkbox is checked. Enables the texture of the surface */ void OnVideoTextureCheckBoxChecked(bool checked); protected: /*! \brief initialize the visibility settings of ToF data (images + surface) \param useToF true: distance image: widget1, amplitude image: widget 2, intensity image: widget 3; false: standard */ void UseToFVisibilitySettings(bool useToF); Ui::QmitkToFUtilViewControls* m_Controls; QmitkStdMultiWidget* m_MultiWidget; QTimer* m_Frametimer; ///< Timer used to continuously update the images + QString m_SelectedCamera; ///< String holding the selected camera + mitk::Image::Pointer m_MitkDistanceImage; ///< member holding a pointer to the distance image of the selected camera mitk::Image::Pointer m_MitkAmplitudeImage; ///< member holding a pointer to the amplitude image of the selected camera mitk::Image::Pointer m_MitkIntensityImage; ///< member holding a pointer to the intensity image of the selected camera mitk::Surface::Pointer m_Surface; ///< member holding a pointer to the surface generated from the distance image of the selected camera mitk::DataNode::Pointer m_DistanceImageNode; ///< DataNode holding the distance image of the selected camera mitk::DataNode::Pointer m_AmplitudeImageNode; ///< DataNode holding the amplitude image of the selected camera mitk::DataNode::Pointer m_IntensityImageNode; ///< DataNode holding the intensity image of the selected camera + mitk::DataNode::Pointer m_RGBImageNode; ///< DataNode holding the rgb image of the selected camera mitk::DataNode::Pointer m_SurfaceNode; ///< DataNode holding the surface generated from the distanc image of the selected camera // ToF processing and recording filter mitk::ToFImageRecorder::Pointer m_ToFImageRecorder; ///< ToF image recorder used for lossless recording of ToF image data mitk::ToFImageGrabber::Pointer m_ToFImageGrabber; ///< Source of a ToF image processing pipeline. Provides pointers to distance, amplitude and intensity image mitk::ToFDistanceImageToSurfaceFilter::Pointer m_ToFDistanceImageToSurfaceFilter; ///< Filter for calculating a surface representation from a given distance image mitk::ToFCompositeFilter::Pointer m_ToFCompositeFilter; ///< Filter combining several processing steps (thresholding, Median filtering, Bilateral filtering) int m_SurfaceDisplayCount; ///< member used to determine whether surface is initialized or not int m_2DDisplayCount; ///< member used to determine whether frame rate output should be shown // members for calculating the frame rate mitk::RealTimeClock::Pointer m_RealTimeClock; ///< real time clock used to calculate the display framerate int m_StepsForFramerate; ///< number of steps used for calculating the display framerate double m_2DTimeBefore; ///< holds the time stamp at the beginning of the display framerate measurement double m_2DTimeAfter; ///< holds the time stamp at the end of the display framerate measurement // members used for displaying an external video source mitk::OpenCVVideoSource::Pointer m_VideoSource; ///< OpenCV video source to connect a video device unsigned char* m_VideoTexture; ///< texture used to show video image int m_VideoCaptureWidth; ///< width of the video image int m_VideoCaptureHeight; ///< height of the video image bool m_VideoEnabled; ///< flag indicating whether video grabbing is enabled. Set via the RGB texture checkbox private: /*! \brief helper method to replace data of the specified node. If node does not exist it will be created \param nodeName Name of the node \param data Data object to be replaced \return returns the node */ mitk::DataNode::Pointer ReplaceNodeData(std::string nodeName, mitk::BaseData* data); void ProcessVideoTransform(); mitk::ToFSurfaceVtkMapper3D::Pointer m_ToFSurfaceVtkMapper3D; }; #endif // _QMITKTOFUTILVIEW_H_INCLUDED