diff --git a/Modules/US/USModel/mitkUSVideoDevice.cpp b/Modules/US/USModel/mitkUSVideoDevice.cpp index 6fb485aaa7..225ce8d0c7 100644 --- a/Modules/US/USModel/mitkUSVideoDevice.cpp +++ b/Modules/US/USModel/mitkUSVideoDevice.cpp @@ -1,177 +1,190 @@ /*=================================================================== 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 "mitkUSVideoDevice.h" - +#include "mitkImageReadAccessor.h" mitk::USVideoDevice::USVideoDevice(int videoDeviceNumber, std::string manufacturer, std::string model) : mitk::USDevice(manufacturer, model) { Init(); m_SourceIsFile = false; m_DeviceID = videoDeviceNumber; m_FilePath = ""; } mitk::USVideoDevice::USVideoDevice(std::string videoFilePath, std::string manufacturer, std::string model) : mitk::USDevice(manufacturer, model) { Init(); m_SourceIsFile = true; m_FilePath = videoFilePath; } mitk::USVideoDevice::USVideoDevice(int videoDeviceNumber, mitk::USImageMetadata::Pointer metadata) : mitk::USDevice(metadata) { Init(); m_SourceIsFile = false; m_DeviceID = videoDeviceNumber; m_FilePath = ""; } mitk::USVideoDevice::USVideoDevice(std::string videoFilePath, mitk::USImageMetadata::Pointer metadata) : mitk::USDevice(metadata) { Init(); m_SourceIsFile = true; m_FilePath = videoFilePath; } mitk::USVideoDevice::~USVideoDevice() { - + m_MultiThreader->TerminateThread(m_ThreadID); } void mitk::USVideoDevice::Init() { m_Source = mitk::USImageVideoSource::New(); //this->SetNumberOfInputs(1); this->SetNumberOfOutputs(1); // mitk::USImage::Pointer output = mitk::USImage::New(); // output->Initialize(); this->SetNthOutput(0, this->MakeOutput(0)); this->m_MultiThreader = itk::MultiThreader::New(); this->m_ImageMutex = itk::FastMutexLock::New(); this->m_CameraActiveMutex= itk::FastMutexLock::New(); m_IsActive = false; } std::string mitk::USVideoDevice::GetDeviceClass(){ return "org.mitk.modules.us.USVideoDevice"; } - bool mitk::USVideoDevice::OnConnection() { if (m_SourceIsFile){ m_Source->SetVideoFileInput(m_FilePath); } else { m_Source->SetCameraInput(m_DeviceID); } SetSourceCropArea(); return true; } bool mitk::USVideoDevice::OnDisconnection() { if (m_IsActive) this->Deactivate(); return true; } - bool mitk::USVideoDevice::OnActivation() { // make sure that video device is ready before aquiring images if ( ! m_Source->GetIsReady() ) { MITK_WARN("mitkUSDevice")("mitkUSVideoDevice") << "Could not activate us video device. Check if video grabber is configured correctly."; return false; } MITK_INFO << "Activated UsVideoDevice!"; this->m_ThreadID = this->m_MultiThreader->SpawnThread(this->Acquire, this); return true; } - void mitk::USVideoDevice::OnDeactivation() { // happens automatically when m_Active is set to false } void mitk::USVideoDevice::GenerateData() { - mitk::USImage::Pointer result; - result = m_Image; + m_ImageMutex->Lock(); + + if ( m_Image.IsNull() || ! m_Image->IsInitialized() ) { m_ImageMutex->Unlock(); return; } + + mitk::USImage::Pointer result = this->GetOutput(); + + if ( ! result->IsInitialized() ) + { + result->Initialize(m_Image->GetPixelType(), m_Image->GetDimension(), m_Image->GetDimensions()); + } + + mitk::ImageReadAccessor inputReadAccessor(m_Image.GetPointer(), m_Image->GetSliceData(0,0,0)); + result->SetSlice(inputReadAccessor.GetData()); + + m_ImageMutex->Unlock(); // Set Metadata result->SetMetadata(this->m_Metadata); //Apply Transformation this->ApplyCalibration(result); // Set Output this->SetNthOutput(0, result); } void mitk::USVideoDevice::GrabImage() { - m_Image = m_Source->GetNextImage(); + mitk::USImage::Pointer image = m_Source->GetNextImage(); + + this->m_ImageMutex->Lock(); + m_Image = image; + this->m_ImageMutex->Unlock(); + //this->SetNthOutput(0, m_Image); //this->Modified(); } void mitk::USVideoDevice::SetSourceCropArea() { if (this->m_Source.IsNotNull()) { if((m_CropArea.cropBottom==0)&& (m_CropArea.cropTop==0)&& (m_CropArea.cropLeft==0)&& (m_CropArea.cropRight==0)) {this->m_Source->RemoveRegionOfInterest();} else { int right = m_Source->GetImageWidth() - m_CropArea.cropRight; int bottom = m_Source->GetImageHeight() - m_CropArea.cropBottom; this->m_Source->SetRegionOfInterest(m_CropArea.cropLeft, m_CropArea.cropTop, right, bottom); } - } else {MITK_WARN << "Cannot set crop are, source is not initialized!";} - } void mitk::USVideoDevice::SetCropArea(mitk::USDevice::USImageCropArea newArea) { m_CropArea = newArea; MITK_INFO << "Set Crop Area L:" << m_CropArea.cropLeft << " R:" << m_CropArea.cropRight << " T:" << m_CropArea.cropTop << " B:" << m_CropArea.cropBottom; if (m_IsConnected) SetSourceCropArea(); } ITK_THREAD_RETURN_TYPE mitk::USVideoDevice::Acquire(void* pInfoStruct) { /* extract this pointer from Thread Info structure */ struct itk::MultiThreader::ThreadInfoStruct * pInfo = (struct itk::MultiThreader::ThreadInfoStruct*)pInfoStruct; mitk::USVideoDevice * device = (mitk::USVideoDevice *) pInfo->UserData; while (device->GetIsActive()) { device->GrabImage(); } return ITK_THREAD_RETURN_VALUE; } diff --git a/Modules/US/USModel/mitkUSVideoDevice.h b/Modules/US/USModel/mitkUSVideoDevice.h index fa7ef2f703..fddcb3d9ee 100644 --- a/Modules/US/USModel/mitkUSVideoDevice.h +++ b/Modules/US/USModel/mitkUSVideoDevice.h @@ -1,154 +1,149 @@ /*=================================================================== 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 MITKUSVideoDevice_H_HEADER_INCLUDED_ #define MITKUSVideoDevice_H_HEADER_INCLUDED_ #include #include #include "mitkUSDevice.h" #include #include "mitkUSImageVideoSource.h" namespace mitk { - /**Documentation * \brief A VideoDevice is the common class for video only devices. They capture Video Input either from * a file or from a device, and transform the output into an mitkUSImage with attached Metadata. * This simple implementation does only capture and display 2D Images without cropping or registration. * One can simply inherit from this class and overwrite the handle2D and handle 3Dmethods to get full access to the data * \ingroup US */ class MitkUS_EXPORT USVideoDevice : public mitk::USDevice { public: mitkClassMacro(USVideoDevice, mitk::USDevice); // To open a device (DeviceID, Manufacturer, Model) mitkNewMacro3Param(Self, int, std::string, std::string); // To open A VideoFile (Path, Manufacturer, Model) mitkNewMacro3Param(Self, std::string, std::string, std::string); // To open a device (DeviceID, Metadata) mitkNewMacro2Param(Self, int, mitk::USImageMetadata::Pointer); // To open A VideoFile (Path, Metadata) mitkNewMacro2Param(Self, std::string, mitk::USImageMetadata::Pointer); /*@brief Sets the area that will be cropped from the US image. Set [0,0,0,0] to disable it, which is also default. */ void SetCropArea(mitk::USDevice::USImageCropArea newArea); /** * \brief Returns the qualified name of this class. Be sure to override this when inheriting from VideoDevice! */ virtual std::string GetDeviceClass(); void GenerateData(); itkGetMacro(Source, mitk::USImageVideoSource::Pointer); itkGetMacro(Image, mitk::USImage::Pointer); itkGetMacro(DeviceID,int); itkGetMacro(FilePath,std::string); void GrabImage(); protected: static ITK_THREAD_RETURN_TYPE Acquire(void* pInfoStruct); - - /** * \brief Creates a new device that will deliver USImages taken from a video device. * under windows, try -1 for device number, which will grab the first available one * (Open CV functionality) */ USVideoDevice(int videoDeviceNumber, std::string manufacturer, std::string model); /** * \brief Creates a new device that will deliver USImages taken from a video file. */ USVideoDevice(std::string videoFilePath, std::string manufacturer, std::string model); /** * \brief Creates a new device that will deliver USImages taken from a video device. * under windows, try -1 for device number, which will grab the first available one * (Open CV functionality) */ USVideoDevice(int videoDeviceNumber, mitk::USImageMetadata::Pointer metadata); /** * \brief Creates a new device that will deliver USImages taken from a video file. */ USVideoDevice(std::string videoFilePath, mitk::USImageMetadata::Pointer metadata); virtual ~USVideoDevice(); /** * \brief Initializes common properties for all constructors. */ void Init(); /** * \brief Is called during the connection process. * Returns true if successful and false if unsuccessful. Additionally, you may throw an exception to clarify what went wrong. */ virtual bool OnConnection(); /** * \brief Is called during the disconnection process. * Returns true if successful and false if unsuccessful. Additionally, you may throw an exception to clarify what went wrong. */ virtual bool OnDisconnection(); /** * \brief Is called during the activation process. After this method is finsihed, the device should be generating images */ virtual bool OnActivation(); - /** * \brief Is called during the deactivation process. After a call to this method the device should still be connected, but not producing images anymore. */ virtual void OnDeactivation(); /** * \brief The image source that we use to aquire data */ mitk::USImageVideoSource::Pointer m_Source; /** * \brief True, if this source plays back a file, false if it recieves data from a device */ bool m_SourceIsFile; /** * \brief The device id to connect to. Undefined, if m_SourceIsFile == true; */ int m_DeviceID; /** * \brief The Filepath id to connect to. Undefined, if m_SourceIsFile == false; */ std::string m_FilePath; void SetSourceCropArea(); // Threading-Related 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 mitk::USImage::Pointer m_Image; - + mitk::USImage::Pointer m_OutputImage; }; } // namespace mitk #endif