diff --git a/Modules/IGTBase/include/mitkIGTMimeTypes.h b/Modules/IGTBase/include/mitkIGTMimeTypes.h index cef22a1141..52b5f38d47 100644 --- a/Modules/IGTBase/include/mitkIGTMimeTypes.h +++ b/Modules/IGTBase/include/mitkIGTMimeTypes.h @@ -1,34 +1,35 @@ /*=================================================================== 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 MITKIOMIMETYPE_H_HEADER_INCLUDED_ #define MITKIOMIMETYPE_H_HEADER_INCLUDED_ #include #include #include namespace mitk { class MITKIGTBASE_EXPORT IGTMimeTypes { public: static CustomMimeType NAVIGATIONDATASETXML_MIMETYPE(); static CustomMimeType NAVIGATIONDATASETCSV_MIMETYPE(); + static CustomMimeType USDEVICEINFORMATIONXML_MIMETYPE(); }; } #endif // MITKIOMIMETYPE_H_HEADER_INCLUDED_ \ No newline at end of file diff --git a/Modules/IGTBase/src/mitkIGTMimeTypes.cpp b/Modules/IGTBase/src/mitkIGTMimeTypes.cpp index f342ad8bea..a9db7c8f96 100644 --- a/Modules/IGTBase/src/mitkIGTMimeTypes.cpp +++ b/Modules/IGTBase/src/mitkIGTMimeTypes.cpp @@ -1,38 +1,48 @@ /*=================================================================== 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 #include "mitkIGTMimeTypes.h" mitk::CustomMimeType mitk::IGTMimeTypes::NAVIGATIONDATASETXML_MIMETYPE() { mitk::CustomMimeType mimeType(IOMimeTypes::DEFAULT_BASE_NAME() + ".NavigationDataSet.xml"); std::string category = "NavigationDataSet"; mimeType.SetComment("NavigationDataSet (XML)"); mimeType.SetCategory(category); mimeType.AddExtension("xml"); return mimeType; } mitk::CustomMimeType mitk::IGTMimeTypes::NAVIGATIONDATASETCSV_MIMETYPE() { mitk::CustomMimeType mimeType(IOMimeTypes::DEFAULT_BASE_NAME() + ".NavigationDataSet.csv"); std::string category = "NavigationDataSet"; mimeType.SetComment("NavigationDataSet (csv)"); mimeType.SetCategory(category); mimeType.AddExtension("csv"); return mimeType; +} + +mitk::CustomMimeType mitk::IGTMimeTypes::USDEVICEINFORMATIONXML_MIMETYPE() +{ + mitk::CustomMimeType mimeType(IOMimeTypes::DEFAULT_BASE_NAME() + ".USDeviceInformation.xml"); + std::string category = "USDeviceInformation"; + mimeType.SetComment("USDeviceInformation (XML)"); + mimeType.SetCategory(category); + mimeType.AddExtension("xml"); + return mimeType; } \ No newline at end of file diff --git a/Modules/US/USModel/mitkUSDeviceReaderXML.cpp b/Modules/US/USModel/mitkUSDeviceReaderXML.cpp new file mode 100644 index 0000000000..3395896e24 --- /dev/null +++ b/Modules/US/USModel/mitkUSDeviceReaderXML.cpp @@ -0,0 +1,235 @@ +/*=================================================================== + +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 +#include "mitkUSDeviceReaderXML.h" +#include +#include + +#include + +// Third Party +#include +#include +#include + +const static char* TAG_ULTRASOUNDDEVICE = "ULTRASOUNDDEVICE"; +const static char* TAG_GENERALSETTINGS = "GENERALSETTINGS"; +const static char* TAG_PROBES = "PROBES"; +const static char* TAG_PROBE = "PROBE"; +const static char* TAG_DEPTHS = "DEPTHS"; +const static char* TAG_DEPTH = "DEPTH"; +const static char* TAG_SPACING = "SPACING"; +const static char* TAG_CROPPING = "CROPPING"; + +const static char* ATTR_FILEVERS = "filevers"; +const static char* ATTR_TYPE = "type"; +const static char* ATTR_NAME = "name"; +const static char* ATTR_MANUFACTURER = "manufacturer"; +const static char* ATTR_MODEL = "model"; +const static char* ATTR_COMMENT = "comment"; +const static char* ATTR_IMAGESTREAMS = "imagestreams"; +const static char* ATTR_GREYSCALE = "greyscale"; +const static char* ATTR_RESOLUTIONOVERRIDE = "resolutionOverride"; +const static char* ATTR_RESOLUTIONWIDTH = "resolutionWidth"; +const static char* ATTR_RESOLUTIONHEIGHT = "resolutionHeight"; +const static char* ATTR_SOURCEID = "sourceID"; +const static char* ATTR_FILEPATH = "filepath"; +const static char* ATTR_OPENCVPORT = "opencvPort"; +const static char* ATTR_DEPTH = "depth"; +const static char* ATTR_X = "x"; +const static char* ATTR_Y = "y"; +const static char* ATTR_TOP = "top"; +const static char* ATTR_BOTTOM = "bottom"; +const static char* ATTR_LEFT = "left"; +const static char* ATTR_RIGHT = "right"; + +mitk::USDeviceReaderXML::USDeviceReaderXML() : AbstractFileReader( + mitk::IGTMimeTypes::USDEVICEINFORMATIONXML_MIMETYPE(), + "MITK USDevice Reader (XML)"), m_Filename("") +{ + RegisterService(); +} + +mitk::USDeviceReaderXML::~USDeviceReaderXML() +{ +} + +mitk::USDeviceReaderXML::USVideoDeviceConfigData &mitk::USDeviceReaderXML::GetUSVideoDeviceConfigData() +{ + return m_DeviceConfig; +} + +mitk::USDeviceReaderXML::USDeviceReaderXML(const mitk::USDeviceReaderXML& other) : AbstractFileReader(other) +{ +} + +mitk::USDeviceReaderXML* mitk::USDeviceReaderXML::Clone() const +{ + return new USDeviceReaderXML(*this); +} + + + + +std::vector> mitk::USDeviceReaderXML::Read() +{ + MITK_WARN << "This method is not implemented. \ + Please use the method ReadUltrasoundDeviceConfiguration() instead."; + std::vector result; + return result; +} + +bool mitk::USDeviceReaderXML::ReadUltrasoundDeviceConfiguration() +{ + MITK_INFO << "Try to start reading xml device configuration..."; + if (m_Filename == "") + { + MITK_WARN << "Cannot read file - empty filename!"; + return false; + } + + TiXmlDocument document(m_Filename); + if (!document.LoadFile()) + { + MITK_ERROR << "Error when opening and reading file :" << m_Filename; + return false; + } + + TiXmlHandle documentHandle(&document); + TiXmlElement* ultrasoundDeviceTag = documentHandle.FirstChildElement(TAG_ULTRASOUNDDEVICE).ToElement(); + if (ultrasoundDeviceTag == nullptr) + { + MITK_ERROR << "Error parsing the file :" << m_Filename << std::endl << "Wrong xml format structure."; + return false; + } + + //Extract attribute information of the ULTRASOUNDDEVICE-Tag: + this->ExtractAttributeInformationOfUltrasoundDeviceTag(ultrasoundDeviceTag); + + TiXmlElement* generalSettingsTag = documentHandle.FirstChildElement(TAG_ULTRASOUNDDEVICE).FirstChildElement(TAG_GENERALSETTINGS).ToElement(); + if (generalSettingsTag == nullptr) + { + MITK_ERROR << "Error parsing the GENERALSETTINGS-Tag in the file :" << m_Filename; + return false; + } + + //Extract attribute information of the GENERALSETTINGS-Tag: + this->ExtractAttributeInformationOfGeneralSettingsTag(generalSettingsTag); + + TiXmlElement* probesTag = documentHandle.FirstChildElement(TAG_ULTRASOUNDDEVICE).FirstChildElement(TAG_PROBES).ToElement(); + if (probesTag == nullptr) + { + MITK_ERROR << "Error: PROBES-Tag was not found in the file :" << m_Filename << "Therefore, creating default probe."; + //Create default ultrasound probe: + mitk::USProbe::Pointer ultrasoundProbeDefault = mitk::USProbe::New(); + ultrasoundProbeDefault->SetName("default"); + ultrasoundProbeDefault->SetDepth(0); + m_DeviceConfig.probes.push_back(ultrasoundProbeDefault); + return true; + } + + //Extract all saved and configured probes of the USDevice: + for (TiXmlElement* probeTag = probesTag->FirstChildElement(TAG_PROBE); + probeTag != nullptr; probeTag = probeTag->NextSiblingElement()) + { + this->ExtractProbe(probeTag); + } + return true; +} + +void mitk::USDeviceReaderXML::SetFilename(std::string filename) +{ + m_Filename = filename; +} + +void mitk::USDeviceReaderXML::ExtractAttributeInformationOfUltrasoundDeviceTag(TiXmlElement *ultrasoundTag) +{ + ultrasoundTag->QueryDoubleAttribute(ATTR_FILEVERS, &m_DeviceConfig.fileversion); + ultrasoundTag->QueryStringAttribute(ATTR_TYPE, &m_DeviceConfig.deviceType); + ultrasoundTag->QueryStringAttribute(ATTR_NAME, &m_DeviceConfig.deviceName); + ultrasoundTag->QueryStringAttribute(ATTR_MANUFACTURER, &m_DeviceConfig.manufacturer); + ultrasoundTag->QueryStringAttribute(ATTR_MODEL, &m_DeviceConfig.model); + ultrasoundTag->QueryStringAttribute(ATTR_COMMENT, &m_DeviceConfig.comment); + ultrasoundTag->QueryIntAttribute(ATTR_IMAGESTREAMS, &m_DeviceConfig.numberOfImageStreams); +} + +void mitk::USDeviceReaderXML::ExtractAttributeInformationOfGeneralSettingsTag(TiXmlElement *generalSettingsTag) +{ + generalSettingsTag->QueryBoolAttribute(ATTR_GREYSCALE, &m_DeviceConfig.useGreyscale); + generalSettingsTag->QueryBoolAttribute(ATTR_RESOLUTIONOVERRIDE, &m_DeviceConfig.useResolutionOverride); + generalSettingsTag->QueryIntAttribute(ATTR_RESOLUTIONHEIGHT, &m_DeviceConfig.resolutionHeight); + generalSettingsTag->QueryIntAttribute(ATTR_RESOLUTIONWIDTH, &m_DeviceConfig.resolutionWidth); + generalSettingsTag->QueryIntAttribute(ATTR_SOURCEID, &m_DeviceConfig.sourceID); + generalSettingsTag->QueryStringAttribute(ATTR_FILEPATH, &m_DeviceConfig.filepathVideoSource); + generalSettingsTag->QueryIntAttribute(ATTR_OPENCVPORT, &m_DeviceConfig.opencvPort); +} + +void mitk::USDeviceReaderXML::ExtractProbe(TiXmlElement *probeTag) +{ + mitk::USProbe::Pointer ultrasoundProbe = mitk::USProbe::New(); + std::string probeName; + probeTag->QueryStringAttribute(ATTR_NAME, &probeName); + ultrasoundProbe->SetName(probeName); + + TiXmlElement* depthsTag = probeTag->FirstChildElement(TAG_DEPTHS); + if (depthsTag != nullptr) + { + for (TiXmlElement* depthTag = depthsTag->FirstChildElement(TAG_DEPTH); + depthTag != nullptr; depthTag = depthTag->NextSiblingElement()) + { + int depth = 0; + mitk::Vector3D spacing; + spacing[0] = 1; + spacing[1] = 1; + spacing[2] = 1; + + depthTag->QueryIntAttribute(ATTR_DEPTH, &depth); + + TiXmlElement* spacingTag = depthTag->FirstChildElement(TAG_SPACING); + if (spacingTag != nullptr) + { + spacingTag->QueryDoubleAttribute(ATTR_X, &spacing[0]); + spacingTag->QueryDoubleAttribute(ATTR_Y, &spacing[1]); + } + + ultrasoundProbe->SetDepthAndSpacing(depth, spacing); + } + } + else + { + MITK_ERROR << "Error: DEPTHS-Tag was not found in the file :" << m_Filename + << "Therefore, creating default depth [0] and spacing [1,1,1] for the probe."; + ultrasoundProbe->SetDepth(0); + } + + unsigned int croppingTop = 0; + unsigned int croppingBottom = 0; + unsigned int croppingLeft = 0; + unsigned int croppingRight = 0; + + TiXmlElement* croppingTag = probeTag->FirstChildElement(TAG_CROPPING); + if (croppingTag != nullptr) + { + croppingTag->QueryUnsignedAttribute(ATTR_TOP, &croppingTop); + croppingTag->QueryUnsignedAttribute(ATTR_BOTTOM, &croppingBottom); + croppingTag->QueryUnsignedAttribute(ATTR_LEFT, &croppingLeft); + croppingTag->QueryUnsignedAttribute(ATTR_RIGHT, &croppingRight); + } + + ultrasoundProbe->SetProbeCropping(croppingTop, croppingBottom, croppingLeft, croppingRight); + m_DeviceConfig.probes.push_back(ultrasoundProbe); +} diff --git a/Modules/US/USModel/mitkUSDeviceReaderXML.h b/Modules/US/USModel/mitkUSDeviceReaderXML.h new file mode 100644 index 0000000000..2b6c0a4fde --- /dev/null +++ b/Modules/US/USModel/mitkUSDeviceReaderXML.h @@ -0,0 +1,101 @@ +/*=================================================================== + +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 mitkUSDeviceReaderXML_H_HEADER_INCLUDED_ +#define mitkUSDeviceReaderXML_H_HEADER_INCLUDED_ + +#include + +#include +#include + +class TiXmlElement; +class TiXmlNode; + +namespace mitk { + + class MITKUS_EXPORT USDeviceReaderXML : public AbstractFileReader + { + public: + USDeviceReaderXML(); + ~USDeviceReaderXML() override; + + using AbstractFileReader::Read; + std::vector> Read() override; + bool ReadUltrasoundDeviceConfiguration(); + + void SetFilename(std::string filename); + + typedef struct USVideoDeviceConfigData_ + { + double fileversion; + std::string deviceType; + std::string deviceName; + std::string manufacturer; + std::string model; + std::string comment; + int numberOfImageStreams; + + bool useGreyscale; + bool useResolutionOverride; + int resolutionWidth; + int resolutionHeight; + int sourceID; + std::string filepathVideoSource; + int opencvPort; + + std::vector probes; + + USVideoDeviceConfigData_() + : fileversion(0), deviceType("Unknown"), deviceName("Unknown"), + manufacturer("Unknown"), comment(""), numberOfImageStreams(1), + useGreyscale(true), useResolutionOverride(true), + resolutionWidth(640), resolutionHeight(480), sourceID(0), + filepathVideoSource(""), opencvPort(0) + { }; + + }USVideoDeviceConfigData; + + USVideoDeviceConfigData &GetUSVideoDeviceConfigData(); + + protected: + USDeviceReaderXML(const USDeviceReaderXML& other); + mitk::USDeviceReaderXML* Clone() const override; + + /** + * \brief Extracts all stored attribute information of the ULTRASOUNDDEVICE-Tag. + */ + void ExtractAttributeInformationOfUltrasoundDeviceTag(TiXmlElement *element); + + /** + * \brief Extracts all stored attribute information of the GENERALSETTINGS-Tag. + */ + void ExtractAttributeInformationOfGeneralSettingsTag(TiXmlElement *element); + + /** + * \brief Extracts all stored information of a single ultrasound probe. + */ + void ExtractProbe(TiXmlElement *element); + + private: + std::string m_Filename; + USVideoDeviceConfigData m_DeviceConfig; + }; + +} // namespace mitk + +#endif // mitkUSDeviceReaderXML_H_HEADER_INCLUDED_ diff --git a/Modules/US/USModel/mitkUSDeviceWriterXML.cpp b/Modules/US/USModel/mitkUSDeviceWriterXML.cpp new file mode 100644 index 0000000000..1e5b2d9766 --- /dev/null +++ b/Modules/US/USModel/mitkUSDeviceWriterXML.cpp @@ -0,0 +1,61 @@ +/*=================================================================== + +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 +#include "mitkUSDeviceWriterXML.h" +#include +#include +#include + +// Third Party +#include +#include +#include +#include + +mitk::USDeviceWriterXML::USDeviceWriterXML() : AbstractFileWriter(USDevice::GetStaticNameOfClass(), + mitk::IGTMimeTypes::USDEVICEINFORMATIONXML_MIMETYPE(), + "MITK USDevice Writer (XML)"), m_Filename("") +{ + RegisterService(); +} + +mitk::USDeviceWriterXML::USDeviceWriterXML(const mitk::USDeviceWriterXML& other) : AbstractFileWriter(other) +{ +} + +mitk::USDeviceWriterXML::~USDeviceWriterXML() +{ +} + +mitk::USDeviceWriterXML* mitk::USDeviceWriterXML::Clone() const +{ + return new USDeviceWriterXML(*this); +} + +void mitk::USDeviceWriterXML::Write() +{ + if (m_Filename == "") + { + MITK_WARN << "Cannot write to file - empty filename!"; + return; + } +} + +void mitk::USDeviceWriterXML::SetFilename(std::string filename) +{ + m_Filename = filename; +} diff --git a/Modules/US/USModel/mitkUSDeviceWriterXML.h b/Modules/US/USModel/mitkUSDeviceWriterXML.h new file mode 100644 index 0000000000..05f4141f9b --- /dev/null +++ b/Modules/US/USModel/mitkUSDeviceWriterXML.h @@ -0,0 +1,48 @@ +/*=================================================================== + +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 mitkUSDeviceWriterXML_H_Header_INCLUDED_ +#define mitkUSDeviceWriterXML_H_Header_INCLUDED_ + +#include + +#include + +namespace mitk { + class MITKUS_EXPORT USDeviceWriterXML : public AbstractFileWriter + { + public: + + USDeviceWriterXML(); + ~USDeviceWriterXML() override; + + using AbstractFileWriter::Write; + void Write() override; + + void SetFilename(std::string filename); + + protected: + USDeviceWriterXML(const USDeviceWriterXML& other); + mitk::USDeviceWriterXML* Clone() const override; + + private: + std::string m_Filename; + + + }; +} + +#endif // mitkUSDeviceWriterXML_H_Header_INCLUDED_ diff --git a/Modules/US/USModel/mitkUSProbe.cpp b/Modules/US/USModel/mitkUSProbe.cpp index 7f6e08cfc4..fd8fef5ac7 100644 --- a/Modules/US/USModel/mitkUSProbe.cpp +++ b/Modules/US/USModel/mitkUSProbe.cpp @@ -1,88 +1,111 @@ /*=================================================================== 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 "mitkUSProbe.h" #include mitk::USProbe::USProbe() : itk::Object(), m_CurrentDepth(0) { } mitk::USProbe::USProbe(std::string identifier) : m_Name(identifier), m_CurrentDepth(0) { } mitk::USProbe::~USProbe() { } +void mitk::USProbe::SetProbeCropping(unsigned int top, unsigned int bottom, unsigned int left, unsigned int right) +{ + m_Cropping.top = top; + m_Cropping.bottom = bottom; + m_Cropping.left = left; + m_Cropping.right = right; +} + +mitk::USProbe::USProbeCropping mitk::USProbe::GetProbeCropping() +{ + return m_Cropping; +} + bool mitk::USProbe::IsEqualToProbe(mitk::USProbe::Pointer probe) { if (m_Name.compare(probe->GetName()) == 0) return true; else return false; } void mitk::USProbe::SetDepthAndSpacing(int depth, mitk::Vector3D spacing) { m_DepthsAndSpacings.insert(std::pair(depth, spacing)); } std::map mitk::USProbe::GetDepthsAndSpacing() { return m_DepthsAndSpacings; } void mitk::USProbe::SetDepth(int depth) { mitk::Vector3D defaultSpacing; defaultSpacing[0] = 1; defaultSpacing[1] = 1; defaultSpacing[2] = 1; m_DepthsAndSpacings.insert(std::pair(depth, defaultSpacing)); } void mitk::USProbe::RemoveDepth(int depthToRemove) { m_DepthsAndSpacings.erase(depthToRemove); } void mitk::USProbe::SetSpacingForGivenDepth(int givenDepth, Vector3D spacing) { m_DepthsAndSpacings[givenDepth][0] = spacing[0]; m_DepthsAndSpacings[givenDepth][1] = spacing[1]; m_DepthsAndSpacings[givenDepth][2] = spacing[2]; } mitk::Vector3D mitk::USProbe::GetSpacingForGivenDepth(int givenDepth) { mitk::Vector3D spacing; std::map::iterator it = m_DepthsAndSpacings.find(givenDepth); if (it != m_DepthsAndSpacings.end()) //check if given depth really exists { spacing[0] = it->second[0]; spacing[1] = it->second[1]; spacing[2] = it->second[2]; } else { //spacing does not exist, so set default spacing (1,1,1) spacing[0] = 1; spacing[1] = 1; spacing[2] = 1; } return spacing; } + +bool mitk::USProbe::IsDepthAndSpacingEmpty() +{ + if( m_DepthsAndSpacings.size() == 0 ) + { + return true; + } + + return false; +} diff --git a/Modules/US/USModel/mitkUSProbe.h b/Modules/US/USModel/mitkUSProbe.h index 9462beb29e..2ca2f931ed 100644 --- a/Modules/US/USModel/mitkUSProbe.h +++ b/Modules/US/USModel/mitkUSProbe.h @@ -1,99 +1,130 @@ /*=================================================================== 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 MITKUSProbe_H_HEADER_INCLUDED_ #define MITKUSProbe_H_HEADER_INCLUDED_ #include #include #include #include #include namespace mitk { /**Documentation * \brief Right now, the US Probe is only a fancy name for a string. Later, it could handle probe specific parameters * like the current frequency etc. It is able to compare itself to other probes for device managment though. * * \ingroup US */ //Be sure to check the isEqualTo() method if you expand this class to see if it needs work! class MITKUS_EXPORT USProbe : public itk::Object { public: mitkClassMacroItkParent(USProbe, itk::Object); itkFactorylessNewMacro(Self) itkCloneMacro(Self) mitkNewMacro1Param(Self, std::string); + /** + * \brief Struct to define a probe specific ultrasound image cropping. + */ + typedef struct USProbeCropping_ + { + unsigned int top; + unsigned int bottom; + unsigned int left; + unsigned int right; + + USProbeCropping_() + : top(0), bottom(0), left(0), right(0) { }; + + USProbeCropping_(unsigned int top, unsigned int bottom, unsigned int left, unsigned int right) + : top(top), bottom(bottom), left(left), right(right) { }; + }USProbeCropping; + + /** + * \brief Sets the probe cropping. + */ + void SetProbeCropping(unsigned int top, unsigned int bottom, unsigned int left, unsigned int right); + USProbeCropping GetProbeCropping(); + /** * \brief Compares this probe to another probe and returns true if they are equal in terms of name AND NAME ONLY * be sure to sufficiently extend this method along with further capabilities probes. */ bool IsEqualToProbe(mitk::USProbe::Pointer probe); /** * \brief Sets a scanning depth of the probe and the associated spacing */ void SetDepthAndSpacing(int depth, Vector3D spacing); /** * \brief Gets all scanning depths and the associates spacings of the probe as an std::map with depth as key (represented by an int) and *spacing as value (represented by a Vector3D) */ std::map GetDepthsAndSpacing(); /** - * \brief Sets a scanning depth of the probe with the default spacing (1,1,0). Exact spacing needs to be calibrated. + * \brief Sets a scanning depth of the probe with the default spacing (1,1,1). Exact spacing needs to be calibrated. */ void SetDepth(int depth); /** * \brief Removes the given depth of the probe, if it exists */ void RemoveDepth(int depthToRemove); /** * \ brief Sets the spacing associated to the given depth of the probe. Spacing needs to be calibrated. */ void SetSpacingForGivenDepth(int givenDepth, Vector3D spacing); /** * \brief Returns the spacing that is associated to the given depth of the probe. - *If spacing was not calibrated or if depth does not exist for this probe the default spacing (1,1,0) is returned. + *If spacing was not calibrated or if depth does not exist for this probe the default spacing (1,1,1) is returned. */ Vector3D GetSpacingForGivenDepth(int givenDepth); + /** + * \brief Checks, whether the std::map m_DepthAndSpacings contains at least one depth element or not. + * \return True, if the the std::map m_DepthAndSpacings does not contain at least one depth element, else false. + */ + bool IsDepthAndSpacingEmpty(); + //## getter and setter ## itkGetMacro(Name, std::string); itkSetMacro(Name, std::string); itkGetMacro(CurrentDepth, double); itkSetMacro(CurrentDepth, double); protected: USProbe(); USProbe(std::string identifier); ~USProbe() override; std::string m_Name; double m_CurrentDepth; // Map containing the depths and the associated spacings as an std::vector with depth as key and spacing as value std::map m_DepthsAndSpacings; + + USProbeCropping m_Cropping; }; } // namespace mitk #endif diff --git a/Modules/US/USModel/mitkUSVideoDevice.cpp b/Modules/US/USModel/mitkUSVideoDevice.cpp index 2db712f3ca..6d216e8296 100644 --- a/Modules/US/USModel/mitkUSVideoDevice.cpp +++ b/Modules/US/USModel/mitkUSVideoDevice.cpp @@ -1,253 +1,258 @@ /*=================================================================== 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 "mitkUSVideoDeviceCustomControls.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_Source->UnRegister(); m_Source = nullptr; } void mitk::USVideoDevice::Init() { m_Source = mitk::USImageVideoSource::New(); m_ControlInterfaceCustom = mitk::USVideoDeviceCustomControls::New(this); //this->SetNumberOfInputs(1); this->SetNumberOfIndexedOutputs(1); // mitk::USImage::Pointer output = mitk::USImage::New(); // output->Initialize(); this->SetNthOutput(0, this->MakeOutput(0)); } std::string mitk::USVideoDevice::GetDeviceClass() { return mitk::USVideoDevice::GetDeviceClassStatic(); } std::string mitk::USVideoDevice::GetDeviceClassStatic() { return "org.mitk.modules.us.USVideoDevice"; } mitk::USAbstractControlInterface::Pointer mitk::USVideoDevice::GetControlInterfaceCustom() { return m_ControlInterfaceCustom.GetPointer(); } bool mitk::USVideoDevice::OnInitialization() { // nothing to do at initialization of video device return true; } 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_DeviceState == State_Activated) this->Deactivate(); m_Source->ReleaseInput(); 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!"; return true; } bool mitk::USVideoDevice::OnDeactivation() { // happens automatically when m_Active is set to false return true; } void mitk::USVideoDevice::GenerateData() { Superclass::GenerateData(); if( m_ImageVector.size() == 0 || this->GetNumberOfIndexedOutputs() == 0 ) { return; } m_ImageMutex->Lock(); auto& image = m_ImageVector[0]; if( image.IsNotNull() && image->IsInitialized() && m_CurrentProbe.IsNotNull() ) { //MITK_INFO << "Spacing CurrentProbe: " << m_CurrentProbe->GetSpacingForGivenDepth(m_CurrentProbe->GetCurrentDepth()); image->GetGeometry()->SetSpacing(m_CurrentProbe->GetSpacingForGivenDepth(m_CurrentProbe->GetCurrentDepth())); this->GetOutput(0)->SetGeometry(image->GetGeometry()); } m_ImageMutex->Unlock(); } void mitk::USVideoDevice::UnregisterOnService() { if (m_DeviceState == State_Activated) { this->Deactivate(); } if (m_DeviceState == State_Connected) { this->Disconnect(); } mitk::USDevice::UnregisterOnService(); } mitk::USImageSource::Pointer mitk::USVideoDevice::GetUSImageSource() { return m_Source.GetPointer(); } std::vector mitk::USVideoDevice::GetAllProbes() { if (m_Probes.empty()) { MITK_INFO << "No probes exist for this USVideDevice. Empty vector is returned"; } return m_Probes; } +void mitk::USVideoDevice::DeleteAllProbes() +{ + m_Probes.clear(); +} + mitk::USProbe::Pointer mitk::USVideoDevice::GetCurrentProbe() { if (m_CurrentProbe.IsNotNull()) { return m_CurrentProbe; } else { return nullptr; } } mitk::USProbe::Pointer mitk::USVideoDevice::GetProbeByName(std::string name) { for (std::vector::iterator it = m_Probes.begin(); it != m_Probes.end(); it++) { if (name.compare((*it)->GetName()) == 0) return (*it); } MITK_INFO << "No probe with given name " << name << " was found."; return nullptr; //no matching probe was found so 0 is returned } void mitk::USVideoDevice::RemoveProbeByName(std::string name) { for (std::vector::iterator it = m_Probes.begin(); it != m_Probes.end(); it++) { if (name.compare((*it)->GetName()) == 0) { m_Probes.erase(it); return; } } MITK_INFO << "No Probe with given name " << name << " was found"; } void mitk::USVideoDevice::AddNewProbe(mitk::USProbe::Pointer probe) { m_Probes.push_back(probe); } bool mitk::USVideoDevice::GetIsSourceFile() { return m_SourceIsFile; } void mitk::USVideoDevice::SetDefaultProbeAsCurrentProbe() { if( m_Probes.size() == 0 ) { std::string name = "default"; mitk::USProbe::Pointer defaultProbe = mitk::USProbe::New( name ); m_Probes.push_back( defaultProbe ); } m_CurrentProbe = m_Probes.at(0); MITK_INFO << "SetDefaultProbeAsCurrentProbe()"; this->ProbeChanged( m_CurrentProbe->GetName() ); } void mitk::USVideoDevice::SetCurrentProbe(std::string probename) { m_CurrentProbe = this->GetProbeByName( probename ); MITK_INFO << "SetCurrentProbe() " << probename; } void mitk::USVideoDevice::SetSpacing(double xSpacing, double ySpacing) { mitk::Vector3D spacing; spacing[0] = xSpacing; spacing[1] = ySpacing; spacing[2] = 1; MITK_INFO << "Spacing: " << spacing; if( m_CurrentProbe.IsNotNull() ) { m_CurrentProbe->SetSpacingForGivenDepth(m_CurrentProbe->GetCurrentDepth(), spacing); } else { MITK_WARN << "Cannot set spacing. Current ultrasound probe not set."; } } diff --git a/Modules/US/USModel/mitkUSVideoDevice.h b/Modules/US/USModel/mitkUSVideoDevice.h index 774f3d4b9d..df205dd6c0 100644 --- a/Modules/US/USModel/mitkUSVideoDevice.h +++ b/Modules/US/USModel/mitkUSVideoDevice.h @@ -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. ===================================================================*/ #ifndef MITKUSVideoDevice_H_HEADER_INCLUDED_ #define MITKUSVideoDevice_H_HEADER_INCLUDED_ #include #include #include "mitkUSDevice.h" #include "mitkUSImageVideoSource.h" #include "mitkUSProbe.h" #include namespace itk { template class SmartPointer; } namespace mitk { class USVideoDeviceCustomControls; class USAbstractControlInterface; /** * \brief A mitk::USVideoDevice 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 mitk::USImage with attached metadata. * This simple implementation does only capture and display 2d images without * registration for example. * * \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); /** * \return the qualified name of this class (as returned by GetDeviceClassStatic()) */ std::string GetDeviceClass() override; /** * This methode is necessary instead of a static member attribute to avoid * "static initialization order fiasco" when an instance of this class is * used in a module activator. * * \return the qualified name of this class */ static std::string GetDeviceClassStatic(); /** * Getter for the custom control interface which was created during the * construction process of mitk::USVideoDevice. * * \return custom control interface of the video device */ itk::SmartPointer GetControlInterfaceCustom() override; /** * \brief Remove this device from the micro service. * This method is public for mitk::USVideoDevice, because this devices * can be completly removed. This is not possible for API devices, which * should be available while their sub module is loaded. */ void UnregisterOnService(); /** * \return mitk::USImageSource connected to this device */ USImageSource::Pointer GetUSImageSource() override; /** * \brief Return all probes for this USVideoDevice or an empty vector it no probes were set * Returns a std::vector of all probes that exist for this USVideoDevice if there were probes set while creating or modifying this USVideoDevice. * Otherwise it returns an empty vector. Therefore always check if vector is filled, before using it! */ std::vector GetAllProbes(); + /** + * \brief Cleans the std::vector containing all configured probes. + */ + void DeleteAllProbes(); + /** * \brief Return current active probe for this USVideoDevice * Returns a pointer to the probe that is currently in use. If there were probes set while creating or modifying this USVideoDevice. * Returns null otherwise */ mitk::USProbe::Pointer GetCurrentProbe(); /** \brief adds a new probe to the device */ void AddNewProbe(mitk::USProbe::Pointer probe); /** * \brief get the probe by its name * Returns a pointer to the probe identified by the given name. If no probe of given name exists for this Device 0 is returned. */ mitk::USProbe::Pointer GetProbeByName(std::string name); /** * \brief Removes the Probe with the given name */ void RemoveProbeByName(std::string name); /** \brief True, if this Device plays back a file, false if it recieves data from a device */ bool GetIsSourceFile(); /** * \brief Sets the first existing probe or the default probe of the video device * as the current probe of it. */ void SetDefaultProbeAsCurrentProbe(); /** * \brief Sets the probe with the given name as current probe if the named probe exists. */ void SetCurrentProbe( std::string probename ); /** * \brief Sets the given spacing of the current depth of the current probe. */ void SetSpacing( double xSpacing, double ySpacing ) override; itkGetMacro(ImageVector, std::vector); itkGetMacro(DeviceID, int); itkGetMacro(FilePath, std::string); protected: /** * \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); ~USVideoDevice() override; /** * \brief Initializes common properties for all constructors. */ void Init(); /** * \brief Is called during the initialization process. * Returns true if successful and false if unsuccessful. Additionally, you may throw an exception to clarify what went wrong. */ bool OnInitialization() override; /** * \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. */ bool OnConnection() override; /** * \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. */ bool OnDisconnection() override; /** * \brief Is called during the activation process. After this method is finsihed, the device should be generating images */ bool OnActivation() override; /** * \brief Is called during the deactivation process. After a call to this method the device should still be connected, but not producing images anymore. */ bool OnDeactivation() override; /** * \brief Grabs the next frame from the Video input. * This method is called internally, whenever Update() is invoked by an Output. */ virtual void GenerateData() override; /** * \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; /** * \brief custom control interface for us video device */ itk::SmartPointer m_ControlInterfaceCustom; /** * \brief probes for this USVideoDevice */ std::vector < mitk::USProbe::Pointer > m_Probes; /** \brief probe that is currently in use */ mitk::USProbe::Pointer m_CurrentProbe; }; } // namespace mitk #endif // MITKUSVideoDevice_H_HEADER_INCLUDED_ diff --git a/Modules/US/files.cmake b/Modules/US/files.cmake index 93bf7bcfb2..42c099ed21 100644 --- a/Modules/US/files.cmake +++ b/Modules/US/files.cmake @@ -1,34 +1,36 @@ SET(CPP_FILES ## Module Activator mitkUSActivator.cpp ## Model Classes USModel/mitkUSImage.cpp USModel/mitkUSImageMetadata.cpp USModel/mitkUSDevice.cpp USModel/mitkUSIGTLDevice.cpp USModel/mitkUSVideoDevice.cpp USModel/mitkUSVideoDeviceCustomControls.cpp USModel/mitkUSProbe.cpp USModel/mitkUSDevicePersistence.cpp +USModel/mitkUSDeviceReaderXML.cpp +USModel/mitkUSDeviceWriterXML.cpp ## Filters and Sources USFilters/mitkUSImageLoggingFilter.cpp USFilters/mitkUSImageSource.cpp USFilters/mitkUSImageVideoSource.cpp USFilters/mitkIGTLMessageToUSImageFilter.cpp ## Control Interfaces USControlInterfaces/mitkUSAbstractControlInterface.cpp USControlInterfaces/mitkUSControlInterfaceBMode.cpp USControlInterfaces/mitkUSControlInterfaceProbes.cpp USControlInterfaces/mitkUSControlInterfaceDoppler.cpp USControlInterfaces/mitkUSDiPhASDeviceCustomControls.cpp ) set(RESOURCE_FILES Interactions/USPointMarkInteractions.xml Interactions/USZoneInteractions.xml Interactions/USZoneInteractionsHold.xml ) diff --git a/Modules/USUI/Qmitk/QmitkUSNewVideoDeviceWidget.cpp b/Modules/USUI/Qmitk/QmitkUSNewVideoDeviceWidget.cpp index 4912d53cad..b0414d5f81 100644 --- a/Modules/USUI/Qmitk/QmitkUSNewVideoDeviceWidget.cpp +++ b/Modules/USUI/Qmitk/QmitkUSNewVideoDeviceWidget.cpp @@ -1,405 +1,776 @@ /*=================================================================== 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 // mitk headers // itk headers +#include +#include + const std::string QmitkUSNewVideoDeviceWidget::VIEW_ID = "org.mitk.views.QmitkUSNewVideoDeviceWidget"; QmitkUSNewVideoDeviceWidget::QmitkUSNewVideoDeviceWidget(QWidget* parent, Qt::WindowFlags f) : QWidget(parent, f) { m_Controls = nullptr; CreateQtPartControl(this); } QmitkUSNewVideoDeviceWidget::~QmitkUSNewVideoDeviceWidget() {} //////////////////// INITIALIZATION ///////////////////// void QmitkUSNewVideoDeviceWidget::CreateQtPartControl(QWidget* parent) { if (!m_Controls) { // create GUI widgets m_Controls = new Ui::QmitkUSNewVideoDeviceWidgetControls; m_Controls->setupUi(parent); this->CreateConnections(); } } void QmitkUSNewVideoDeviceWidget::CreateConnections() { if (m_Controls) { // connect(m_Controls->m_BtnDone, SIGNAL(clicked()), this, // SLOT(OnClickedDone())); connect(m_Controls->m_BtnCancel, SIGNAL(clicked()), this, SLOT(OnClickedCancel())); connect(m_Controls->m_RadioDeviceSource, SIGNAL(clicked()), this, SLOT(OnDeviceTypeSelection())); connect(m_Controls->m_RadioFileSource, SIGNAL(clicked()), this, SLOT(OnDeviceTypeSelection())); connect(m_Controls->m_RadioOIGTLClientSource, SIGNAL(clicked()), this, SLOT(OnDeviceTypeSelection())); connect(m_Controls->m_RadioOIGTLServerSource, SIGNAL(clicked()), this, SLOT(OnDeviceTypeSelection())); connect(m_Controls->m_OpenFileButton, SIGNAL(clicked()), this, SLOT(OnOpenFileButtonClicked())); + connect(m_Controls->m_BtnSave, SIGNAL(clicked()), this, + SLOT(OnSaveButtonClicked())); + connect(m_Controls->m_BtnLoadConfiguration, SIGNAL(clicked()), this, + SLOT(OnLoadConfigurationButtonClicked())); + //Connect buttons and functions for editing of probes + connect(m_Controls->m_AddNewProbePushButton, SIGNAL(clicked()), this, SLOT(OnAddNewProbeClicked())); connect(m_Controls->m_BtnRemoveProbe, SIGNAL(clicked()), this, SLOT(OnClickedRemoveProbe())); connect(m_Controls->m_BtnRemoveDepth, SIGNAL(clicked()), this, SLOT(OnClickedRemoveDepth())); connect(m_Controls->m_BtnAddDepths, SIGNAL(clicked()), this, SLOT(OnClickedAddDepths())); connect(m_Controls->m_Probes, SIGNAL(currentTextChanged(const QString &)), this, SLOT(OnProbeChanged(const QString &))); + connect(m_Controls->m_Depths, SIGNAL(currentTextChanged(const QString &)), this, SLOT(OnDepthChanged(const QString &))); + + connect(m_Controls->m_XSpacingSpinBox, SIGNAL(valueChanged(double)), this, SLOT(OnXSpacingSpinBoxChanged(double))); + connect(m_Controls->m_YSpacingSpinBox, SIGNAL(valueChanged(double)), this, SLOT(OnYSpacingSpinBoxChanged(double))); + connect(m_Controls->m_CroppingTopSpinBox, SIGNAL(valueChanged(int)), this, SLOT(OnCroppingTopSpinBoxChanged(int))); + connect(m_Controls->m_CroppingRightSpinBox, SIGNAL(valueChanged(int)), this, SLOT(OnCroppingRightSpinBoxChanged(int))); + connect(m_Controls->m_CroppingBottomSpinBox, SIGNAL(valueChanged(int)), this, SLOT(OnCroppingBottomSpinBoxChanged(int))); + connect(m_Controls->m_CroppingLeftSpinBox, SIGNAL(valueChanged(int)), this, SLOT(OnCroppingLeftSpinBoxChanged(int))); } } ///////////// Methods & Slots Handling Direct Interaction ///////////////// void QmitkUSNewVideoDeviceWidget::OnClickedDone() { m_Active = false; // Create Device mitk::USVideoDevice::Pointer newDevice; if (m_Controls->m_RadioDeviceSource->isChecked()) { newDevice = mitk::USVideoDevice::New( m_Controls->m_DeviceSelector->value(), m_Controls->m_Manufacturer->text().toStdString(), m_Controls->m_Model->text().toStdString()); newDevice->SetComment(m_Controls->m_Comment->text().toStdString()); } else if (m_Controls->m_RadioFileSource->isChecked()) { newDevice = mitk::USVideoDevice::New( m_Controls->m_FilePathSelector->text().toStdString(), m_Controls->m_Manufacturer->text().toStdString(), m_Controls->m_Model->text().toStdString()); newDevice->SetComment(m_Controls->m_Comment->text().toStdString()); } else if (m_Controls->m_RadioOIGTLClientSource->isChecked()) { std::string host = m_Controls->m_OIGTLClientHost->text().toStdString(); int port = m_Controls->m_OIGTLClientPort->value(); // Create a new USIGTLDevice. The last parameter tells the device that it should be a client. mitk::USIGTLDevice::Pointer device = mitk::USIGTLDevice::New(m_Controls->m_Manufacturer->text().toStdString(), m_Controls->m_Model->text().toStdString(), host, port, false); device->Initialize(); emit Finished(); // The rest of this method does stuff that is specific to USVideoDevices, // which we don't need. So we return directly. return; } else { std::string host = m_Controls->m_OIGTLServerHost->text().toStdString(); int port = m_Controls->m_OIGTLServerPort->value(); // Create a new USIGTLDevice. The last parameter tells the device that it should be a server. mitk::USIGTLDevice::Pointer device = mitk::USIGTLDevice::New(m_Controls->m_Manufacturer->text().toStdString(), m_Controls->m_Model->text().toStdString(), host, port, true); device->Initialize(); emit Finished(); // The rest of this method does stuff that is specific to USVideoDevices, // which we don't need. So we return directly. return; } // get USImageVideoSource from new device mitk::USImageVideoSource::Pointer imageSource = dynamic_cast( newDevice->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(!m_Controls->m_CheckGreyscale->isChecked()); // If Resolution override is activated, apply it if (m_Controls->m_CheckResolutionOverride->isChecked()) { int width = m_Controls->m_ResolutionWidth->value(); int height = m_Controls->m_ResolutionHeight->value(); imageSource->OverrideResolution(width, height); imageSource->SetResolutionOverride(true); } - if (!m_Controls->m_ProbesInformation->text().isEmpty()) //there are informations about the probes of the device, so create the probes + if (m_Controls->m_Probes->count() != 0 ) //there are informations about the probes of the device, so create the probes { - AddProbesToDevice(newDevice); + this->AddProbesToDevice(newDevice); } else //no information about the probes of the device, so set default value { mitk::USProbe::Pointer probe = mitk::USProbe::New("default"); probe->SetDepth(0); + newDevice->DeleteAllProbes(); newDevice->AddNewProbe(probe); } newDevice->Initialize(); CleanUpAfterCreatingNewDevice(); emit Finished(); } void QmitkUSNewVideoDeviceWidget::OnClickedFinishedEditing() { m_Active = false; m_TargetDevice->SetManufacturer(m_Controls->m_Manufacturer->text().toStdString()); m_TargetDevice->SetName(m_Controls->m_Model->text().toStdString()); m_TargetDevice->SetComment(m_Controls->m_Comment->text().toStdString()); - if (!m_Controls->m_ProbesInformation->text().isEmpty()){ //there is information about probes to add, so add them - AddProbesToDevice(m_TargetDevice); + if (m_Controls->m_Probes->count() != 0) //there are informations about the probes of the device, so create the probes + { + this->AddProbesToDevice(m_TargetDevice); } + else //no information about the probes of the device, so set default value + { + mitk::USProbe::Pointer probe = mitk::USProbe::New("default"); + probe->SetDepth(0); + m_TargetDevice->DeleteAllProbes(); + m_TargetDevice->AddNewProbe(probe); + } + mitk::USImageVideoSource::Pointer imageSource = dynamic_cast( m_TargetDevice->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(!m_Controls->m_CheckGreyscale->isChecked()); // If Resolution override is activated, apply it if (m_Controls->m_CheckResolutionOverride->isChecked()) { int width = m_Controls->m_ResolutionWidth->value(); int height = m_Controls->m_ResolutionHeight->value(); imageSource->OverrideResolution(width, height); imageSource->SetResolutionOverride(true); } CleanUpAfterEditingOfDevice(); MITK_INFO << "Finished Editing"; emit Finished(); } void QmitkUSNewVideoDeviceWidget::OnClickedCancel() { m_TargetDevice = nullptr; m_Active = false; CleanUpAfterCreatingNewDevice(); CleanUpAfterEditingOfDevice(); emit Finished(); } void QmitkUSNewVideoDeviceWidget::OnDeviceTypeSelection() { m_Controls->m_FilePathSelector->setEnabled( m_Controls->m_RadioFileSource->isChecked()); m_Controls->m_DeviceSelector->setEnabled( m_Controls->m_RadioDeviceSource->isChecked()); m_Controls->m_OIGTLClientHost->setEnabled( m_Controls->m_RadioOIGTLClientSource->isChecked()); m_Controls->m_OIGTLClientPort->setEnabled( m_Controls->m_RadioOIGTLClientSource->isChecked()); m_Controls->m_OIGTLServerHost->setEnabled( m_Controls->m_RadioOIGTLServerSource->isChecked()); m_Controls->m_OIGTLServerPort->setEnabled( m_Controls->m_RadioOIGTLServerSource->isChecked()); } void QmitkUSNewVideoDeviceWidget::OnOpenFileButtonClicked() { QString fileName = QFileDialog::getOpenFileName(nullptr, "Open Video File"); if (fileName.isNull()) { return; } // user pressed cancel m_Controls->m_FilePathSelector->setText(fileName); m_Controls->m_RadioFileSource->setChecked(true); this->OnDeviceTypeSelection(); } ///////////////// Methods & Slots Handling Logic ////////////////////////// void QmitkUSNewVideoDeviceWidget::EditDevice(mitk::USDevice::Pointer device) { // If no VideoDevice is given, throw an exception - if (device.IsNull()) - { - mitkThrow() << "No device selected"; - } - else if (device->GetDeviceClass().compare("org.mitk.modules.us.USVideoDevice") != + if (device->GetDeviceClass().compare("org.mitk.modules.us.USVideoDevice") != 0) { // TODO Alert if bad path mitkThrow() << "NewVideoDeviceWidget recieved an incompatible device type " "to edit. Type was: " << device->GetDeviceClass(); } m_TargetDevice = static_cast(device.GetPointer()); m_Active = true; - + m_ConfigProbes.clear(); + m_ConfigProbes = m_TargetDevice->GetAllProbes(); ChangeUIEditingUSVideoDevice(); } void QmitkUSNewVideoDeviceWidget::CreateNewDevice() { - //When new device is created there are no probes to edit, therefore disable the Groupbox - m_Controls->m_GroupBoxEditProbes->setEnabled(false); - //Toggle functionality of Btn_Done connect(m_Controls->m_BtnDone, SIGNAL(clicked()), this, SLOT(OnClickedDone())); m_Controls->m_BtnDone->setText("Add Video Device"); //Fill Metadata with default information m_Controls->m_Manufacturer->setText("Unknown Manufacturer"); m_Controls->m_Model->setText("Unknown Model"); m_Controls->m_Comment->setText("None"); m_TargetDevice = nullptr; + m_ConfigProbes.clear(); m_Active = true; } /////////////////////// HOUSEHOLDING CODE /////////////////////////////// QListWidgetItem* QmitkUSNewVideoDeviceWidget::ConstructItemFromDevice( mitk::USDevice::Pointer device) { QListWidgetItem* result = new QListWidgetItem; std::string text = device->GetManufacturer() + "|" + device->GetName(); result->setText(text.c_str()); return result; } void QmitkUSNewVideoDeviceWidget::ChangeUIEditingUSVideoDevice() { - //activate the groupbox contaning the options to edit the probes of the device and fill it with information - m_Controls->m_GroupBoxEditProbes->setEnabled(true); - std::vector probes = m_TargetDevice->GetAllProbes(); - for (std::vector::iterator it = probes.begin(); it != probes.end(); it++) + for (std::vector::iterator it = m_ConfigProbes.begin(); it != m_ConfigProbes.end(); it++) { std::string probeName = (*it)->GetName(); m_Controls->m_Probes->addItem(QString::fromUtf8(probeName.data(), probeName.size())); } OnProbeChanged(m_Controls->m_Probes->currentText()); //Toggle functionality of Btn_Done - m_Controls->m_BtnDone->setText("Save Changes"); + m_Controls->m_BtnDone->setText("Apply Changes"); connect(m_Controls->m_BtnDone, SIGNAL(clicked()), this, SLOT(OnClickedFinishedEditing())); //Fill Metadata with Information provided by the Device selected to edit m_Controls->m_Manufacturer->setText(m_TargetDevice->GetManufacturer().c_str()); m_Controls->m_Model->setText(m_TargetDevice->GetName().c_str()); m_Controls->m_Comment->setText(m_TargetDevice->GetComment().c_str()); } void QmitkUSNewVideoDeviceWidget::OnClickedAddDepths() { if (!m_Controls->m_Probes->currentText().isEmpty()) { - std::string probename = m_Controls->m_Probes->currentText().toStdString(); - mitk::USProbe::Pointer currentProbe = m_TargetDevice->GetProbeByName(probename); QString depths = m_Controls->m_AddDepths->text(); + if( depths.isEmpty() ) + return; + + std::string probename = m_Controls->m_Probes->currentText().toStdString(); + mitk::USProbe::Pointer currentProbe = this->CheckIfProbeExistsAlready(probename); + QStringList singleDepths = depths.split(','); for (int i = 0; i < singleDepths.size(); i++) { currentProbe->SetDepth(singleDepths.at(i).toInt()); } m_Controls->m_AddDepths->clear(); + m_Controls->m_Depths->setEnabled(true); + m_Controls->m_BtnRemoveDepth->setEnabled(true); OnProbeChanged(m_Controls->m_Probes->currentText()); } } void QmitkUSNewVideoDeviceWidget::OnClickedRemoveDepth() { if (!m_Controls->m_Probes->currentText().isEmpty() && !m_Controls->m_Depths->currentText().isEmpty()) { std::string probename = m_Controls->m_Probes->currentText().toStdString(); int indexOfDepthToRemove = m_Controls->m_Depths->currentIndex(); - mitk::USProbe::Pointer currentProbe = m_TargetDevice->GetProbeByName(probename); + mitk::USProbe::Pointer currentProbe = this->CheckIfProbeExistsAlready(probename); currentProbe->RemoveDepth(m_Controls->m_Depths->currentText().toInt()); m_Controls->m_Depths->removeItem(indexOfDepthToRemove); + + if (m_Controls->m_Depths->count() == 0) + { + m_Controls->m_Depths->setEnabled(false); + m_Controls->m_BtnRemoveDepth->setEnabled(false); + + this->EnableDisableSpacingAndCropping(false); + } } } void QmitkUSNewVideoDeviceWidget::OnClickedRemoveProbe() { if (!m_Controls->m_Probes->currentText().isEmpty()) { std::string probename = m_Controls->m_Probes->currentText().toStdString(); int indexOfProbeToRemove = m_Controls->m_Probes->currentIndex(); - m_TargetDevice->RemoveProbeByName(probename); + m_ConfigProbes.erase(m_ConfigProbes.begin() + indexOfProbeToRemove); m_Controls->m_Probes->removeItem(indexOfProbeToRemove); + if( m_Controls->m_Probes->count() == 0 ) + { + m_Controls->m_Probes->setEnabled(false); + m_Controls->m_BtnRemoveProbe->setEnabled(false); + m_Controls->m_BtnAddDepths->setEnabled(false); + m_Controls->m_AddDepths->setEnabled(false); + m_Controls->m_Depths->setEnabled(false); + m_Controls->m_BtnRemoveDepth->setEnabled(false); + + this->EnableDisableSpacingAndCropping(false); + } } } void QmitkUSNewVideoDeviceWidget::OnProbeChanged(const QString & probename) { if (!probename.isEmpty()) { std::string name = probename.toStdString(); - mitk::USProbe::Pointer probe = m_TargetDevice->GetProbeByName(name); - std::map depths = probe->GetDepthsAndSpacing(); + mitk::USProbe::Pointer probe = this->CheckIfProbeExistsAlready(name); + if( probe.IsNotNull() ) + { + std::map depths = probe->GetDepthsAndSpacing(); + m_Controls->m_Depths->clear(); + for (std::map::iterator it = depths.begin(); it != depths.end(); it++) + { + m_Controls->m_Depths->addItem(QString::number(it->first)); + } + + this->OnDepthChanged(m_Controls->m_Depths->currentText().toInt(), probe); + } + } + else + { m_Controls->m_Depths->clear(); - for (std::map::iterator it = depths.begin(); it != depths.end(); it++) + m_Controls->m_Depths->setEnabled(false); + m_Controls->m_BtnRemoveDepth->setEnabled(false); + } +} + +void QmitkUSNewVideoDeviceWidget::OnDepthChanged(int depth, mitk::USProbe* probe) +{ + if (m_Controls->m_Depths->count() == 0) + { + m_Controls->m_Depths->setEnabled(false); + m_Controls->m_BtnRemoveDepth->setEnabled(false); + + this->EnableDisableSpacingAndCropping(false); + return; + } + + if (probe != nullptr) + { + mitk::Vector3D spacing = probe->GetSpacingForGivenDepth(depth); + m_Controls->m_XSpacingSpinBox->setValue(spacing[0]); + m_Controls->m_YSpacingSpinBox->setValue(spacing[1]); + + mitk::USProbe::USProbeCropping cropping = probe->GetProbeCropping(); + m_Controls->m_CroppingTopSpinBox->setValue(cropping.top); + m_Controls->m_CroppingRightSpinBox->setValue(cropping.right); + m_Controls->m_CroppingBottomSpinBox->setValue(cropping.bottom); + m_Controls->m_CroppingLeftSpinBox->setValue(cropping.left); + + this->EnableDisableSpacingAndCropping(true); + + m_Controls->m_Depths->setEnabled(true); + m_Controls->m_BtnRemoveDepth->setEnabled(true); + m_Controls->m_AddDepths->setEnabled(true); + m_Controls->m_BtnAddDepths->setEnabled(true); + m_Controls->m_Probes->setEnabled(true); + m_Controls->m_BtnRemoveProbe->setEnabled(true); + } +} + +void QmitkUSNewVideoDeviceWidget::OnDepthChanged(const QString &depth) +{ + MITK_INFO << "OnDepthChanged(int, mitk::USProbe)"; + if( depth.isEmpty() ) + { + this->EnableDisableSpacingAndCropping(false); + return; + } + QString probeName = m_Controls->m_Probes->currentText(); + + this->OnDepthChanged(depth.toInt(), this->CheckIfProbeExistsAlready(probeName.toStdString()) ); +} + +void QmitkUSNewVideoDeviceWidget::OnSaveButtonClicked() +{ + QMessageBox msgBox; + msgBox.setText("This feature is not implemented yet."); + msgBox.exec(); + return; + /* + QString fileName = QFileDialog::getSaveFileName(nullptr, "Save Configuration ..."); + if( fileName.isNull() ) + { + return; + } // user pressed cancel + */ + +} + +void QmitkUSNewVideoDeviceWidget::OnLoadConfigurationButtonClicked() +{ + QString fileName = QFileDialog::getOpenFileName(this, "Open ultrasound device configuration ..."); + if (fileName.isNull()) + { + return; + } // user pressed cancel + + mitk::USDeviceReaderXML deviceReader; + deviceReader.SetFilename(fileName.toStdString()); + if (!deviceReader.ReadUltrasoundDeviceConfiguration()) + { + QMessageBox msgBox; + msgBox.setText("Error when parsing the selected file. Could not load stored device information."); + msgBox.exec(); + return; + } + mitk::USDeviceReaderXML::USVideoDeviceConfigData config = deviceReader.GetUSVideoDeviceConfigData(); + + if( config.fileversion == 1.0 ) + { + if (config.deviceType.compare("video") == 0) { - m_Controls->m_Depths->addItem(QString::number(it->first)); + //Fill info in metadata groupbox: + m_Controls->m_DeviceName->setText(QString::fromStdString(config.deviceName)); + m_Controls->m_Manufacturer->setText(QString::fromStdString(config.manufacturer)); + m_Controls->m_Model->setText(QString::fromStdString(config.model)); + m_Controls->m_Comment->setText(QString::fromStdString(config.comment)); + + //Fill info about video source: + m_Controls->m_DeviceSelector->setValue(config.sourceID); + m_Controls->m_FilePathSelector->setText(QString::fromStdString(config.filepathVideoSource)); + + //Fill video options: + m_Controls->m_CheckGreyscale->setChecked(config.useGreyscale); + + //Fill override options: + m_Controls->m_CheckResolutionOverride->setChecked(config.useResolutionOverride); + m_Controls->m_ResolutionWidth->setValue(config.resolutionWidth); + m_Controls->m_ResolutionHeight->setValue(config.resolutionHeight); + + //Fill information about probes: + m_ConfigProbes.clear(); + m_ConfigProbes = config.probes; + + m_Controls->m_Probes->clear(); + m_Controls->m_ProbeNameLineEdit->clear(); + m_Controls->m_AddDepths->clear(); + m_Controls->m_Depths->clear(); + + for( int index = 0; index < m_ConfigProbes.size(); ++index) + { + m_Controls->m_Probes->addItem(QString::fromStdString(config.probes.at(index)->GetName())); + } + this->OnProbeChanged(m_Controls->m_Probes->currentText()); + } + else + { + MITK_WARN << "Unknown device type detected. The device type must be of type |video|"; + } + } + else + { + MITK_WARN << "Unknown fileversion. Only fileversion 1.0 is known to the system."; } } +void QmitkUSNewVideoDeviceWidget::OnAddNewProbeClicked() +{ + QString probeName = m_Controls->m_ProbeNameLineEdit->text(); + probeName = probeName.trimmed(); + if (probeName.isEmpty()) + { + m_Controls->m_ProbeNameLineEdit->clear(); + return; + } + + if( this->CheckIfProbeExistsAlready(probeName.toStdString() ) != nullptr ) + { + QMessageBox msgBox; + msgBox.setText("Probe name already exists. Please choose another name for the probe."); + msgBox.exec(); + m_Controls->m_ProbeNameLineEdit->clear(); + } + else + { + mitk::USProbe::Pointer newProbe = mitk::USProbe::New(probeName.toStdString()); + m_ConfigProbes.push_back(newProbe); + m_Controls->m_Probes->addItem(QString::fromStdString(probeName.toStdString())); + + m_Controls->m_Probes->setEnabled(true); + m_Controls->m_BtnRemoveProbe->setEnabled(true); + m_Controls->m_BtnAddDepths->setEnabled(true); + m_Controls->m_AddDepths->setEnabled(true); + m_Controls->m_ProbeNameLineEdit->clear(); + } +} + +void QmitkUSNewVideoDeviceWidget::OnXSpacingSpinBoxChanged(double value) +{ + MITK_INFO << "Changing x-spacing to: " << value; + QString probeName = m_Controls->m_Probes->currentText(); + int depth = m_Controls->m_Depths->currentText().toInt(); + + mitk::USProbe::Pointer probe = this->CheckIfProbeExistsAlready(probeName.toStdString()); + if (probe.IsNull()) + { + QMessageBox msgBox; + msgBox.setText("An error occurred when changing the spacing. \ + The specified probe does not exist. \ + Please restart the configuration process."); + msgBox.exec(); + return; + } + + mitk::Vector3D spacing = probe->GetSpacingForGivenDepth(depth); + spacing[0] = value; + probe->SetSpacingForGivenDepth(depth, spacing); +} + +void QmitkUSNewVideoDeviceWidget::OnYSpacingSpinBoxChanged(double value) +{ + MITK_INFO << "Changing y-spacing to: " << value; + QString probeName = m_Controls->m_Probes->currentText(); + int depth = m_Controls->m_Depths->currentText().toInt(); + + mitk::USProbe::Pointer probe = this->CheckIfProbeExistsAlready(probeName.toStdString()); + if (probe.IsNull()) + { + QMessageBox msgBox; + msgBox.setText("An error occurred when changing the spacing. \ + The specified probe does not exist. \ + Please restart the configuration process."); + msgBox.exec(); + return; + } + + mitk::Vector3D spacing = probe->GetSpacingForGivenDepth(depth); + spacing[1] = value; + probe->SetSpacingForGivenDepth(depth, spacing); +} + +void QmitkUSNewVideoDeviceWidget::OnCroppingTopSpinBoxChanged(int value) +{ + MITK_INFO << "Changing cropping top to: " << value; + QString probeName = m_Controls->m_Probes->currentText(); + + mitk::USProbe::Pointer probe = this->CheckIfProbeExistsAlready(probeName.toStdString()); + if (probe.IsNull()) + { + QMessageBox msgBox; + msgBox.setText("An error occurred when changing the probe cropping. \ + The specified probe does not exist. \ + Please restart the configuration process."); + msgBox.exec(); + return; + } + + mitk::USProbe::USProbeCropping cropping = probe->GetProbeCropping(); + probe->SetProbeCropping(value, cropping.bottom, cropping.left, cropping.right); +} + +void QmitkUSNewVideoDeviceWidget::OnCroppingRightSpinBoxChanged(int value) +{ + MITK_INFO << "Changing cropping right to: " << value; + QString probeName = m_Controls->m_Probes->currentText(); + + mitk::USProbe::Pointer probe = this->CheckIfProbeExistsAlready(probeName.toStdString()); + if (probe.IsNull()) + { + QMessageBox msgBox; + msgBox.setText("An error occurred when changing the probe cropping. \ + The specified probe does not exist. \ + Please restart the configuration process."); + msgBox.exec(); + return; + } + + mitk::USProbe::USProbeCropping cropping = probe->GetProbeCropping(); + probe->SetProbeCropping(cropping.top, cropping.bottom, cropping.left, value); +} + +void QmitkUSNewVideoDeviceWidget::OnCroppingBottomSpinBoxChanged(int value) +{ + MITK_INFO << "Changing cropping bottom to: " << value; + QString probeName = m_Controls->m_Probes->currentText(); + + mitk::USProbe::Pointer probe = this->CheckIfProbeExistsAlready(probeName.toStdString()); + if (probe.IsNull()) + { + QMessageBox msgBox; + msgBox.setText("An error occurred when changing the probe cropping. \ + The specified probe does not exist. \ + Please restart the configuration process."); + msgBox.exec(); + return; + } + + mitk::USProbe::USProbeCropping cropping = probe->GetProbeCropping(); + probe->SetProbeCropping(cropping.top, value, cropping.left, cropping.right); +} + +void QmitkUSNewVideoDeviceWidget::OnCroppingLeftSpinBoxChanged(int value) +{ + MITK_INFO << "Changing cropping left to: " << value; + QString probeName = m_Controls->m_Probes->currentText(); + + mitk::USProbe::Pointer probe = this->CheckIfProbeExistsAlready(probeName.toStdString()); + if (probe.IsNull()) + { + QMessageBox msgBox; + msgBox.setText("An error occurred when changing the probe cropping. \ + The specified probe does not exist. \ + Please restart the configuration process."); + msgBox.exec(); + return; + } + + mitk::USProbe::USProbeCropping cropping = probe->GetProbeCropping(); + probe->SetProbeCropping(cropping.top, cropping.bottom, value, cropping.right); +} + void QmitkUSNewVideoDeviceWidget::CleanUpAfterCreatingNewDevice() { disconnect(m_Controls->m_BtnDone, SIGNAL(clicked()), this, SLOT(OnClickedDone())); - m_Controls->m_ProbesInformation->clear(); + m_Controls->m_Probes->clear(); + m_Controls->m_Depths->clear(); + m_Controls->m_AddDepths->clear(); + m_Controls->m_ProbeNameLineEdit->clear(); + m_ConfigProbes.clear(); } void QmitkUSNewVideoDeviceWidget::CleanUpAfterEditingOfDevice() { disconnect(m_Controls->m_BtnDone, SIGNAL(clicked()), this, SLOT(OnClickedFinishedEditing())); m_Controls->m_Probes->clear(); m_Controls->m_Depths->clear(); m_Controls->m_AddDepths->clear(); - m_Controls->m_ProbesInformation->clear(); + m_ConfigProbes.clear(); } void QmitkUSNewVideoDeviceWidget::AddProbesToDevice(mitk::USVideoDevice::Pointer device) { - QString probesInformation = m_Controls->m_ProbesInformation->text(); - QStringList probes = probesInformation.split(';'); //split the different probes - for (int i = 0; i < probes.size(); i++) + device->DeleteAllProbes(); + for( std::vector::iterator it = m_ConfigProbes.begin(); + it != m_ConfigProbes.end(); it++) { - QStringList depths = probes.at(i).split(','); //now for every probe split the probe name and the different depths - mitk::USProbe::Pointer probe = mitk::USProbe::New(); - probe->SetName(depths.at(0).toStdString()); //first element is the probe name - for (int i = 1; i < depths.size(); i++) //all the other elements are the depths for the specific probe so add them to the probe + if ((*it)->IsDepthAndSpacingEmpty()) { - probe->SetDepth(depths.at(i).toInt()); + (*it)->SetDepth(0); } - device->AddNewProbe(probe); + device->AddNewProbe((*it)); } } + +mitk::USProbe::Pointer QmitkUSNewVideoDeviceWidget::CheckIfProbeExistsAlready(std::string &probeName) +{ + for( std::vector::iterator it = m_ConfigProbes.begin(); + it != m_ConfigProbes.end(); it++ ) + { + if( probeName.compare((*it)->GetName()) == 0) + return (*it); + } + return nullptr; //no matching probe was found so nullptr is returned +} + +void QmitkUSNewVideoDeviceWidget::EnableDisableSpacingAndCropping(bool enable) +{ + m_Controls->m_XSpacingSpinBox->setEnabled(enable); + m_Controls->m_YSpacingSpinBox->setEnabled(enable); + m_Controls->m_XSpacingLabel->setEnabled(enable); + m_Controls->m_YSpacingLabel->setEnabled(enable); + + m_Controls->m_CroppingTopSpinBox->setEnabled(enable); + m_Controls->m_CroppingRightSpinBox->setEnabled(enable); + m_Controls->m_CroppingBottomSpinBox->setEnabled(enable); + m_Controls->m_CroppingLeftSpinBox->setEnabled(enable); + m_Controls->m_CroppingTopLabel->setEnabled(enable); + m_Controls->m_CroppingBottomLabel->setEnabled(enable); + m_Controls->m_CroppingLeftLabel->setEnabled(enable); + m_Controls->m_CroppingRightLabel->setEnabled(enable); +} diff --git a/Modules/USUI/Qmitk/QmitkUSNewVideoDeviceWidget.h b/Modules/USUI/Qmitk/QmitkUSNewVideoDeviceWidget.h index be811eb4ed..0e9adbaf46 100644 --- a/Modules/USUI/Qmitk/QmitkUSNewVideoDeviceWidget.h +++ b/Modules/USUI/Qmitk/QmitkUSNewVideoDeviceWidget.h @@ -1,130 +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 _QmitkUSNewVideoDeviceWidget_H_INCLUDED #define _QmitkUSNewVideoDeviceWidget_H_INCLUDED #include "MitkUSUIExports.h" #include "ui_QmitkUSNewVideoDeviceWidgetControls.h" #include "mitkUSVideoDevice.h" #include "mitkUSIGTLDevice.h" //QT headers #include #include //mitk header /** * @brief This Widget enables the USer to create and connect Video Devices. * * @ingroup USUI */ class MITKUSUI_EXPORT QmitkUSNewVideoDeviceWidget :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; QmitkUSNewVideoDeviceWidget(QWidget* p = nullptr, Qt::WindowFlags f1 = nullptr); ~QmitkUSNewVideoDeviceWidget() override; /* @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(); signals: void Finished(); public slots: /* \brief Activates the widget and displays the given device's Data to edit. */ void EditDevice(mitk::USDevice::Pointer device); /* \brief Activates the widget with fields empty. */ void CreateNewDevice(); protected slots: /* \brief Called, when the the user clicks the "Done" button (Labeled either "Add Device" or "Edit Device", depending on the situation. */ void OnClickedDone(); void OnClickedFinishedEditing(); /* \brief Called, when the button "Cancel" was clicked */ void OnClickedCancel(); /* \brief Called, when the Use selects one of the Radiobuttons */ void OnDeviceTypeSelection(); void OnOpenFileButtonClicked(); void OnClickedRemoveProbe(); void OnClickedRemoveDepth(); void OnClickedAddDepths(); void OnProbeChanged(const QString & probename); + void OnDepthChanged(int depth, mitk::USProbe* probe); + + void OnDepthChanged(const QString &depth); + + void OnSaveButtonClicked(); + + void OnLoadConfigurationButtonClicked(); + + void OnAddNewProbeClicked(); + + void OnXSpacingSpinBoxChanged(double value); + + void OnYSpacingSpinBoxChanged(double value); + + void OnCroppingTopSpinBoxChanged(int value); + + void OnCroppingRightSpinBoxChanged(int value); + + void OnCroppingBottomSpinBoxChanged(int value); + + void OnCroppingLeftSpinBoxChanged(int value); + protected: Ui::QmitkUSNewVideoDeviceWidgetControls* m_Controls; ///< member holding the UI elements of this widget /* \brief Constructs a ListItem from the given device for display in the list of active devices */ QListWidgetItem* ConstructItemFromDevice(mitk::USDevice::Pointer device); void ChangeUIEditingUSVideoDevice(); void CleanUpAfterEditingOfDevice(); void CleanUpAfterCreatingNewDevice(); void AddProbesToDevice(mitk::USVideoDevice::Pointer device); + mitk::USProbe::Pointer CheckIfProbeExistsAlready(std::string &probe); + + /** + * \brief Enables or disables the GUI elements of the spacing and cropping options. + * \param enable If true: the GUI elements are enabled. If false: elements are disabled. + */ + void EnableDisableSpacingAndCropping(bool enable); + /* \brief Displays whether this widget is active or not. It gets activated by either sending a Signal to * the "CreateNewDevice" Slot or to the "EditDevice" Slot. If the user finishes editing the device, a * "EditingComplete" Signal is sent, and the widget is set to inactive again. Clicking Cancel also * deactivates it. */ bool m_Active; /** * \brief This is the device to edit. It is either the device transmitted in the "EditDevice" signal, or a new one * if the "CreateNewDevice slot was called. */ mitk::USVideoDevice::Pointer m_TargetDevice; + + /** + * \brief The config probes are used to have a possibility to configure ultrasound probes without having an existing + * created USVideoDevice yet. + */ + std::vector m_ConfigProbes; }; #endif // _QmitkUSNewVideoDeviceWidget_H_INCLUDED diff --git a/Modules/USUI/Qmitk/QmitkUSNewVideoDeviceWidgetControls.ui b/Modules/USUI/Qmitk/QmitkUSNewVideoDeviceWidgetControls.ui index 33f618298a..44e004599b 100644 --- a/Modules/USUI/Qmitk/QmitkUSNewVideoDeviceWidgetControls.ui +++ b/Modules/USUI/Qmitk/QmitkUSNewVideoDeviceWidgetControls.ui @@ -1,543 +1,710 @@ QmitkUSNewVideoDeviceWidgetControls 0 0 - 333 + 332 972 0 0 QmitkUSNewVideoDeviceWidget - + QLayout::SetDefaultConstraint - - QFormLayout::AllNonFixedFieldsGrow - 0 - 0 + 10 0 0 - + + + + + + Add Video Device + + + + :/USUI/accept.png:/USUI/accept.png + + + + + + + Cancel + + + + :/USUI/restart.png:/USUI/restart.png + + + + + + + + + 0 + + + + + Load Device Configuration + + + + + + + Save->File + + + + :/USUI/accept.png:/USUI/accept.png + + + + + + + + + Metadata: + + + + + + Unknown Manufacturer + + + + + + + Model + + + + + + + + 50 + false + true + + + + Device Information: + + + + + + + Comment + + + + + + + Manufacturer + + + + + + + Unknown Model + + + + + + + None + + + + + + + Name + + + + + + + USVideoDevice + + + + + + + Video Source: From Device: true 0 10 0 From File: false ... OIGTL Server false localhost false 1 65535 18944 OIGTL Client false localhost false 1 65535 18944 - - - - Video Options: - - - - - - Greyscale Image (Significantly faster) - - - true - - - - - - - - - - - - Add Video Device - - - - :/USUI/accept.png:/USUI/accept.png - - - - - - - Cancel - - - - :/USUI/restart.png:/USUI/restart.png - - - - - - - - - - 0 - 0 - + + + + true - 50 - 130 + 0 + 180 - Add Probes - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + Edit Probes - - - - - Enter the names of the probes of the VideoDevice and, separated by commas, its scanning depths. If you want to add several probes separate the probes and their informations by semicolons E.g. ACV,100,120,150;BDW,90,100;CSV,120,150,180 + + + + + false - - Qt::AutoText + + 6 - - true + + 0.000001000000000 - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + + 1.000000000000000 - - true + + 0.010000000000000 - - -2 + + 1.000000000000000 - - + + + + false + + + Qt::WheelFocus + + + Enter a depth to add to the chosen probe + + - - - - - - - Override: - - - - + + + + true + - Width: + Probes - - - - - 0 - 0 - + + + + false - - 10 + + Qt::WheelFocus - - 2048 + + Add Depth - - 10 + + + + + + false - - 480 + + Cropping Right - - + + + + false + - Height: + Cropping Top - - - - - 0 - 0 - - - - 10 + + + + false - - 2048 + + Cropping Bottom - - 10 + + + + + + - - 640 + + Enter the name of the probe - - + + - Enable Resolution Override + Add New Probe - - - - If you encounter problems with devices (e.g. Images of uniform color and error messages in the log window), then try to set the resolution externally using the device's driver panel and then enter the same resolution here. + + + + false - - true + + Spacing Y-direction - - - - - - - false - - - - 0 - 180 - - - - Edit Probes - - - - + + + + false + - Probes + Spacing X-direction - - - - - 0 - 0 - + + + + false + + + 6 + + + 0.000001000000000 + + + 1.000000000000000 + + + 0.010000000000000 + + + 1.000000000000000 - + + + false + 0 0 Qt::WheelFocus Remove this Probe - - - - Scanning Depths for chosen Probe + + + + false + + + + 0 + 0 + - + + + false + 0 0 - + + + false + 0 0 Qt::WheelFocus Remove this Depth - + + + false + - Enter Scanning Depths you want to add to chosen Probe. -Seperate them by commas. E.g. 120,150,180 + Scanning depths for chosen probe - - - - Qt::WheelFocus + + + + false + + + 400 - - - - Qt::WheelFocus + + + + false + + + 400 + + + + + + + false - Add Depths + Cropping Left + + + + + + + false + + + 400 + + + + + + + false + + + 400 - - + + - Metadata: + Video Options: - - - + + + - Comment + Greyscale Image (Significantly faster) + + + true - - - - - 50 - false - true - - + + + + + + + Override: + + + + - Device Information: + Width: - - - - Manufacturer + + + + + 0 + 0 + + + + 10 + + + 2048 + + + 10 + + + 480 - - + + - Unknown Manufacturer + Height: - - - - Model + + + + + 0 + 0 + + + + 10 + + + 2048 + + + 10 + + + 640 - - + + - Unknown Model + Enable Resolution Override - - + + - None + If you encounter problems with devices (e.g. Images of uniform color and error messages in the log window), then try to set the resolution externally using the device's driver panel and then enter the same resolution here. + + + true m_Manufacturer m_Model m_Comment m_RadioDeviceSource m_DeviceSelector m_RadioFileSource m_CheckResolutionOverride