diff --git a/Modules/US/USModel/mitkUSDevice.cpp b/Modules/US/USModel/mitkUSDevice.cpp index 75e1e80bbe..784320ddba 100644 --- a/Modules/US/USModel/mitkUSDevice.cpp +++ b/Modules/US/USModel/mitkUSDevice.cpp @@ -1,529 +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. ===================================================================*/ #include "mitkUSDevice.h" #include "mitkImageReadAccessor.h" // US Control Interfaces #include "mitkUSControlInterfaceProbes.h" #include "mitkUSControlInterfaceBMode.h" #include "mitkUSControlInterfaceDoppler.h" // Microservices #include #include #include #include mitk::USDevice::PropertyKeys mitk::USDevice::GetPropertyKeys() { static mitk::USDevice::PropertyKeys propertyKeys; return propertyKeys; } mitk::USDevice::USImageCropArea mitk::USDevice::GetCropArea() { MITK_INFO << "Return Crop Area L:" << m_CropArea.cropLeft << " R:" << m_CropArea.cropRight << " T:" << m_CropArea.cropTop << " B:" << m_CropArea.cropBottom; return m_CropArea; } mitk::USDevice::USDevice(std::string manufacturer, std::string model) : mitk::ImageSource(), + m_Manufacturer(manufacturer), + m_Name(model), m_IsFreezed(false), m_DeviceState(State_NoState), m_SpawnAcquireThread(true), m_MultiThreader(itk::MultiThreader::New()), m_ImageMutex(itk::FastMutexLock::New()), m_ThreadID(-1), m_UnregisteringStarted(false) { - // Initialize Members - m_Metadata = mitk::USImageMetadata::New(); - m_Metadata->SetDeviceManufacturer(manufacturer); - m_Metadata->SetDeviceModel(model); - USImageCropArea empty; empty.cropBottom = 0; empty.cropTop = 0; empty.cropLeft = 0; empty.cropRight = 0; this->m_CropArea = empty; //set number of outputs this->SetNumberOfIndexedOutputs(1); //create a new output mitk::Image::Pointer newOutput = mitk::Image::New(); this->SetNthOutput(0,newOutput); } mitk::USDevice::USDevice(mitk::USImageMetadata::Pointer metadata) : mitk::ImageSource(), m_IsFreezed(false), m_DeviceState(State_NoState), m_SpawnAcquireThread(true), m_MultiThreader(itk::MultiThreader::New()), m_ImageMutex(itk::FastMutexLock::New()), m_ThreadID(-1), m_UnregisteringStarted(false) { - m_Metadata = metadata; + m_Manufacturer = metadata->GetDeviceManufacturer(); + m_Name = metadata->GetDeviceModel(); + m_Comment = metadata->GetDeviceComment(); USImageCropArea empty; empty.cropBottom = 0; empty.cropTop = 0; empty.cropLeft = 0; empty.cropRight = 0; this->m_CropArea = empty; //set number of outputs this->SetNumberOfIndexedOutputs(1); //create a new output mitk::Image::Pointer newOutput = mitk::Image::New(); this->SetNthOutput(0,newOutput); } mitk::USDevice::~USDevice() { if (m_ThreadID >= 0) { m_MultiThreader->TerminateThread(m_ThreadID); } // make sure that the us device is not registered at the micro service // anymore after it is destructed this->UnregisterOnService(); } mitk::USAbstractControlInterface::Pointer mitk::USDevice::GetControlInterfaceCustom() { MITK_INFO << "Custom control interface does not exist for this object."; return 0; } mitk::USControlInterfaceBMode::Pointer mitk::USDevice::GetControlInterfaceBMode() { MITK_INFO << "Control interface BMode does not exist for this object."; return 0; } mitk::USControlInterfaceProbes::Pointer mitk::USDevice::GetControlInterfaceProbes() { MITK_INFO << "Control interface Probes does not exist for this object."; return 0; } mitk::USControlInterfaceDoppler::Pointer mitk::USDevice::GetControlInterfaceDoppler() { MITK_INFO << "Control interface Doppler does not exist for this object."; return 0; } us::ServiceProperties mitk::USDevice::ConstructServiceProperties() { mitk::USDevice::PropertyKeys propertyKeys = mitk::USDevice::GetPropertyKeys(); us::ServiceProperties props; props[propertyKeys.US_PROPKEY_ISCONNECTED] = this->GetIsConnected() ? "true" : "false"; props[propertyKeys.US_PROPKEY_ISACTIVE] = this->GetIsActive() ? "true" : "false"; props[propertyKeys.US_PROPKEY_LABEL] = this->GetServicePropertyLabel(); // get identifier of selected probe if there is one selected mitk::USControlInterfaceProbes::Pointer probesControls = this->GetControlInterfaceProbes(); if (probesControls.IsNotNull() && probesControls->GetIsActive()) { mitk::USProbe::Pointer probe = probesControls->GetSelectedProbe(); if (probe.IsNotNull()) { props[propertyKeys.US_PROPKEY_PROBES_SELECTED] = probe->GetName(); } } props[ propertyKeys.US_PROPKEY_CLASS ] = GetDeviceClass(); - props[ mitk::USImageMetadata::PROP_DEV_MANUFACTURER ] = m_Metadata->GetDeviceManufacturer(); - props[ mitk::USImageMetadata::PROP_DEV_MODEL ] = m_Metadata->GetDeviceModel(); - props[ mitk::USImageMetadata::PROP_DEV_COMMENT ] = m_Metadata->GetDeviceComment(); - props[ mitk::USImageMetadata::PROP_PROBE_NAME ] = m_Metadata->GetProbeName(); - props[ mitk::USImageMetadata::PROP_PROBE_FREQUENCY ] = m_Metadata->GetProbeFrequency(); - props[ mitk::USImageMetadata::PROP_ZOOM ] = m_Metadata->GetZoom(); + props[ propertyKeys.US_PROPKEY_MANUFACTURER ] = m_Manufacturer; + props[ propertyKeys.US_PROPKEY_NAME ] = m_Name; + props[ propertyKeys.US_PROPKEY_COMMENT ] = m_Comment; m_ServiceProperties = props; return props; } void mitk::USDevice::UnregisterOnService() { // unregister on micro service if ( m_ServiceRegistration && ! m_UnregisteringStarted) { // make sure that unregister is not started a second // time due to a callback during unregister for example m_UnregisteringStarted = true; m_ServiceRegistration.Unregister(); m_ServiceRegistration = 0; } } bool mitk::USDevice::Initialize() { if (! this->OnInitialization() ) { return false; } m_DeviceState = State_Initialized; // Get Context and Module us::ModuleContext* context = us::GetModuleContext(); us::ServiceProperties props = this->ConstructServiceProperties(); m_ServiceRegistration = context->RegisterService(this, props); return true; } bool mitk::USDevice::Connect() { if ( this->GetIsConnected() ) { MITK_INFO("mitkUSDevice") << "Tried to connect an ultrasound device that was already connected. Ignoring call..."; return true; } if ( ! this->GetIsInitialized() ) { MITK_ERROR("mitkUSDevice") << "Cannot connect device if it is not in initialized state."; return false; } // Prepare connection, fail if this fails. if ( ! this->OnConnection() ) { return false; } // Update state m_DeviceState = State_Connected; this->UpdateServiceProperty(mitk::USDevice::GetPropertyKeys().US_PROPKEY_ISCONNECTED, true); return true; } void mitk::USDevice::ConnectAsynchron() { this->m_MultiThreader->SpawnThread(this->ConnectThread, this); } bool mitk::USDevice::Disconnect() { if ( ! GetIsConnected()) { MITK_WARN << "Tried to disconnect an ultrasound device that was not connected. Ignoring call..."; return false; } // Prepare connection, fail if this fails. if (! this->OnDisconnection()) return false; // Update state m_DeviceState = State_Initialized; this->UpdateServiceProperty(mitk::USDevice::GetPropertyKeys().US_PROPKEY_ISCONNECTED, false); return true; } bool mitk::USDevice::Activate() { if (! this->GetIsConnected()) { MITK_INFO("mitkUSDevice") << "Cannot activate device if it is not in connected state."; return true; } if ( OnActivation() ) { m_DeviceState = State_Activated; m_FreezeBarrier = itk::ConditionVariable::New(); // spawn thread for aquire images if us device is active if (m_SpawnAcquireThread) { this->m_ThreadID = this->m_MultiThreader->SpawnThread(this->Acquire, this); } this->UpdateServiceProperty(mitk::USDevice::GetPropertyKeys().US_PROPKEY_ISACTIVE, true); this->UpdateServiceProperty(mitk::USDevice::GetPropertyKeys().US_PROPKEY_LABEL, this->GetServicePropertyLabel()); } return m_DeviceState == State_Activated; } void mitk::USDevice::Deactivate() { if ( ! this->GetIsActive() ) { MITK_WARN("mitkUSDevice") << "Cannot deactivate a device which is not activae."; return; } if ( ! OnDeactivation() ) { return; } m_DeviceState = State_Connected; this->UpdateServiceProperty(mitk::USDevice::GetPropertyKeys().US_PROPKEY_ISACTIVE, false); this->UpdateServiceProperty(mitk::USDevice::GetPropertyKeys().US_PROPKEY_LABEL, this->GetServicePropertyLabel()); } void mitk::USDevice::SetIsFreezed(bool freeze) { if ( ! this->GetIsActive() ) { MITK_WARN("mitkUSDevice") << "Cannot freeze or unfreeze if device is not active."; return; } this->OnFreeze(freeze); if ( freeze ) { m_IsFreezed = true; } else { m_IsFreezed = false; // wake up the image acquisition thread m_FreezeBarrier->Signal(); } } bool mitk::USDevice::GetIsFreezed() { if ( ! this->GetIsActive() ) { MITK_WARN("mitkUSDevice")("mitkUSTelemedDevice") << "Cannot get freeze state if the hardware interface is not ready. Returning false..."; return false; } return m_IsFreezed; } void mitk::USDevice::PushFilter(AbstractOpenCVImageFilter::Pointer filter) { mitk::USImageSource::Pointer imageSource = this->GetUSImageSource(); if ( imageSource.IsNull() ) { MITK_ERROR << "ImageSource must not be null when pushing a filter."; mitkThrow() << "ImageSource must not be null when pushing a filter."; } imageSource->PushFilter(filter); } void mitk::USDevice::PushFilterIfNotPushedBefore(AbstractOpenCVImageFilter::Pointer filter) { mitk::USImageSource::Pointer imageSource = this->GetUSImageSource(); if ( imageSource.IsNull() ) { MITK_ERROR << "ImageSource must not be null when pushing a filter."; mitkThrow() << "ImageSource must not be null when pushing a filter."; } if ( ! imageSource->GetIsFilterInThePipeline(filter) ) { imageSource->PushFilter(filter); } } bool mitk::USDevice::RemoveFilter(AbstractOpenCVImageFilter::Pointer filter) { mitk::USImageSource::Pointer imageSource = this->GetUSImageSource(); if ( imageSource.IsNull() ) { MITK_ERROR << "ImageSource must not be null when pushing a filter."; mitkThrow() << "ImageSource must not be null when removing a filter."; } return imageSource->RemoveFilter(filter); } void mitk::USDevice::UpdateServiceProperty(std::string key, std::string value) { m_ServiceProperties[ key ] = value; m_ServiceRegistration.SetProperties(m_ServiceProperties); } void mitk::USDevice::UpdateServiceProperty(std::string key, double value) { std::stringstream stream; stream << value; this->UpdateServiceProperty(key, stream.str()); } void mitk::USDevice::UpdateServiceProperty(std::string key, bool value) { this->UpdateServiceProperty(key, value ? std::string("true") : std::string("false")); } /** mitk::Image* mitk::USDevice::GetOutput() { if (this->GetNumberOfOutputs() < 1) return NULL; return static_cast(this->ProcessObject::GetPrimaryOutput()); } mitk::Image* mitk::USDevice::GetOutput(unsigned int idx) { if (this->GetNumberOfOutputs() < 1) return NULL; return static_cast(this->ProcessObject::GetOutput(idx)); } void mitk::USDevice::GraftOutput(itk::DataObject *graft) { this->GraftNthOutput(0, graft); } void mitk::USDevice::GraftNthOutput(unsigned int idx, itk::DataObject *graft) { if ( idx >= this->GetNumberOfOutputs() ) { itkExceptionMacro(<<"Requested to graft output " << idx << " but this filter only has " << this->GetNumberOfOutputs() << " Outputs."); } if ( !graft ) { itkExceptionMacro(<<"Requested to graft output with a NULL pointer object" ); } itk::DataObject* output = this->GetOutput(idx); if ( !output ) { itkExceptionMacro(<<"Requested to graft output that is a NULL pointer" ); } // Call Graft on USImage to copy member data output->Graft( graft ); } */ void mitk::USDevice::GrabImage() { mitk::Image::Pointer image = this->GetUSImageSource()->GetNextImage(); m_ImageMutex->Lock(); this->SetImage(image); m_ImageMutex->Unlock(); } //########### GETTER & SETTER ##################// bool mitk::USDevice::GetIsInitialized() { return m_DeviceState == State_Initialized; } bool mitk::USDevice::GetIsActive() { return m_DeviceState == State_Activated; } bool mitk::USDevice::GetIsConnected() { return m_DeviceState == State_Connected; } std::string mitk::USDevice::GetDeviceManufacturer(){ - return this->m_Metadata->GetDeviceManufacturer(); + return m_Manufacturer; } std::string mitk::USDevice::GetDeviceModel(){ - return this->m_Metadata->GetDeviceModel(); + return m_Name; } std::string mitk::USDevice::GetDeviceComment(){ - return this->m_Metadata->GetDeviceComment(); + return m_Comment; } void mitk::USDevice::GenerateData() { m_ImageMutex->Lock(); if ( m_Image.IsNull() || ! m_Image->IsInitialized() ) { m_ImageMutex->Unlock(); return; } mitk::Image::Pointer output = this->GetOutput(); if ( ! output->IsInitialized() || output->GetDimension(0) != m_Image->GetDimension(0) || output->GetDimension(1) != m_Image->GetDimension(1) ) { output->Initialize(m_Image->GetPixelType(), m_Image->GetDimension(), m_Image->GetDimensions()); } mitk::ImageReadAccessor inputReadAccessor(m_Image, m_Image->GetSliceData(0,0,0)); output->SetSlice(inputReadAccessor.GetData()); m_ImageMutex->Unlock(); }; std::string mitk::USDevice::GetServicePropertyLabel() { std::string isActive; if (this->GetIsActive()) { isActive = " (Active)"; } else { isActive = " (Inactive)"; } // e.g.: Zonare MyLab5 (Active) - return m_Metadata->GetDeviceManufacturer() + " " + m_Metadata->GetDeviceModel() + isActive; + return m_Manufacturer + " " + m_Name + isActive; } ITK_THREAD_RETURN_TYPE mitk::USDevice::Acquire(void* pInfoStruct) { /* extract this pointer from Thread Info structure */ struct itk::MultiThreader::ThreadInfoStruct * pInfo = (struct itk::MultiThreader::ThreadInfoStruct*)pInfoStruct; mitk::USDevice* device = (mitk::USDevice*) pInfo->UserData; while (device->GetIsActive()) { // lock this thread when ultrasound device is freezed if ( device->m_IsFreezed ) { itk::SimpleMutexLock* mutex = &(device->m_FreezeMutex); mutex->Lock(); if (device->m_FreezeBarrier.IsNotNull()) { device->m_FreezeBarrier->Wait(mutex); } } device->GrabImage(); } return ITK_THREAD_RETURN_VALUE; } ITK_THREAD_RETURN_TYPE mitk::USDevice::ConnectThread(void* pInfoStruct) { /* extract this pointer from Thread Info structure */ struct itk::MultiThreader::ThreadInfoStruct * pInfo = (struct itk::MultiThreader::ThreadInfoStruct*)pInfoStruct; mitk::USDevice* device = (mitk::USDevice*) pInfo->UserData; device->Connect(); return ITK_THREAD_RETURN_VALUE; } diff --git a/Modules/US/USModel/mitkUSDevice.h b/Modules/US/USModel/mitkUSDevice.h index 3d50dbd980..d81a4e2a68 100644 --- a/Modules/US/USModel/mitkUSDevice.h +++ b/Modules/US/USModel/mitkUSDevice.h @@ -1,413 +1,423 @@ /*=================================================================== 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 MITKUSDevice_H_HEADER_INCLUDED_ #define MITKUSDevice_H_HEADER_INCLUDED_ // STL #include // MitkUS #include "mitkUSProbe.h" -#include "mitkUSImageMetadata.h" #include #include "mitkUSImageSource.h" // MITK #include #include // ITK #include #include // Microservices #include #include #include +// DEPRECATED +#include "mitkUSImageMetadata.h" + namespace itk { template class SmartPointer; } namespace mitk { class USAbstractControlInterface; class USControlInterfaceBMode; class USControlInterfaceProbes; class USControlInterfaceDoppler; /** * \brief A device holds information about it's model, make and the connected probes. It is the * common super class for all devices and acts as an image source for mitkUSImages. It is the base class * for all US Devices, and every new device should extend it. * * US Devices support output of calibrated images, i.e. images that include a specific geometry. * To achieve this, call SetCalibration, and make sure that the subclass also calls apply * transformation at some point (The USDevice does not automatically apply the transformation to the image) * * Note that USDevices will be removed from micro servive when their * destructor is called. Registering into micro service is done when * mitk::USDevice::Initialize() is called. * * \ingroup US */ class MitkUS_EXPORT USDevice : public mitk::ImageSource { public: enum DeviceStates { State_NoState, State_Initialized, State_Connected, State_Activated }; mitkClassMacro(USDevice, mitk::ImageSource); struct USImageCropArea { int cropLeft; int cropRight; int cropBottom; int cropTop; }; /** * \brief These constants are used in conjunction with Microservices. * The constants aren't defined as static member attributes to avoid the * "static initialization order fiasco", which would occur when objects of * this class are used in module activators (for restoring stored device, * for example). */ struct PropertyKeys { const std::string US_INTERFACE_NAME; // Common Interface name of all US Devices. Used to refer to this device via Microservices + const std::string US_PROPKEY_MANUFACTURER; + const std::string US_PROPKEY_NAME; + const std::string US_PROPKEY_COMMENT; const std::string US_PROPKEY_LABEL; // Human readable text represntation of this device const std::string US_PROPKEY_ISCONNECTED; // Whether this device is connected or not. const std::string US_PROPKEY_ISACTIVE; // Whether this device is active or not. const std::string US_PROPKEY_CLASS; // Class Name of this Object const std::string US_PROPKEY_PROBES_SELECTED; const std::string US_PROPKEY_BMODE_FREQUENCY; const std::string US_PROPKEY_BMODE_POWER; const std::string US_PROPKEY_BMODE_DEPTH; const std::string US_PROPKEY_BMODE_GAIN; const std::string US_PROPKEY_BMODE_REJECTION; const std::string US_PROPKEY_BMODE_DYNAMIC_RANGE; PropertyKeys() : US_INTERFACE_NAME("org.mitk.services.UltrasoundDevice"), + US_PROPKEY_MANUFACTURER(US_INTERFACE_NAME + ".manufacturer"), + US_PROPKEY_NAME(US_INTERFACE_NAME + ".name"), US_PROPKEY_LABEL(US_INTERFACE_NAME + ".label"), + US_PROPKEY_COMMENT(US_INTERFACE_NAME + ".comment"), US_PROPKEY_ISCONNECTED(US_INTERFACE_NAME + ".isConnected"), US_PROPKEY_ISACTIVE(US_INTERFACE_NAME + ".isActive"), US_PROPKEY_CLASS(US_INTERFACE_NAME + ".class"), US_PROPKEY_PROBES_SELECTED(US_INTERFACE_NAME + ".probes.selected"), US_PROPKEY_BMODE_FREQUENCY(US_INTERFACE_NAME + ".bmode.frequency"), US_PROPKEY_BMODE_POWER(US_INTERFACE_NAME + ".bmode.power"), US_PROPKEY_BMODE_DEPTH(US_INTERFACE_NAME + ".bmode.depth"), US_PROPKEY_BMODE_GAIN(US_INTERFACE_NAME + ".bmode.gain"), US_PROPKEY_BMODE_REJECTION(US_INTERFACE_NAME + ".bmode.rejection"), US_PROPKEY_BMODE_DYNAMIC_RANGE(US_INTERFACE_NAME + ".bmode.dynamicRange") {} }; /** * \return keys for the microservice properties of ultrasound devices */ static mitk::USDevice::PropertyKeys GetPropertyKeys(); /** * \brief Default getter for the custom control interface. * Has to be implemented in a subclass if a custom control interface is * available. Default implementation returns null. * * \return null pointer */ virtual itk::SmartPointer GetControlInterfaceCustom(); /** * \brief Default getter for the b mode control interface. * Has to be implemented in a subclass if a b mode control interface is * available. Default implementation returns null. * * \return null pointer */ virtual itk::SmartPointer GetControlInterfaceBMode(); /** * \brief Default getter for the probes control interface. * Has to be implemented in a subclass if a probes control interface is * available. Default implementation returns null. * * \return null pointer */ virtual itk::SmartPointer GetControlInterfaceProbes(); /** * \brief Default getter for the doppler control interface. * Has to be implemented in a subclass if a doppler control interface is * available. Default implementation returns null. * * \return null pointer */ virtual itk::SmartPointer GetControlInterfaceDoppler(); /** * \brief Changes device state to mitk::USDevice::State_Initialized. * During initialization the virtual method * mitk::USDevice::OnInitialization will be called. If this method * returns false the initialization process will be canceled. Otherwise * the mitk::USDevice is registered in a micro service. */ bool Initialize(); /** * \brief Connects this device. A connected device is ready to deliver images (i.e. be Activated). A Connected Device can be active. A disconnected Device cannot be active. * Internally calls onConnect and then registers the device with the service. A device usually should * override the OnConnection() method, but never the Connect() method, since this will possibly exclude the device * from normal service management. The exact flow of events is: * 0. Check if the device is already connected. If yes, return true anyway, but don't do anything. * 1. Call OnConnection() Here, a device should establish it's connection with the hardware Afterwards, it should be ready to start transmitting images at any time. * 2. If OnConnection() returns true ("successful"), then the device is registered with the service. * 3. if not, it the method itself returns false or may throw an expection, depeneding on the device implementation. * */ bool Connect(); void ConnectAsynchron(); /** * \brief Works analogously to mitk::USDevice::Connect(). Don't override this Method, but onDisconnection instead. */ bool Disconnect(); /** * \brief Activates this device. * After the activation process, the device will start to produce images. * This Method will fail, if the device is not connected. */ bool Activate(); /** * \brief Deactivates this device. * After the deactivation process, the device will no longer produce * images, but still be connected. */ void Deactivate(); /** * \brief Can toggle if ultrasound image is currently updated or freezed. * * \param freeze true to stop updating the ultrasound image, false to start updating again */ virtual void SetIsFreezed(bool freeze); /** * \return true if device is currently freezed (no image update is done), false otherwise */ virtual bool GetIsFreezed(); void PushFilter(AbstractOpenCVImageFilter::Pointer filter); void PushFilterIfNotPushedBefore(AbstractOpenCVImageFilter::Pointer filter); bool RemoveFilter(AbstractOpenCVImageFilter::Pointer filter); /** * \brief Given property is updated in the device micro service. * This method is mainly for being used by the control interface * superclasses. You do not need to call it by yoursefs in your * concrete control interface classes. */ void UpdateServiceProperty(std::string key, std::string value); void UpdateServiceProperty(std::string key, double value); void UpdateServiceProperty(std::string key, bool value); //########### GETTER & SETTER ##################// /** * \brief Returns the Class of the Device. This Method must be reimplemented by every Inheriting Class. */ virtual std::string GetDeviceClass() = 0; /** * \brief True, if the device object is created and initialized, false otherwise. */ bool GetIsInitialized(); /** * \brief True, if the device is currently generating image data, false otherwise. */ bool GetIsActive(); /** * \brief True, if the device is currently ready to start transmitting image data or is already * transmitting image data. A disconnected device cannot be activated. */ bool GetIsConnected(); /* @return Returns the area that will be cropped from the US image. Is disabled / [0,0,0,0] by default. */ mitk::USDevice::USImageCropArea GetCropArea(); - std::string GetDeviceManufacturer(); - std::string GetDeviceModel(); - std::string GetDeviceComment(); + /** \brief Deprecated -> use GetManufacturer() instead */ + DEPRECATED(std::string GetDeviceManufacturer()); + /** \brief Deprecated -> use GetName() instead */ + DEPRECATED(std::string GetDeviceModel()); + /** \brief Deprecated -> use GetCommend() instead */ + DEPRECATED(std::string GetDeviceComment()); + + itkGetMacro(Manufacturer, std::string); + itkGetMacro(Name, std::string); + itkGetMacro(Comment, std::string); itkGetMacro(DeviceState, DeviceStates); void GrabImage(); virtual USImageSource::Pointer GetUSImageSource() = 0; protected: itkSetMacro(Image, mitk::Image::Pointer); itkSetMacro(SpawnAcquireThread, bool); itkGetMacro(SpawnAcquireThread, bool); static ITK_THREAD_RETURN_TYPE Acquire(void* pInfoStruct); static ITK_THREAD_RETURN_TYPE ConnectThread(void* pInfoStruct); mitk::Image::Pointer m_Image; mitk::Image::Pointer m_OutputImage; bool m_IsFreezed; DeviceStates m_DeviceState; /* @brief defines the area that should be cropped from the US image */ USImageCropArea m_CropArea; /** * \brief This Method constructs the service properties which can later be used to * register the object with the Microservices * Return service properties */ us::ServiceProperties ConstructServiceProperties(); /** * \brief Remove this device from the micro service. */ void UnregisterOnService(); /** * \brief Is called during the initialization process. * Override this method in a subclass to handle the actual initialization. * If it returns false, the initialization process will be canceled. * * \return true if successful and false if unsuccessful * \throw mitk::Exception implementation may throw an exception to clarify what went wrong */ virtual bool OnInitialization() = 0; /** * \brief Is called during the connection process. * Override this method in a subclass to handle the actual connection. * If it returns false, the connection process will be canceled. * * \return true if successful and false if unsuccessful * \throw mitk::Exception implementation may throw an exception to clarify what went wrong */ virtual bool OnConnection() = 0; /** * \brief Is called during the disconnection process. * Override this method in a subclass to handle the actual disconnection. * If it returns false, the disconnection process will be canceled. * * \return true if successful and false if unsuccessful * \throw mitk::Exception implementation may throw an exception to clarify what went wrong */ virtual bool OnDisconnection() = 0; /** * \brief Is called during the activation process. * After this method is finished, the device should be generating images. * If it returns false, the activation process will be canceled. * * \return true if successful and false if unsuccessful * \throw mitk::Exception implementation may throw an exception to clarify what went wrong */ virtual bool OnActivation() = 0; /** * \brief Is called during the deactivation process. * After a call to this method the device should still be connected, * but not producing images anymore. * * \return true if successful and false if unsuccessful * \throw mitk::Exception implementation may throw an exception to clarify what went wrong */ virtual bool OnDeactivation() = 0; /** * \brief Called when mitk::USDevice::SetIsFreezed() is called. * Subclasses can overwrite this method to do additional actions. Default * implementation does noting. */ virtual void OnFreeze(bool) { } - /** - * \brief This metadata set is privately used to imprint USImages with Metadata later. - * At instantiation time, it only contains Information about the Device. - * At scan time, it integrates this data with the probe information and - * imprints it on the produced images. This field is intentionally hidden - * from outside interference. - */ - mitk::USImageMetadata::Pointer m_Metadata; - /** * \brief Enforces minimal Metadata to be set. */ USDevice(std::string manufacturer, std::string model); /** * \brief Constructs a device with the given Metadata. Make sure the Metadata contains meaningful content! */ - USDevice(mitk::USImageMetadata::Pointer metadata); + DEPRECATED(USDevice(mitk::USImageMetadata::Pointer metadata)); virtual ~USDevice(); /** * \brief Grabs the next frame from the Video input. * This method is called internally, whenever Update() is invoked by an Output. */ virtual void GenerateData(); std::string GetServicePropertyLabel(); private: + std::string m_Manufacturer; + std::string m_Name; + std::string m_Comment; + bool m_SpawnAcquireThread; /** * \brief The device's ServiceRegistration object that allows to modify it's Microservice registraton details. */ us::ServiceRegistration m_ServiceRegistration; /** * \brief Properties of the device's Microservice. */ us::ServiceProperties m_ServiceProperties; // Threading-Related itk::ConditionVariable::Pointer m_FreezeBarrier; itk::SimpleMutexLock m_FreezeMutex; itk::MultiThreader::Pointer m_MultiThreader; ///< itk::MultiThreader used for thread handling itk::FastMutexLock::Pointer m_ImageMutex; ///< mutex for images provided by the image source int m_ThreadID; ///< ID of the started thread bool m_UnregisteringStarted; }; } // namespace mitk // This is the microservice declaration. Do not meddle! US_DECLARE_SERVICE_INTERFACE(mitk::USDevice, "org.mitk.services.UltrasoundDevice") #endif // MITKUSDevice_H_HEADER_INCLUDED_ diff --git a/Modules/US/USModel/mitkUSDevicePersistence.cpp b/Modules/US/USModel/mitkUSDevicePersistence.cpp index aaf3127d3b..c41481dad3 100644 --- a/Modules/US/USModel/mitkUSDevicePersistence.cpp +++ b/Modules/US/USModel/mitkUSDevicePersistence.cpp @@ -1,213 +1,207 @@ /*=================================================================== 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 "mitkUSDevicePersistence.h" //Microservices #include #include #include #include mitk::USDevicePersistence::USDevicePersistence() : m_devices("MITK US","Device Settings") { } void mitk::USDevicePersistence::StoreCurrentDevices() { us::ModuleContext* thisContext = us::GetModuleContext(); std::vector > services = thisContext->GetServiceReferences(); MITK_INFO << "Trying to save " << services.size() << " US devices."; int numberOfSavedDevices = 0; for(std::vector >::iterator it = services.begin(); it != services.end(); ++it) { mitk::USDevice::Pointer currentDevice = thisContext->GetService(*it); //check if it is a USVideoDevice if (currentDevice->GetDeviceClass() == "org.mitk.modules.us.USVideoDevice") { mitk::USVideoDevice::Pointer currentVideoDevice = dynamic_cast(currentDevice.GetPointer()); QString identifier = "device" + QString::number(numberOfSavedDevices); m_devices.setValue(identifier,USVideoDeviceToString(currentVideoDevice)); numberOfSavedDevices++; } else { MITK_WARN << "Saving of US devices of the type " << currentDevice->GetDeviceClass() << " is not supported at the moment. Skipping device."; } } m_devices.setValue("numberOfSavedDevices",numberOfSavedDevices); MITK_INFO << "Successfully saved " << numberOfSavedDevices << " US devices."; } std::vector mitk::USDevicePersistence::RestoreLastDevices() { std::vector devices; int numberOfSavedDevices = m_devices.value("numberOfSavedDevices").toInt(); for(int i=0; i(StringToUSVideoDevice(currentString).GetPointer()); //currentDevice->Initialize(); devices.push_back(currentDevice.GetPointer()); } catch (...) { MITK_ERROR << "Error occured while loading a USVideoDevice from persistence. Device assumed corrupt, will be deleted."; //QMessageBox::warning(NULL, "Could not load device" ,"A stored ultrasound device is corrupted and could not be loaded. The device will be deleted."); } } MITK_INFO << "Restoring " << numberOfSavedDevices << " US devices."; return devices; } QString mitk::USDevicePersistence::USVideoDeviceToString(mitk::USVideoDevice::Pointer d) { - QString manufacturer = d->GetDeviceManufacturer().c_str(); - QString model = d->GetDeviceModel().c_str(); - QString comment = d->GetDeviceComment().c_str(); + QString manufacturer = d->GetManufacturer().c_str(); + QString model = d->GetName().c_str(); + QString comment = d->GetComment().c_str(); int source = d->GetDeviceID(); std::string file = d->GetFilePath(); if (file == "") file = "none"; mitk::USImageVideoSource::Pointer imageSource = dynamic_cast(d->GetUSImageSource().GetPointer()); if ( ! imageSource ) { MITK_ERROR << "There is no USImageVideoSource at the current device."; mitkThrow() << "There is no USImageVideoSource at the current device."; } int greyscale = imageSource->GetIsGreyscale(); int resOverride = imageSource->GetResolutionOverride(); int resWidth = imageSource->GetResolutionOverrideWidth(); int resHight = imageSource->GetResolutionOverrideHeight(); mitk::USImageVideoSource::USImageRoi roi = imageSource->GetRegionOfInterest(); char seperator = '|'; QString returnValue = manufacturer + seperator + model + seperator + comment + seperator + QString::number(source) + seperator + file.c_str() + seperator + QString::number(greyscale) + seperator + QString::number(resOverride) + seperator + QString::number(resWidth) + seperator + QString::number(resHight) + seperator + QString::number(roi.topLeftX) + seperator + QString::number(roi.topLeftY) + seperator + QString::number(roi.bottomRightX) + seperator + QString::number(roi.bottomRightY) ; MITK_INFO << "Output String: " << returnValue.toStdString(); return returnValue; } mitk::USVideoDevice::Pointer mitk::USDevicePersistence::StringToUSVideoDevice(QString s) { MITK_INFO << "Input String: " << s.toStdString(); std::vector data; std::string seperators = "|"; std::string text = s.toStdString(); split(text,seperators,data); if(data.size() != 13) { MITK_ERROR << "Cannot parse US device! (Size: " << data.size() << ")"; return mitk::USVideoDevice::New("INVALID","INVALID","INVALID"); } std::string manufacturer = data.at(0); std::string model = data.at(1); std::string comment = data.at(2); int source = (QString(data.at(3).c_str())).toInt(); std::string file = data.at(4); bool greyscale = (QString(data.at(5).c_str())).toInt(); bool resOverride = (QString(data.at(6).c_str())).toInt(); int resWidth = (QString(data.at(7).c_str())).toInt(); int resHight = (QString(data.at(8).c_str())).toInt(); mitk::USImageVideoSource::USImageRoi cropArea; cropArea.topLeftX = (QString(data.at(9).c_str())).toInt(); cropArea.topLeftY = (QString(data.at(10).c_str())).toInt(); cropArea.bottomRightX = (QString(data.at(11).c_str())).toInt(); cropArea.bottomRightY = (QString(data.at(12).c_str())).toInt(); - // Assemble Metadata - mitk::USImageMetadata::Pointer metadata = mitk::USImageMetadata::New(); - metadata->SetDeviceManufacturer(manufacturer); - metadata->SetDeviceComment(comment); - metadata->SetDeviceModel(model); - metadata->SetProbeName(""); - metadata->SetZoom(""); - // Create Device mitk::USVideoDevice::Pointer returnValue; if (file == "none") { - returnValue = mitk::USVideoDevice::New(source, metadata); + returnValue = mitk::USVideoDevice::New(source, manufacturer, model); + returnValue->SetComment(comment); } else { - returnValue = mitk::USVideoDevice::New(file, metadata); + returnValue = mitk::USVideoDevice::New(file, manufacturer, model); + returnValue->SetComment(comment); } mitk::USImageVideoSource::Pointer imageSource = dynamic_cast(returnValue->GetUSImageSource().GetPointer()); if ( ! imageSource ) { MITK_ERROR << "There is no USImageVideoSource at the current device."; mitkThrow() << "There is no USImageVideoSource at the current device."; } // Set Video Options imageSource->SetColorOutput(!greyscale); // If Resolution override is activated, apply it if (resOverride) { imageSource->OverrideResolution(resWidth, resHight); imageSource->SetResolutionOverride(true); } // Set Crop Area imageSource->SetRegionOfInterest(cropArea); return returnValue; } void mitk::USDevicePersistence::split(std::string& text, std::string& separators, std::vector& words) { int n = text.length(); int start, stop; start = text.find_first_not_of(separators); while ((start >= 0) && (start < n)) { stop = text.find_first_of(separators, start); if ((stop < 0) || (stop > n)) stop = n; words.push_back(text.substr(start, stop - start)); start = text.find_first_not_of(separators, stop + 1); } } \ No newline at end of file diff --git a/Modules/US/USNavigation/mitkUSCombinedModality.cpp b/Modules/US/USNavigation/mitkUSCombinedModality.cpp index 170ceab810..032ccb30b5 100644 --- a/Modules/US/USNavigation/mitkUSCombinedModality.cpp +++ b/Modules/US/USNavigation/mitkUSCombinedModality.cpp @@ -1,492 +1,490 @@ /*=================================================================== 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 "mitkUSCombinedModality.h" #include "mitkUSDevice.h" #include "mitkNavigationDataSource.h" #include "mitkImageReadAccessor.h" #include #include #include "mitkTrackingDeviceSource.h" // US Control Interfaces #include "mitkUSControlInterfaceProbes.h" #include "mitkUSControlInterfaceBMode.h" #include "mitkUSControlInterfaceDoppler.h" //TempIncludes #include const std::string mitk::USCombinedModality::DeviceClassIdentifier = "org.mitk.modules.us.USCombinedModality"; mitk::USCombinedModality::USCombinedModality(USDevice::Pointer usDevice, NavigationDataSource::Pointer trackingDevice, std::string manufacturer, std::string model) : mitk::USDevice(manufacturer, model), m_UltrasoundDevice(usDevice), m_TrackingDevice(trackingDevice), m_SmoothingFilter(mitk::NavigationDataSmoothingFilter::New()), m_DelayFilter(mitk::NavigationDataDelayFilter::New(0)), m_NumberOfSmoothingValues(0), m_DelayCount(0) { this->RebuildFilterPipeline(); //create a new output (for the image data) mitk::Image::Pointer newOutput = mitk::Image::New(); this->SetNthOutput(0,newOutput); // Combined Modality should not spawn an own acquire thread, because // image acquiring is done by the included us device this->SetSpawnAcquireThread(false); } mitk::USCombinedModality::~USCombinedModality() { } std::string mitk::USCombinedModality::GetDeviceClass() { return DeviceClassIdentifier; } mitk::USImageSource::Pointer mitk::USCombinedModality::GetUSImageSource() { if (m_UltrasoundDevice.IsNull()) { MITK_ERROR("USCombinedModality")("USDevice") << "UltrasoundDevice must not be null."; mitkThrow() << "UltrasoundDevice must not be null."; } return m_UltrasoundDevice->GetUSImageSource(); } mitk::USAbstractControlInterface::Pointer mitk::USCombinedModality::GetControlInterfaceCustom() { if (m_UltrasoundDevice.IsNull()) { MITK_ERROR("USCombinedModality")("USDevice") << "UltrasoundDevice must not be null."; mitkThrow() << "UltrasoundDevice must not be null."; } return m_UltrasoundDevice->GetControlInterfaceCustom(); } mitk::USControlInterfaceBMode::Pointer mitk::USCombinedModality::GetControlInterfaceBMode() { if (m_UltrasoundDevice.IsNull()) { MITK_ERROR("USCombinedModality")("USDevice") << "UltrasoundDevice must not be null."; mitkThrow() << "UltrasoundDevice must not be null."; } return m_UltrasoundDevice->GetControlInterfaceBMode(); } mitk::USControlInterfaceProbes::Pointer mitk::USCombinedModality::GetControlInterfaceProbes() { if (m_UltrasoundDevice.IsNull()) { MITK_ERROR("USCombinedModality")("USDevice") << "UltrasoundDevice must not be null."; mitkThrow() << "UltrasoundDevice must not be null."; } return m_UltrasoundDevice->GetControlInterfaceProbes(); } mitk::USControlInterfaceDoppler::Pointer mitk::USCombinedModality::GetControlInterfaceDoppler() { if (m_UltrasoundDevice.IsNull()) { MITK_ERROR("USCombinedModality")("USDevice") << "UltrasoundDevice must not be null."; mitkThrow() << "UltrasoundDevice must not be null."; } return m_UltrasoundDevice->GetControlInterfaceDoppler(); } void mitk::USCombinedModality::UnregisterOnService() { if (m_DeviceState == State_Activated) { this->Deactivate(); } if (m_DeviceState == State_Connected) { this->Disconnect(); } mitk::USDevice::UnregisterOnService(); } mitk::AffineTransform3D::Pointer mitk::USCombinedModality::GetCalibration() { std::string calibrationKey = this->GetIdentifierForCurrentCalibration(); if (calibrationKey.empty()) { MITK_WARN("USCombinedModality")("USDevice") << "Could not get a key for the calibration."; return 0; } // find calibration for combination of probe identifier and depth std::map::iterator calibrationIterator = m_Calibrations.find(calibrationKey); if (calibrationIterator == m_Calibrations.end()) { MITK_WARN("USCombinedModality")("USDevice") << "No calibration found for selected probe and depth."; return 0; } return calibrationIterator->second; } void mitk::USCombinedModality::SetCalibration (mitk::AffineTransform3D::Pointer calibration) { if (calibration.IsNull()) { MITK_WARN << "Null pointer passed to SetCalibration of mitk::USDevice. Ignoring call."; return; } std::string calibrationKey = this->GetIdentifierForCurrentCalibration(); if (calibrationKey.empty()) { MITK_WARN << "Could not get a key for the calibration -> Calibration cannot be set."; return; } m_Calibrations[calibrationKey] = calibration; - m_Metadata->SetDeviceIsCalibrated(true); - if (m_ServiceRegistration != 0) { this->UpdateServiceProperty(mitk::USImageMetadata::PROP_DEV_ISCALIBRATED, true); } } void mitk::USCombinedModality::SetNumberOfSmoothingValues(unsigned int numberOfSmoothingValues) { unsigned int oldNumber = m_NumberOfSmoothingValues; m_NumberOfSmoothingValues = numberOfSmoothingValues; // if filter should be activated or deactivated if ( ( oldNumber == 0 && numberOfSmoothingValues != 0 ) || ( oldNumber != 0 && numberOfSmoothingValues == 0 ) ) { this->RebuildFilterPipeline(); } m_SmoothingFilter->SetNumerOfValues(numberOfSmoothingValues); } void mitk::USCombinedModality::SetDelayCount(unsigned int delayCount) { unsigned int oldCount = m_DelayCount; m_DelayCount = delayCount; // if filter should be activated or deactivated if ( ( oldCount == 0 && delayCount != 0 ) || ( oldCount != 0 && delayCount == 0 ) ) { this->RebuildFilterPipeline(); } m_DelayFilter->SetDelay(delayCount); } bool mitk::USCombinedModality::OnInitialization() { if (m_UltrasoundDevice.IsNull()) { MITK_ERROR("USCombinedModality")("USDevice") << "UltrasoundDevice must not be null."; mitkThrow() << "UltrasoundDevice must not be null."; } if ( m_UltrasoundDevice->GetDeviceState() < mitk::USDevice::State_Initialized ) { return m_UltrasoundDevice->Initialize(); } else { return true; } } bool mitk::USCombinedModality::OnConnection() { if (m_UltrasoundDevice.IsNull()) { MITK_ERROR("USCombinedModality")("USDevice") << "UltrasoundDevice must not be null."; mitkThrow() << "UltrasoundDevice must not be null."; } // connect ultrasound device only if it is not already connected if ( m_UltrasoundDevice->GetDeviceState() >= mitk::USDevice::State_Connected ) { return true; } else { return m_UltrasoundDevice->Connect(); } } bool mitk::USCombinedModality::OnDisconnection() { if (m_UltrasoundDevice.IsNull()) { MITK_ERROR("USCombinedModality")("USDevice") << "UltrasoundDevice must not be null."; mitkThrow() << "UltrasoundDevice must not be null."; } return m_UltrasoundDevice->Disconnect(); } bool mitk::USCombinedModality::OnActivation() { if ( m_UltrasoundDevice.IsNull() ) { MITK_ERROR("USCombinedModality")("USDevice") << "UltrasoundDevice must not be null."; mitkThrow() << "UltrasoundDevice must not be null."; } mitk::TrackingDeviceSource::Pointer trackingDeviceSource = dynamic_cast(m_TrackingDevice.GetPointer()); if ( trackingDeviceSource.IsNull() ) { MITK_WARN("USCombinedModality")("USDevice") << "Cannot start tracking as TrackingDeviceSource is null."; } trackingDeviceSource->StartTracking(); // activate ultrasound device only if it is not already activated if ( m_UltrasoundDevice->GetDeviceState() >= mitk::USDevice::State_Activated ) { return true; } else { return m_UltrasoundDevice->Activate(); } } bool mitk::USCombinedModality::OnDeactivation() { if ( m_UltrasoundDevice.IsNull() ) { MITK_ERROR("USCombinedModality")("USDevice") << "UltrasoundDevice must not be null."; mitkThrow() << "UltrasoundDevice must not be null."; } mitk::TrackingDeviceSource::Pointer trackingDeviceSource = dynamic_cast(m_TrackingDevice.GetPointer()); if ( trackingDeviceSource.IsNull() ) { MITK_WARN("USCombinedModality")("USDevice") << "Cannot stop tracking as TrackingDeviceSource is null."; } trackingDeviceSource->StopTracking(); m_UltrasoundDevice->Deactivate(); return m_UltrasoundDevice->GetIsConnected(); } void mitk::USCombinedModality::OnFreeze(bool freeze) { if (m_UltrasoundDevice.IsNull()) { MITK_ERROR("USCombinedModality")("USDevice") << "UltrasoundDevice must not be null."; mitkThrow() << "UltrasoundDevice must not be null."; } m_UltrasoundDevice->SetIsFreezed(freeze); mitk::TrackingDeviceSource::Pointer trackingDeviceSource = dynamic_cast(m_TrackingDevice.GetPointer()); if ( trackingDeviceSource.IsNull() ) { MITK_WARN("USCombinedModality")("USDevice") << "Cannot freeze tracking."; } else { if ( freeze ) { trackingDeviceSource->StopTracking(); } else { trackingDeviceSource->StartTracking(); } } } mitk::NavigationDataSource::Pointer mitk::USCombinedModality::GetNavigationDataSource() { return m_LastFilter.GetPointer(); } bool mitk::USCombinedModality::GetIsCalibratedForCurrentStatus() { return m_Calibrations.find(this->GetIdentifierForCurrentCalibration()) != m_Calibrations.end(); } void mitk::USCombinedModality::GenerateData() { // update ultrasound image source and get current output then m_UltrasoundDevice->Modified(); m_UltrasoundDevice->Update(); mitk::Image::Pointer image = m_UltrasoundDevice->GetOutput(); if ( image.IsNull() || ! image->IsInitialized() ) { return; } // get output and initialize it if it wasn't initialized before mitk::Image::Pointer output = this->GetOutput(); if ( ! output->IsInitialized() ) { output->Initialize(image); } mitk::ImageReadAccessor inputReadAccessor(image, image->GetSliceData(0,0,0)); output->SetSlice(inputReadAccessor.GetData()); std::string calibrationKey = this->GetIdentifierForCurrentCalibration(); if ( ! calibrationKey.empty() ) { std::map::iterator calibrationIterator = m_Calibrations.find(calibrationKey); if ( calibrationIterator != m_Calibrations.end()) { // transform image according to callibration if one is set // for current configuration of probe and depth output->GetGeometry()->SetIndexToWorldTransform(calibrationIterator->second); } } } std::string mitk::USCombinedModality::SerializeCalibration() { std::stringstream result; result << "" << std::endl; // For each calibration in the set for (std::map::iterator it = m_Calibrations.begin(); it != m_Calibrations.end(); it++) { mitk::AffineTransform3D::MatrixType matrix = it->second->GetMatrix(); mitk::AffineTransform3D::TranslationType translation = it->second->GetTranslation(); TiXmlElement elem(it->first); // Serialize Matrix elem.SetDoubleAttribute("M00", matrix[0][0]); elem.SetDoubleAttribute("M01", matrix[0][1]); elem.SetDoubleAttribute("M02", matrix[0][2]); elem.SetDoubleAttribute("M10", matrix[1][0]); elem.SetDoubleAttribute("M11", matrix[1][1]); elem.SetDoubleAttribute("M12", matrix[1][2]); elem.SetDoubleAttribute("M20", matrix[2][0]); elem.SetDoubleAttribute("M21", matrix[2][1]); elem.SetDoubleAttribute("M22", matrix[2][2]); // Serialize Offset elem.SetDoubleAttribute("T0", translation[0]); elem.SetDoubleAttribute("T1", translation[1]); elem.SetDoubleAttribute("T2", translation[2]); result << elem << std::endl; } result << "" << std::endl; return result.str(); } void mitk::USCombinedModality::DeserializeCalibration(const std::string& xmlString, bool clearPreviousCalibrations) { // Sanitize Input if (xmlString == "") { MITK_WARN << "Empty string passed to Deserialize() method of CombinedModality. Aborting..."; return; } // Clear previous calibrations if necessary if (clearPreviousCalibrations) m_Calibrations.clear(); // Parse Input TiXmlDocument doc; if(!doc.Parse(xmlString.c_str())) { MITK_WARN << "Unable to deserialize calibrations in CombinedModality. Error was: " << doc.ErrorDesc(); return; } TiXmlElement* root = doc.FirstChildElement(); if(root == NULL) { MITK_WARN << "Unable to deserialize calibrations in CombinedModality. String contained no root element."; return; } // Read Calibrations for(TiXmlElement* elem = root->FirstChildElement(); elem != NULL; elem = elem->NextSiblingElement()) { mitk::AffineTransform3D::MatrixType matrix; mitk::AffineTransform3D::OffsetType translation; std::string calibName = elem->Value(); // Deserialize Matrix elem->QueryDoubleAttribute("M00", &matrix[0][0]); elem->QueryDoubleAttribute("M01", &matrix[0][1]); elem->QueryDoubleAttribute("M02", &matrix[0][2]); elem->QueryDoubleAttribute("M10", &matrix[1][0]); elem->QueryDoubleAttribute("M11", &matrix[1][1]); elem->QueryDoubleAttribute("M12", &matrix[1][2]); elem->QueryDoubleAttribute("M20", &matrix[2][0]); elem->QueryDoubleAttribute("M21", &matrix[2][1]); elem->QueryDoubleAttribute("M22", &matrix[2][2]); // Deserialize Offset elem->QueryDoubleAttribute("T0", &translation[0]); elem->QueryDoubleAttribute("T1", &translation[1]); elem->QueryDoubleAttribute("T2", &translation[2]); mitk::AffineTransform3D::Pointer calibration = mitk::AffineTransform3D::New(); calibration->SetMatrix(matrix); calibration->SetTranslation(translation); m_Calibrations[calibName] = calibration; } } std::string mitk::USCombinedModality::GetIdentifierForCurrentCalibration() { us::ServiceProperties::const_iterator probeIt = m_ServiceProperties.find( mitk::USCombinedModality::GetPropertyKeys().US_PROPKEY_PROBES_SELECTED); // get probe identifier from control interface for probes std::string probeName = "default"; if (probeIt != m_ServiceProperties.end()) { probeName = (probeIt->second).ToString(); } // get string for depth value from the micro service properties std::string depth; us::ServiceProperties::iterator depthIterator = m_ServiceProperties.find( mitk::USCombinedModality::GetPropertyKeys().US_PROPKEY_BMODE_DEPTH); if (depthIterator != m_ServiceProperties.end()) { depth = depthIterator->second.ToString(); } else { depth = "0"; } return probeName + depth; } void mitk::USCombinedModality::RebuildFilterPipeline() { m_LastFilter = m_TrackingDevice; if ( m_NumberOfSmoothingValues > 0 ) { for (unsigned int i = 0; i < m_TrackingDevice->GetNumberOfOutputs(); i++) { m_SmoothingFilter->SetInput(i, m_LastFilter->GetOutput(i)); } m_LastFilter = m_SmoothingFilter; } if ( m_DelayCount > 0 ) { for (unsigned int i = 0; i < m_TrackingDevice->GetNumberOfOutputs(); i++) { m_DelayFilter->SetInput(i, m_LastFilter->GetOutput(i)); } m_LastFilter = m_DelayFilter; } }