diff --git a/CMake/BuildConfigurations/camiPhotoacousticsSetup.cmake b/CMake/BuildConfigurations/camiPhotoacousticsSetup.cmake
index 3f745c3d34..4a881e5fb6 100644
--- a/CMake/BuildConfigurations/camiPhotoacousticsSetup.cmake
+++ b/CMake/BuildConfigurations/camiPhotoacousticsSetup.cmake
@@ -1,25 +1,25 @@
message(STATUS "Configuring MITK Photoacoustics Setup Build")
# Enable open cv and open igt link, which is a necessary configuration
set(MITK_USE_OpenCV ON CACHE BOOL "MITK Use OpenCV Library" FORCE)
set(MITK_USE_OpenIGTLink ON CACHE BOOL "MITK Use OpenIGTLink Library" FORCE)
set(MITK_USE_US_DiPhAS_SDK ON CACHE BOOL "Use DiPhAS SDK" FORCE)
set(MITK_US_DiPhAS_SDK_PATH "C:/Users/dkfz/Source/Repos/UltrasoundResearchPlatform_SDK/UltrasoundResearchPlatformSDK_Cpp/x64" CACHE PATH "DiPhAS SDK Path")
set(MITK_USE_OPHIR_PYRO_HARDWARE ON CACHE BOOL "Use the Ophir sensor build-in in OPOTEK Phocus Mobile" FORCE)
set(MITK_OPHIR_API_PATH "C:/OphirCppWrapper" CACHE PATH "Ophir API Path")
-set(MITK_USE_OPOTEK_HARDWARE ON CACHE BOOL "Use hardware build-in in OPOTEK Phocus Mobile" FORCE)
-set(MITK_GALIL_API_PATH "C:/OphirCppWrapper" CACHE PATH "Galil API Path")
+set(MITK_USE_GALIL_HARDWARE ON CACHE BOOL "Use hardware build-in in OPOTEK Phocus Mobile" FORCE)
+set(MITK_GALIL_API_PATH "C:/Program Files (x86)/Galil/gclib" CACHE PATH "Galil API Path")
# Enable default plugins and the navigation modules
set(MITK_CONFIG_PLUGINS
org.mitk.gui.qt.datamanager
org.mitk.gui.qt.stdmultiwidgeteditor
org.mitk.gui.qt.imagenavigator
org.mitk.gui.qt.properties
org.mitk.gui.qt.viewnavigator
org.mitk.gui.qt.ultrasound
org.mitk.gui.qt.lasercontrol
)
diff --git a/CMake/FindOpenCL.cmake b/CMake/FindOpenCL.cmake
index 848594e9e3..551d768b13 100644
--- a/CMake/FindOpenCL.cmake
+++ b/CMake/FindOpenCL.cmake
@@ -1,88 +1,88 @@
# - Try to find OpenCL
# This module tries to find an OpenCL implementation on your system. It supports
# AMD / ATI, Apple and NVIDIA implementations, but should work, too.
#
# To set manually the paths, define these environment variables:
# OpenCL_INCPATH - Include path (e.g. OpenCL_INCPATH=/opt/cuda/4.0/cuda/include)
# OpenCL_LIBPATH - Library path (e.h. OpenCL_LIBPATH=/usr/lib64/nvidia)
#
# Once done this will define
# OPENCL_FOUND - system has OpenCL
# OPENCL_INCLUDE_DIRS - the OpenCL include directory
# OPENCL_LIBRARIES - link these to use OpenCL
#
# WIN32 should work, but is untested
FIND_PACKAGE(PackageHandleStandardArgs)
SET (OPENCL_VERSION_STRING "0.1.0")
SET(OPENCL_VERSION_MAJOR 0)
SET(OPENCL_VERSION_MINOR 1)
SET(OPENCL_VERSION_PATCH 0)
IF(APPLE)
FIND_LIBRARY(OPENCL_LIBRARIES OpenCL DOC "OpenCL lib for OSX")
FIND_PATH(OPENCL_INCLUDE_DIRS OpenCL/cl.h DOC "Include for OpenCL on OSX")
FIND_PATH(_OPENCL_CPP_INCLUDE_DIRS OpenCL/cl.hpp DOC "Include for OpenCL CPP bindings on OSX")
ELSE()
IF (WIN32)
FIND_PATH(OPENCL_INCLUDE_DIRS CL/cl.h)
FIND_PATH(_OPENCL_CPP_INCLUDE_DIRS CL/cl.hpp)
IF(CMAKE_SIZEOF_VOID_P MATCHES "8")
SET(OPENCL_LIB_DIR "$ENV{ATISTREAMSDKROOT}/lib/x86_64")
if(NOT IS_DIRECTORY ${OPENCL_LIB_DIR})
SET(OPENCL_LIB_DIR "$ENV{CUDA_PATH}/lib/x64")
endif()
ELSE()
SET(OPENCL_LIB_DIR "$ENV{ATISTREAMSDKROOT}/lib/x86")
if(NOT IS_DIRECTORY ${OPENCL_LIB_DIR}) # need to convert path in the cmake style ?
SET(OPENCL_LIB_DIR "$ENV{CUDA_PATH}/lib/Win32")
endif()
ENDIF()
file(TO_CMAKE_PATH ${OPENCL_LIB_DIR} OPENCL_LIB_DIR)
GET_FILENAME_COMPONENT(OPENCL_LIB_DIR ${OPENCL_LIB_DIR} ABSOLUTE)
FIND_LIBRARY(OPENCL_LIBRARIES OpenCL.lib PATHS ${OPENCL_LIB_DIR} ENV OpenCL_LIBPATH)
GET_FILENAME_COMPONENT(_OPENCL_INC_CAND ${OPENCL_LIB_DIR}/../../include ABSOLUTE)
# On Win32 search relative to the library
FIND_PATH(OPENCL_INCLUDE_DIRS CL/cl.h PATHS "${_OPENCL_INC_CAND}" ENV OpenCL_INCPATH)
FIND_PATH(_OPENCL_CPP_INCLUDE_DIRS CL/cl.hpp PATHS "${_OPENCL_INC_CAND}" ENV OpenCL_INCPATH)
ELSE ()
# Unix style platforms
FIND_LIBRARY(OPENCL_LIBRARIES libOpenCL.so
PATHS "/usr/local/cuda/lib64" "/opt/AMDAPP/lib64" ENV LD_LIBRARY_PATH ENV OpenCL_LIBPATH
)
GET_FILENAME_COMPONENT(OPENCL_LIB_DIR ${OPENCL_LIBRARIES} PATH)
GET_FILENAME_COMPONENT(_OPENCL_INC_CAND ${OPENCL_LIB_DIR}/../../include ABSOLUTE)
# The AMD SDK currently does not place its headers
# in /usr/include, therefore also search relative
# to the library
FIND_PATH(OPENCL_INCLUDE_DIRS CL/cl.h PATHS ${_OPENCL_INC_CAND} "/usr/local/cuda/include" "/opt/AMDAPP/include" ENV OpenCL_INCPATH)
FIND_PATH(_OPENCL_CPP_INCLUDE_DIRS CL/cl.hpp PATHS ${_OPENCL_INC_CAND} "/usr/local/cuda/include" "/opt/AMDAPP/include" ENV OpenCL_INCPATH)
ENDIF ()
ENDIF ()
FIND_PACKAGE_HANDLE_STANDARD_ARGS(OpenCL DEFAULT_MSG OPENCL_LIBRARIES OPENCL_INCLUDE_DIRS)
IF(_OPENCL_CPP_INCLUDE_DIRS)
SET( OPENCL_HAS_CPP_BINDINGS TRUE )
LIST( APPEND OPENCL_INCLUDE_DIRS ${_OPENCL_CPP_INCLUDE_DIRS} )
# This is often the same, so clean up
LIST( REMOVE_DUPLICATES OPENCL_INCLUDE_DIRS )
-ENDIF(_OPENCL_CPP_INCLUDE_DIRS)
+ENDIF()
MARK_AS_ADVANCED(
OPENCL_INCLUDE_DIRS
)
diff --git a/Modules/PhotoacousticsHardware/CMakeLists.txt b/Modules/PhotoacousticsHardware/CMakeLists.txt
index fa90f023da..06bde63943 100644
--- a/Modules/PhotoacousticsHardware/CMakeLists.txt
+++ b/Modules/PhotoacousticsHardware/CMakeLists.txt
@@ -1,21 +1,21 @@
if(WIN32)
option(MITK_USE_GALIL_HARDWARE "Enable support for OPOTEK Lasers" OFF)
- option(MITK_USE_OPHIR_PRYO_HARDWARE "Enable support for Ophir Pyroelectrical Sensors" OFF)
+ option(MITK_USE_OPHIR_PYRO_HARDWARE "Enable support for Ophir Pyroelectrical Sensors" OFF)
- if(MITK_USE_OPHIR_PRYO_HARDWARE)
+ if(MITK_USE_OPHIR_PYRO_HARDWARE)
set(MITK_OPHIR_API_PATH "" CACHE PATH "Path to Ophir API lib.")
endif()
if(MITK_USE_GALIL_HARDWARE)
set(MITK_GALIL_API_PATH "" CACHE PATH "Path to Galil API header files.")
MITK_CREATE_MODULE(
SUBPROJECTS
DEPENDS MitkIGT
INCLUDE_DIRS PUBLIC "${MITK_GALIL_API_PATH}/include" "${MITK_OPHIR_API_PATH}"
INTERNAL_INCLUDE_DIRS ${INCLUDE_DIRS_INTERNAL}
ADDITIONAL_LIBS "${MITK_GALIL_API_PATH}/lib/dynamic/x64/gclib.lib" "${MITK_GALIL_API_PATH}/lib/dynamic/x64/gclibo.lib" tinyxml "${MITK_OPHIR_API_PATH}/OphirPyroWrapper.lib"
PACKAGE_DEPENDS tinyxml
)
endif()
endif()
diff --git a/Modules/PhotoacousticsHardware/Resources/OpotekPhocusMobile.xml b/Modules/PhotoacousticsHardware/Resources/OpotekPhocusMobile.xml
index 37242e3275..04f9701ac9 100644
--- a/Modules/PhotoacousticsHardware/Resources/OpotekPhocusMobile.xml
+++ b/Modules/PhotoacousticsHardware/Resources/OpotekPhocusMobile.xml
@@ -1,42 +1,42 @@
- -3.26731848e+07
- 2.35443306e+05
- -7.04376397e+02
- 1.12232174e+00
- -1.00519593e-03
- 4.79945765e-07
- -9.54424480e-11
+ -4.30076111e+07
+ 3.12495804e+05
+ -9.43122022e+02
+ 1.51584088e+00
+ -1.36913735e-03
+ 6.59021774e-07
+ -1.32069448e-1032561690.000750.000950.00051152008010690.0|695.2|700.4|705.6|710.8|716.0|721.2|726.4|731.6|736.8|742.0|747.2|752.4|757.6|762.8|768.0|773.2|778.4|783.6|788.8|794.0|799.2|804.4|809.6|814.8|820.0|825.2|830.4|835.6|840.8|846.0|851.2|856.4|861.6|866.8|872.0|877.2|882.4|887.6|892.8|898.0|903.2|908.4|913.6|918.8|924.0|929.2|934.4|939.6|944.8
0.000727|0.000726|0.000764|0.000795|0.000824|0.000817|0.000832|0.000893|0.000898|0.000881|0.000870|0.000834|0.000849|0.000793|0.000778|0.000753|0.000755|0.000812|0.000843|0.000818|0.000843|0.000824|0.000829|0.000837|0.000832|0.000796|0.000808|0.000796|0.000774|0.000778|0.000760|0.000741|0.000724|0.000725|0.000703|0.000703|0.000695|0.000697|0.000671|0.000702|0.000679|0.000671|0.000676|0.000647|0.000660|0.000674|0.000686|0.000664|0.000658|0.000643
0.042647|0.043251|0.045291|0.047462|0.048515|0.049305|0.049513|0.050434|0.049656|0.050895|0.048269|0.049129|0.050182|0.049334|0.046761|0.045675|0.045061|0.049129|0.050357|0.049206|0.050050|0.048745|0.048822|0.049041|0.048976|0.047813|0.047082|0.046980|0.046980|0.046442|0.045445|0.044063|0.043909|0.042451|0.041058|0.041760|0.042374|0.041683|0.040269|0.042374|0.041299|0.038996|0.041069|0.040736|0.039994|0.040839|0.040225|0.039994|0.038613|0.037692
41152008N1
\ No newline at end of file
diff --git a/Modules/US/Testing/mitkUSImageVideoSourceTest.cpp b/Modules/US/Testing/mitkUSImageVideoSourceTest.cpp
index 70f426402a..9b060a5ad8 100644
--- a/Modules/US/Testing/mitkUSImageVideoSourceTest.cpp
+++ b/Modules/US/Testing/mitkUSImageVideoSourceTest.cpp
@@ -1,83 +1,83 @@
/*===================================================================
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 "mitkUSImageVideoSource.h"
#include "mitkTestingMacros.h"
class mitkUSImageVideoSourceTestClass
{
public:
static void TestInstantiation()
{
// let's create an object of our class
mitk::USImageVideoSource::Pointer usSource = mitk::USImageVideoSource::New();
MITK_TEST_CONDITION_REQUIRED(usSource.IsNotNull(), "USImageVideoSource should not be null after instantiation");
}
static void TestOpenVideoFile(std::string videoFilePath)
{
mitk::USImageVideoSource::Pointer usSource = mitk::USImageVideoSource::New();
usSource->SetVideoFileInput(videoFilePath);
MITK_TEST_CONDITION_REQUIRED(usSource->GetIsVideoReady(), "USImageVideoSource should have isVideoReady flag set after opening a Video File");
mitk::Image::Pointer frame;
- frame = usSource->GetNextImage();
+ frame = usSource->GetNextImage()[0];
MITK_TEST_CONDITION_REQUIRED(frame.IsNotNull(), "First frame should not be null.");
- frame = usSource->GetNextImage();
+ frame = usSource->GetNextImage()[0];
MITK_TEST_CONDITION_REQUIRED(frame.IsNotNull(), "Second frame should not be null.");
- frame = usSource->GetNextImage();
+ frame = usSource->GetNextImage()[0];
MITK_TEST_CONDITION_REQUIRED(frame.IsNotNull(), "Third frame should not be null.");
- frame = usSource->GetNextImage();
+ frame = usSource->GetNextImage()[0];
MITK_TEST_CONDITION_REQUIRED(frame.IsNotNull(), "Fourth frame should not be null.");
- frame = usSource->GetNextImage();
+ frame = usSource->GetNextImage()[0];
MITK_TEST_CONDITION_REQUIRED(frame.IsNotNull(), "Fifth frame should not be null.");
}
/** This Test will fail if no device is attached. Since it basically covers the same non-OpenCV Functionality as TestOpenVideoFile, it is ommited
static void TestOpenDevice()
{
mitk::USImageVideoSource::Pointer usSource = mitk::USImageVideoSource::New();
usSource->SetCameraInput(-1);
MITK_TEST_CONDITION_REQUIRED(usSource->GetIsVideoReady(), "USImageVideoSource should have isVideoReady flag set after opening a Camera device");
}
*/
};
#ifdef WIN32 // Video file compression is currently only supported under windows.
/**
* This function is testing methods of the class USImageVideoSource.
*/
int mitkUSImageVideoSourceTest(int, char* argv[])
{
MITK_TEST_BEGIN("mitkUSImageVideoSourceTest");
mitkUSImageVideoSourceTestClass::TestInstantiation();
mitkUSImageVideoSourceTestClass::TestOpenVideoFile(argv[1]);
// This test is commented out since no videodevcie ist steadily connected to the dart clients.
// Functionality should sufficiently be tested through TestOpenVideoFile anyway
//mitkUSImageVideoSourceTestClass::TestOpenDevice();
MITK_TEST_END();
}
#else
int mitkUSImageVideoSourceTest(int, char* [] )
{
MITK_TEST_BEGIN("mitkUSImageVideoSourceTest");
MITK_TEST_END();
}
#endif
diff --git a/Modules/US/USFilters/mitkIGTLMessageToUSImageFilter.cpp b/Modules/US/USFilters/mitkIGTLMessageToUSImageFilter.cpp
index f09adb68d0..25c6c847ad 100644
--- a/Modules/US/USFilters/mitkIGTLMessageToUSImageFilter.cpp
+++ b/Modules/US/USFilters/mitkIGTLMessageToUSImageFilter.cpp
@@ -1,188 +1,192 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#include
#include
#include
#include
void mitk::IGTLMessageToUSImageFilter::GetNextRawImage(
- mitk::Image::Pointer& img)
+ std::vector& imgVector)
{
+ if (imgVector.size() != 1)
+ imgVector.resize(1);
+
+ mitk::Image::Pointer& img = imgVector[0];
m_upstream->Update();
mitk::IGTLMessage* msg = m_upstream->GetOutput();
if (msg != nullptr && (!msg->IsDataValid() || std::strcmp(msg->GetIGTLMessageType(), "IMAGE") != 0))
{
img = m_previousImage;
return;
}
igtl::MessageBase::Pointer msgBase = msg->GetMessage();
igtl::ImageMessage* imgMsg = (igtl::ImageMessage*)(msgBase.GetPointer());
bool big_endian = (imgMsg->GetEndian() == igtl::ImageMessage::ENDIAN_BIG);
if (imgMsg->GetCoordinateSystem() != igtl::ImageMessage::COORDINATE_RAS)
{
// TODO: Which coordinate system does MITK use?
mitkThrow() << "Can not handle messages with LPS coordinate system";
}
switch (imgMsg->GetScalarType())
{
case igtl::ImageMessage::TYPE_UINT8:
Initiate(img, imgMsg, big_endian);
break;
case igtl::ImageMessage::TYPE_INT8:
Initiate(img, imgMsg, big_endian);
break;
case igtl::ImageMessage::TYPE_UINT16:
Initiate(img, imgMsg, big_endian);
break;
case igtl::ImageMessage::TYPE_INT16:
Initiate(img, imgMsg, big_endian);
break;
case igtl::ImageMessage::TYPE_UINT32:
Initiate(img, imgMsg, big_endian);
break;
case igtl::ImageMessage::TYPE_INT32:
Initiate(img, imgMsg, big_endian);
break;
case igtl::ImageMessage::TYPE_FLOAT32:
Initiate(img, imgMsg, big_endian);
break;
case igtl::ImageMessage::TYPE_FLOAT64:
Initiate(img, imgMsg, big_endian);
break;
default:
mitkThrow() << "Incompatible PixelType " << imgMsg;
}
}
template
void mitk::IGTLMessageToUSImageFilter::Initiate(mitk::Image::Pointer& img,
igtl::ImageMessage* msg,
bool big_endian)
{
typedef itk::Image ImageType;
typename ImageType::Pointer output = ImageType::New();
typename ImageType::RegionType region;
typename ImageType::RegionType::SizeType size;
typename ImageType::RegionType::IndexType index;
typename ImageType::SpacingType spacing;
typename ImageType::PointType origin;
// Copy dimensions
int dims[3];
msg->GetDimensions(dims);
size_t num_pixel = 1;
for (size_t i = 0; i < 3; i++)
{
size[i] = dims[i];
num_pixel *= dims[i];
}
// Handle subvolume information. We want the subvolume to be the whole image
// for now.
int sdims[3], offs[3];
msg->GetSubVolume(sdims, offs);
for (size_t i = 0; i < 3; i++)
{
if (offs[i] != 0 || sdims[i] != dims[i])
{
// TODO: Handle messages with smaller subvolume than whole image
throw("Can not handle message with smaller subvolume than whole image");
}
}
index.Fill(0);
float matF[4][4];
msg->GetMatrix(matF);
vtkSmartPointer vtkMatrix = vtkSmartPointer::New();
for (size_t i = 0; i < 4; ++i)
for (size_t j = 0; j < 4; ++j)
vtkMatrix->SetElement(i, j, matF[i][j]);
float spacingMsg[3];
msg->GetSpacing(spacingMsg);
for (int i = 0; i < 3; ++i)
spacing[i] = spacingMsg[i];
region.SetSize(size);
region.SetIndex(index);
output->SetRegions(region);
output->SetSpacing(spacing);
output->Allocate();
TPixel* in = (TPixel*)msg->GetScalarPointer();
TPixel* out = (TPixel*)output->GetBufferPointer();
memcpy(out, in, num_pixel * sizeof(TPixel));
if (big_endian)
{
// Even though this method is called "FromSystemToBigEndian", it also swaps
// "FromBigEndianToSystem".
// This makes sense, but might be confusing at first glance.
itk::ByteSwapper::SwapRangeFromSystemToBigEndian(out, num_pixel);
}
else
{
itk::ByteSwapper::SwapRangeFromSystemToLittleEndian(out, num_pixel);
}
img = mitk::Image::New();
img->InitializeByItk(output.GetPointer());
img->SetVolume(output->GetBufferPointer());
//img->GetGeometry()->SetIndexToWorldTransformByVtkMatrix(vtkMatrix);
m_previousImage = img;
float iorigin[3];
msg->GetOrigin(iorigin);
for (size_t i = 0; i < 3; i++)
{
origin[i] = iorigin[i];
}
output->SetOrigin(origin);
}
mitk::IGTLMessageToUSImageFilter::IGTLMessageToUSImageFilter()
: m_upstream(nullptr)
{
MITK_DEBUG << "Instantiated this (" << this << ") mitkIGTMessageToUSImageFilter\n";
}
void mitk::IGTLMessageToUSImageFilter::SetNumberOfExpectedOutputs(
unsigned int numOutputs)
{
if (numOutputs > 1)
{
throw("Can only have 1 output for IGTLMessageToUSImageFilter.");
}
}
void mitk::IGTLMessageToUSImageFilter::ConnectTo(
mitk::IGTLMessageSource* UpstreamFilter)
{
MITK_DEBUG << "Connected this (" << this << ") mitkIGTLMessageToUSImageFilter to MessageSource (" << UpstreamFilter << ")\n";
m_upstream = UpstreamFilter;
}
\ No newline at end of file
diff --git a/Modules/US/USFilters/mitkIGTLMessageToUSImageFilter.h b/Modules/US/USFilters/mitkIGTLMessageToUSImageFilter.h
index 378200a7e8..39d5950341 100644
--- a/Modules/US/USFilters/mitkIGTLMessageToUSImageFilter.h
+++ b/Modules/US/USFilters/mitkIGTLMessageToUSImageFilter.h
@@ -1,82 +1,82 @@
/*===================================================================
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 MITKIGTLMessageToUSImageFilter_H_HEADER_INCLUDED_
#define MITKIGTLMessageToUSImageFilter_H_HEADER_INCLUDED_
#include
#include
#include
#include
#include
namespace mitk
{
class MITKUS_EXPORT IGTLMessageToUSImageFilter : public USImageSource
{
public:
mitkClassMacro(IGTLMessageToUSImageFilter, USImageSource);
itkFactorylessNewMacro(Self);
itkCloneMacro(Self);
/**
*\brief Sets the number of expected outputs.
*
* Normally, this is done automatically by the filter concept. However, in our
* case we can not know, for example, how many tracking elements are stored
* in the incoming igtl message. Therefore, we have to set the number here to
* the expected value.
*/
void SetNumberOfExpectedOutputs(unsigned int numOutputs);
/**
*\brief Connects the input of this filter to the outputs of the given
* IGTLMessageSource
*
* This method does not support smartpointer. use FilterX.GetPointer() to
* retrieve a dumbpointer.
*/
void ConnectTo(mitk::IGTLMessageSource* UpstreamFilter);
protected:
IGTLMessageToUSImageFilter();
using Superclass::GetNextRawImage;
/**
* \brief Copies the data from the next OIGTL message to an mitk::Image.
*
* \param img the image to fill with the data from the OIGTL message.
*/
- virtual void GetNextRawImage(mitk::Image::Pointer& img);
+ virtual void GetNextRawImage(std::vector& imgVector);
private:
mitk::IGTLMessageSource* m_upstream;
mitk::Image::Pointer m_previousImage;
/**
* \brief Templated method to copy the data of the OIGTL message to the image, depending
* on the pixel type contained in the message.
*
* \param img the image to fill with the data from msg
* \param msg the OIGTL message to copy the data from
* \param big_endian whether the data is in big endian byte order
*/
template
void Initiate(mitk::Image::Pointer& img, igtl::ImageMessage* msg, bool big_endian);
};
} // namespace mitk
#endif // MITKIGTLMessageToUSImageFilter_H_HEADER_INCLUDED_
diff --git a/Modules/US/USFilters/mitkUSImageSource.cpp b/Modules/US/USFilters/mitkUSImageSource.cpp
index e46f349fdd..11a5c6b51b 100644
--- a/Modules/US/USFilters/mitkUSImageSource.cpp
+++ b/Modules/US/USFilters/mitkUSImageSource.cpp
@@ -1,117 +1,126 @@
/*===================================================================
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 "mitkUSImageSource.h"
#include "mitkProperties.h"
const char* mitk::USImageSource::IMAGE_PROPERTY_IDENTIFIER = "id_nummer";
mitk::USImageSource::USImageSource()
: m_OpenCVToMitkFilter(mitk::OpenCVToMitkImageFilter::New()),
m_MitkToOpenCVFilter(nullptr),
m_ImageFilter(mitk::BasicCombinationOpenCVImageFilter::New()),
m_CurrentImageId(0),
m_ImageFilterMutex(itk::FastMutexLock::New())
{
}
mitk::USImageSource::~USImageSource()
{
}
void mitk::USImageSource::PushFilter(AbstractOpenCVImageFilter::Pointer filter)
{
m_ImageFilter->PushFilter(filter);
}
bool mitk::USImageSource::RemoveFilter(AbstractOpenCVImageFilter::Pointer filter)
{
return m_ImageFilter->RemoveFilter(filter);
}
bool mitk::USImageSource::GetIsFilterInThePipeline(AbstractOpenCVImageFilter::Pointer filter)
{
return m_ImageFilter->GetIsFilterOnTheList(filter);
}
-mitk::Image::Pointer mitk::USImageSource::GetNextImage()
+std::vector mitk::USImageSource::GetNextImage()
{
- mitk::Image::Pointer result;
+ std::vector result;
- // Get next image and apply OpenCV based filters beforehand
+ // Apply OpenCV based filters beforehand
if (m_ImageFilter.IsNotNull() && !m_ImageFilter->GetIsEmpty())
{
- cv::Mat image;
- this->GetNextRawImage(image);
+ std::vector imageVector;
+ GetNextRawImage(imageVector);
+ if(result.size() != imageVector.size())
+ result.resize(imageVector.size());
- if (!image.empty())
+ for (size_t i = 0; i < imageVector.size(); ++i)
{
- m_ImageFilterMutex->Lock();
- m_ImageFilter->FilterImage(image, m_CurrentImageId);
- m_ImageFilterMutex->Unlock();
-
- // convert to MITK image
- this->m_OpenCVToMitkFilter->SetOpenCVMat(image);
- this->m_OpenCVToMitkFilter->Update();
-
- // OpenCVToMitkImageFilter returns a standard mitk::image.
- result = this->m_OpenCVToMitkFilter->GetOutput();
+ if (!imageVector[i].empty())
+ {
+ m_ImageFilterMutex->Lock();
+ m_ImageFilter->FilterImage(imageVector[i], m_CurrentImageId);
+ m_ImageFilterMutex->Unlock();
+
+ // convert to MITK image
+ this->m_OpenCVToMitkFilter->SetOpenCVMat(imageVector[i]);
+ this->m_OpenCVToMitkFilter->Update();
+
+ // OpenCVToMitkImageFilter returns a standard mitk::image.
+ result[i] = this->m_OpenCVToMitkFilter->GetOutput();
+ }
}
}
- // Get next image without filtering
else
{
- // mitk image can be received direclty if no filtering is necessary
this->GetNextRawImage(result);
}
- if (result.IsNotNull())
- {
- result->SetProperty(IMAGE_PROPERTY_IDENTIFIER, mitk::IntProperty::New(m_CurrentImageId));
- m_CurrentImageId++;
-
- // Everything as expected, return result
- return result;
- }
- else
+ for (size_t i = 0; i < result.size(); ++i)
{
- //MITK_WARN("mitkUSImageSource") << "Result image is not set.";
- return mitk::Image::New();
+ if (result[i].IsNotNull())
+ {
+ result[i]->SetProperty(IMAGE_PROPERTY_IDENTIFIER, mitk::IntProperty::New(m_CurrentImageId));
+ }
+ else
+ {
+ //MITK_WARN("mitkUSImageSource") << "Result image " << i << " is not set.";
+ result[i] = mitk::Image::New();
+ }
}
+ m_CurrentImageId++;
+
+ return result;
}
-void mitk::USImageSource::GetNextRawImage(cv::Mat& image)
+void mitk::USImageSource::GetNextRawImage(std::vector& imageVector)
{
// create filter object if it does not exist yet
if (!m_MitkToOpenCVFilter)
{
m_MitkToOpenCVFilter = mitk::ImageToOpenCVImageFilter::New();
}
// get mitk image through virtual method of the subclass
- mitk::Image::Pointer mitkImg;
+ std::vector mitkImg;
this->GetNextRawImage(mitkImg);
- if (mitkImg.IsNull() || !mitkImg->IsInitialized())
+ for (unsigned int i = 0; i < mitkImg.size(); ++i)
{
- image = cv::Mat();
- return;
+ if (mitkImg[i].IsNull() || !mitkImg[i]->IsInitialized())
+ {
+ imageVector[i] = cv::Mat();
+ }
+ else
+ {
+ // convert mitk::Image to an OpenCV image
+ m_MitkToOpenCVFilter->SetImage(mitkImg[i]);
+ imageVector[i] = m_MitkToOpenCVFilter->GetOpenCVMat();
+ }
}
-
- // convert mitk::Image to an OpenCV image
- m_MitkToOpenCVFilter->SetImage(mitkImg);
- image = m_MitkToOpenCVFilter->GetOpenCVMat();
}
diff --git a/Modules/US/USFilters/mitkUSImageSource.h b/Modules/US/USFilters/mitkUSImageSource.h
index a5dd5bf4cf..499224bf16 100644
--- a/Modules/US/USFilters/mitkUSImageSource.h
+++ b/Modules/US/USFilters/mitkUSImageSource.h
@@ -1,105 +1,105 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#ifndef MITKUSImageSource_H_HEADER_INCLUDED_
#define MITKUSImageSource_H_HEADER_INCLUDED_
// ITK
#include
#include
// MITK
#include
#include
#include "mitkBasicCombinationOpenCVImageFilter.h"
#include "mitkOpenCVToMitkImageFilter.h"
#include "mitkImageToOpenCVImageFilter.h"
// OpenCV
#include "cv.h"
namespace mitk {
/**
* \brief This is an abstract superclass for delivering USImages.
* Each subclass must implement the method mitk::USImageSource::GetNextRawImage().
* The public method mitk::USImageSource::GetNextImage() can the be used to
* get the next image from the image source. This image will be filtered by
* the filter set with mitk::USImageSource::SetImageFilter().
*
* \ingroup US
*/
class MITKUS_EXPORT USImageSource : public itk::Object
{
public:
static const char* IMAGE_PROPERTY_IDENTIFIER;
mitkClassMacroItkParent(USImageSource, itk::Object);
itkGetMacro(ImageFilter, mitk::BasicCombinationOpenCVImageFilter::Pointer);
void PushFilter(AbstractOpenCVImageFilter::Pointer filter);
bool RemoveFilter(AbstractOpenCVImageFilter::Pointer filter);
bool GetIsFilterInThePipeline(AbstractOpenCVImageFilter::Pointer filter);
/**
* \brief Retrieves the next frame. This will typically be the next frame
* in a file or the last cached file in a device. The image is filtered if
* a filter was set by mitk::USImageSource::SetImageFilter().
*
* \return pointer to the next USImage (filtered if set)
*/
- mitk::Image::Pointer GetNextImage();
+ std::vector GetNextImage();
protected:
USImageSource();
virtual ~USImageSource();
/**
* \brief Set the given OpenCV image matrix to the next image received
* from the device or file.
*
* The standard implementation calls the overloaded function with an
* mitk::Image and converts this image to OpenCV then. One should reimplement
* this method for a better performance if an image filter is set.
*/
- virtual void GetNextRawImage(cv::Mat&);
+ virtual void GetNextRawImage(std::vector&);
/**
* \brief Set mitk::Image to the next image received from the device or file.
* This method must be implemented in every subclass.
*/
- virtual void GetNextRawImage(mitk::Image::Pointer&) = 0;
+ virtual void GetNextRawImage(std::vector&) = 0;
/**
* \brief Used to convert from OpenCV Images to MITK Images.
*/
mitk::OpenCVToMitkImageFilter::Pointer m_OpenCVToMitkFilter;
/**
* \brief Used to convert from MITK Images to OpenCV Images.
*/
mitk::ImageToOpenCVImageFilter::Pointer m_MitkToOpenCVFilter;
private:
/**
* \brief Filter is executed during mitk::USImageVideoSource::GetNextImage().
*/
BasicCombinationOpenCVImageFilter::Pointer m_ImageFilter;
int m_CurrentImageId;
itk::FastMutexLock::Pointer m_ImageFilterMutex;
};
} // namespace mitk
#endif /* MITKUSImageSource_H_HEADER_INCLUDED_ */
diff --git a/Modules/US/USFilters/mitkUSImageVideoSource.cpp b/Modules/US/USFilters/mitkUSImageVideoSource.cpp
index d94f2045b6..d27a1b83d7 100644
--- a/Modules/US/USFilters/mitkUSImageVideoSource.cpp
+++ b/Modules/US/USFilters/mitkUSImageVideoSource.cpp
@@ -1,227 +1,233 @@
/*===================================================================
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 HEADER
#include "mitkUSImageVideoSource.h"
#include "mitkImage.h"
//OpenCV HEADER
#include
#include
//Other
#include
mitk::USImageVideoSource::USImageVideoSource()
: m_VideoCapture(new cv::VideoCapture()),
m_IsVideoReady(false),
m_IsGreyscale(false),
m_IsCropped(false),
m_ResolutionOverrideWidth(0),
m_ResolutionOverrideHeight(0),
m_ResolutionOverride(false),
m_GrayscaleFilter(mitk::ConvertGrayscaleOpenCVImageFilter::New()),
m_CropFilter(mitk::CropOpenCVImageFilter::New())
{
}
mitk::USImageVideoSource::~USImageVideoSource()
{
m_VideoCapture->release();
delete m_VideoCapture;
}
void mitk::USImageVideoSource::SetVideoFileInput(std::string path)
{
m_VideoCapture->open(path.c_str());
// check if we succeeded
if(!m_VideoCapture->isOpened()) { m_IsVideoReady = false; }
else { m_IsVideoReady = true; }
// if Override is enabled, use it
if (m_ResolutionOverride)
{
m_VideoCapture->set(CV_CAP_PROP_FRAME_WIDTH, this->m_ResolutionOverrideWidth);
m_VideoCapture->set(CV_CAP_PROP_FRAME_HEIGHT, this->m_ResolutionOverrideHeight);
}
}
void mitk::USImageVideoSource::SetCameraInput(int deviceID)
{
m_VideoCapture->open(deviceID);
if(!m_VideoCapture->isOpened()) // check if we succeeded
m_IsVideoReady = false;
else
m_IsVideoReady = true;
// if Override is enabled, use it
if (m_ResolutionOverride)
{
m_VideoCapture->set(CV_CAP_PROP_FRAME_WIDTH, this->m_ResolutionOverrideWidth);
m_VideoCapture->set(CV_CAP_PROP_FRAME_HEIGHT, this->m_ResolutionOverrideHeight);
}
}
void mitk::USImageVideoSource::ReleaseInput()
{
m_VideoCapture->release();
delete m_VideoCapture;
m_VideoCapture = new cv::VideoCapture();
}
void mitk::USImageVideoSource::SetColorOutput(bool isColor){
if ( ! isColor && ! m_IsGreyscale )
{
this->PushFilter(m_GrayscaleFilter.GetPointer());
}
else if ( isColor && m_IsGreyscale )
{
this->RemoveFilter(m_GrayscaleFilter.GetPointer());
}
m_IsGreyscale = !isColor;
}
int mitk::USImageVideoSource::GetImageHeight()
{
if (m_VideoCapture) { return m_VideoCapture->get(CV_CAP_PROP_FRAME_HEIGHT); }
else { return 0; }
}
int mitk::USImageVideoSource::GetImageWidth()
{
if (m_VideoCapture) { return m_VideoCapture->get(CV_CAP_PROP_FRAME_WIDTH); }
else { return 0; }
}
bool mitk::USImageVideoSource::GetIsReady()
{
if (!m_VideoCapture) { return false; }
return m_VideoCapture->isOpened();
}
void mitk::USImageVideoSource::SetRegionOfInterest(int topLeftX, int topLeftY, int bottomRightX, int bottomRightY)
{
m_CropFilter->SetCropRegion(topLeftX, topLeftY, bottomRightX, bottomRightY);
if (! m_IsCropped && ! m_CropFilter->GetIsCropRegionEmpty())
{
this->PushFilter(m_CropFilter.GetPointer());
m_IsCropped = true;
}
}
void mitk::USImageVideoSource::SetRegionOfInterest(USImageRoi roi)
{
this->SetRegionOfInterest(roi.topLeftX, roi.topLeftY, roi.bottomRightX, roi.bottomRightY);
}
void mitk::USImageVideoSource::SetCropping(USImageCropping cropping)
{
int width = this->GetImageWidth();
int height = this->GetImageHeight();
this->SetRegionOfInterest(cropping.left, cropping.top, width - cropping.right, height - cropping.bottom);
}
mitk::USImageVideoSource::USImageCropping mitk::USImageVideoSource::GetCropping()
{
cv::Rect cropRect = m_CropFilter->GetCropRegion();
USImageCropping cropping;
cropping.left = cropRect.x;
cropping.top = cropRect.y;
if ( cropRect.height == 0 )
{
cropping.bottom = 0;
}
else
{
cropping.bottom = this->GetImageHeight() - (cropRect.y + cropRect.height);
}
if ( cropRect.width == 0 )
{
cropping.right = 0;
}
else
{
cropping.right = this->GetImageWidth() - (cropRect.x + cropRect.width);
}
return cropping;
}
mitk::USImageVideoSource::USImageRoi mitk::USImageVideoSource::GetRegionOfInterest()
{
cv::Rect cropRect = m_CropFilter->GetCropRegion();
return USImageRoi(cropRect.x, cropRect.y, cropRect.x + cropRect.width, cropRect.y + cropRect.height);
}
void mitk::USImageVideoSource::RemoveRegionOfInterest()
{
this->RemoveFilter(m_CropFilter.GetPointer());
m_IsCropped = false;
}
-void mitk::USImageVideoSource::GetNextRawImage( cv::Mat& image )
+void mitk::USImageVideoSource::GetNextRawImage(std::vector& image )
{
// loop video if necessary
//Commented out because setting and getting of these properties is not supported. Therefore on Linux
//you'll always get some Highgui errors from OpenCV
/*if (m_VideoCapture->get(CV_CAP_PROP_POS_FRAMES) == m_VideoCapture->get(CV_CAP_PROP_FRAME_COUNT))
{
m_VideoCapture->set(CV_CAP_PROP_POS_FRAMES, 0);
}*/
+ if (image.size() != 1)
+ image.resize(1);
+
// retrieve image
- *m_VideoCapture >> image; // get a new frame from camera
+ *m_VideoCapture >> image[0]; // get a new frame from camera
}
-void mitk::USImageVideoSource::GetNextRawImage( mitk::Image::Pointer& image )
+void mitk::USImageVideoSource::GetNextRawImage(std::vector& image )
{
- cv::Mat cv_img;
+ if (image.size() != 1)
+ image.resize(1);
+
+ std::vector cv_img;
this->GetNextRawImage(cv_img);
// convert to MITK-Image
- IplImage ipl_img = cv_img;
+ IplImage ipl_img = cv_img[0];
this->m_OpenCVToMitkFilter->SetOpenCVImage(&ipl_img);
this->m_OpenCVToMitkFilter->Update();
// OpenCVToMitkImageFilter returns a standard mitk::image. We then transform it into an USImage
- image = this->m_OpenCVToMitkFilter->GetOutput();
+ image[0] = this->m_OpenCVToMitkFilter->GetOutput();
// clean up
- cv_img.release();
+ cv_img[0].release();
}
void mitk::USImageVideoSource::OverrideResolution(int width, int height)
{
this->m_ResolutionOverrideHeight = height;
this->m_ResolutionOverrideWidth = width;
if (m_VideoCapture != nullptr)
{
m_VideoCapture->set(CV_CAP_PROP_FRAME_WIDTH, width);
m_VideoCapture->set(CV_CAP_PROP_FRAME_HEIGHT, height);
}
}
diff --git a/Modules/US/USFilters/mitkUSImageVideoSource.h b/Modules/US/USFilters/mitkUSImageVideoSource.h
index 525dcf3958..8c18751210 100644
--- a/Modules/US/USFilters/mitkUSImageVideoSource.h
+++ b/Modules/US/USFilters/mitkUSImageVideoSource.h
@@ -1,221 +1,221 @@
/*===================================================================
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 MITKUSImageVideoSource_H_HEADER_INCLUDED_
#define MITKUSImageVideoSource_H_HEADER_INCLUDED_
// ITK
#include
// MITK
#include "mitkUSImageSource.h"
#include "mitkConvertGrayscaleOpenCVImageFilter.h"
#include "mitkCropOpenCVImageFilter.h"
#include "mitkBasicCombinationOpenCVImageFilter.h"
// OpenCV
#include
namespace mitk {
/**
* \brief This class can be pointed to a video file or a videodevice and delivers USImages.
*
* Images are in color by default, but can be set to greyscale via SetColorOutput(false),
* which significantly improves performance.
*
* Images can also be cropped to a region of interest, further increasing performance.
*
* \ingroup US
*/
class MITKUS_EXPORT USImageVideoSource : public mitk::USImageSource
{
public:
mitkClassMacroItkParent(USImageVideoSource, itk::ProcessObject);
itkFactorylessNewMacro(Self)
itkCloneMacro(Self)
/**
* \brief Defines a region of interest by top left and bottom right corner.
*/
struct USImageRoi
{
int topLeftX;
int topLeftY;
int bottomRightX;
int bottomRightY;
USImageRoi()
: topLeftX(0), topLeftY(0), bottomRightX(0), bottomRightY(0) { };
USImageRoi(unsigned int topLeftX, unsigned int topLeftY, unsigned int bottomRightX, unsigned int bottomRightY)
: topLeftX(topLeftX), topLeftY(topLeftY), bottomRightX(bottomRightX), bottomRightY(bottomRightY) { };
};
/**
* \brief Defines a region of interest by distances to the four image borders.
*/
struct USImageCropping
{
unsigned int top;
unsigned int bottom;
unsigned int left;
unsigned int right;
USImageCropping()
: top(0), bottom(0), left(0), right(0) { };
USImageCropping(unsigned int top, unsigned int bottom, unsigned int left, unsigned int right)
: top(top), bottom(bottom), left(left), right(right) { };
};
/**
* \brief Opens a video file for streaming. If nothing goes wrong, the
* VideoSource is ready to deliver images after calling this function.
*/
void SetVideoFileInput(std::string path);
/**
* \brief Opens a video device for streaming. Takes the Device id. Try -1 for "grab the first you can get"
* which works quite well if only one device is available. If nothing goes wrong, the
* VideoSource is ready to deliver images after calling this function.
*/
void SetCameraInput(int deviceID);
void ReleaseInput();
/**
* \brief Sets the output image to rgb or grayscale.
* Output is color by default
* and can be set to color by passing true, or to grayscale again by passing false.
*/
void SetColorOutput(bool isColor);
/**
* \brief Defines the cropping area.
* The rectangle will be justified to the image borders if the given
* rectangle is larger than the video source. If a correct rectangle is
* given, the dimensions of the output image will be equal to those of the
* rectangle.
*/
void SetRegionOfInterest(int topLeftX, int topLeftY, int bottomRightX, int bottomRightY);
/**
* \brief Defines the cropping area.
* The rectangle will be justified to the image borders if the given
* rectangle is larger than the video source. If a correct rectangle is
* given, the dimensions of the output image will be equal to those of the
* rectangle.
*
* \param regionOfInterest struct defining x and y coordinates of top left and bottom right corner
*/
void SetRegionOfInterest(USImageRoi regionOfInterest);
/**
* \brief Defines the cropping area.
* The rectangle will be justified to the image borders if the given
* rectangle is larger than the video source. If a correct rectangle is
* given, the dimensions of the output image will be equal to those of the
* rectangle.
*
* \param cropping struct defining distances to the four image borders
*/
void SetCropping(USImageCropping cropping);
/**
* /brief Removes the region of interest.
* Produced images will be uncropped after call of this method.
*/
void RemoveRegionOfInterest();
/**
* \brief This is a workaround for a problem that happens with some video device drivers.
*
* If you encounter OpenCV Warnings that buffer sizes do not match while calling getNextFrame,
* then do the following: Using the drivers control panel to force a certain resolution, then call
* this method with the same Dimensions after opening the device.
* Before retrieving images one should call mitk::USImageVideoSource::isReady().
*/
void OverrideResolution(int width, int height);
// Getter & Setter
itkGetMacro(IsVideoReady, bool);
itkGetMacro(ResolutionOverride, bool);
itkSetMacro(ResolutionOverride, bool);
itkGetMacro(IsGreyscale,bool);
itkGetMacro(ResolutionOverrideWidth,int);
itkGetMacro(ResolutionOverrideHeight,int);
int GetImageHeight();
int GetImageWidth();
USImageCropping GetCropping();
USImageRoi GetRegionOfInterest();
/**
* \brief Returns true if images can be delivered.
*
* Only if true is returned one can retrieve images via
* mitk::USImageVideoSource::GetNextImage().
* If false is returned, behaviour is undefined.
*/
bool GetIsReady();
protected:
USImageVideoSource();
virtual ~USImageVideoSource();
/**
* \brief Next image is gathered from the image source.
*
* \param[out] image an OpenCV-Matrix containing this image
*/
- virtual void GetNextRawImage( cv::Mat& image ) override;
+ virtual void GetNextRawImage( std::vector& image ) override;
/**
* \brief Next image is gathered from the image source.
*
* \param[out] image an mitk::Image containing this image
*/
- virtual void GetNextRawImage( mitk::Image::Pointer& image ) override;
+ virtual void GetNextRawImage( std::vector& image ) override;
/**
* \brief The source of the video, managed internally
*/
cv::VideoCapture* m_VideoCapture;
/**
* \brief If true, a frame can be grabbed anytime.
*/
bool m_IsVideoReady;
/**
* \brief If true, image output will be greyscale.
*/
bool m_IsGreyscale;
/**
* \brief If true, image will be cropped according to settings of crop filter.
*/
bool m_IsCropped;
/**
* These Variables determined whether Resolution Override is on, what dimensions to use.
*/
int m_ResolutionOverrideWidth;
int m_ResolutionOverrideHeight;
bool m_ResolutionOverride;
ConvertGrayscaleOpenCVImageFilter::Pointer m_GrayscaleFilter;
CropOpenCVImageFilter::Pointer m_CropFilter;
};
} // namespace mitk
#endif /* MITKUSImageVideoSource_H_HEADER_INCLUDED_ */
diff --git a/Modules/US/USHardwareDiPhAS/mitkUSDiPhASDevice.cpp b/Modules/US/USHardwareDiPhAS/mitkUSDiPhASDevice.cpp
index e10cb22f60..5cb68f1dcd 100644
--- a/Modules/US/USHardwareDiPhAS/mitkUSDiPhASDevice.cpp
+++ b/Modules/US/USHardwareDiPhAS/mitkUSDiPhASDevice.cpp
@@ -1,304 +1,307 @@
/*===================================================================
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 "mitkUSDiPhASDevice.h"
#include "mitkUSDiPhASCustomControls.h"
mitk::USDiPhASDevice::USDiPhASDevice(std::string manufacturer, std::string model)
: mitk::USDevice(manufacturer, model), m_ControlsProbes(mitk::USDiPhASProbesControls::New(this)),
m_ImageSource(mitk::USDiPhASImageSource::New(this)),
m_ControlInterfaceCustom(mitk::USDiPhASCustomControls::New(this)),
m_IsRunning(false),
m_BurstHalfwaveClockCount(7),
- m_Interleaved(true)
+ m_Interleaved(true)
{
- SetNumberOfOutputs(1);
+ m_NumberOfOutputs = 2;
+ this->SetNumberOfIndexedOutputs(m_NumberOfOutputs);
+
SetNthOutput(0, this->MakeOutput(0));
+ SetNthOutput(1, this->MakeOutput(1));
}
mitk::USDiPhASDevice::~USDiPhASDevice()
{
}
//Gets
std::string mitk::USDiPhASDevice::GetDeviceClass()
{
return "org.mitk.modules.us.USDiPhASDevice";
}
mitk::USControlInterfaceProbes::Pointer mitk::USDiPhASDevice::GetControlInterfaceProbes()
{
return m_ControlsProbes.GetPointer();
};
mitk::USAbstractControlInterface::Pointer mitk::USDiPhASDevice::GetControlInterfaceCustom()
{
return m_ControlInterfaceCustom.GetPointer();
}
mitk::USImageSource::Pointer mitk::USDiPhASDevice::GetUSImageSource()
{
return m_ImageSource.GetPointer();
}
ScanModeNative& mitk::USDiPhASDevice::GetScanMode()
{
return m_ScanMode;
}
// Setup and Cleanup
bool mitk::USDiPhASDevice::OnInitialization()
{
return true;
}
//----------------------------------------------------------------------------------------------------------------------------
/* ugly wrapper stuff - find better solution so it isn't necessary to create a global pointer to USDiPhASDevice...
* passing a lambda function would be nicer - sadly something goes wrong when passing the adress of a lambda function:
* the API produces access violations. Passing the Lambda function itself would be preferable, but that's not possible
*/
mitk::USDiPhASDevice* w_device;
mitk::USDiPhASImageSource* w_ISource;
void WrapperMessageCallback(const char* message)
{
w_device->MessageCallback(message);
}
void WrapperImageDataCallback(
short* rfDataChannelData, int channelDatalinesPerDataset, int channelDataSamplesPerChannel, int channelDataTotalDatasets,
short* rfDataArrayBeamformed, int beamformedLines, int beamformedSamples, int beamformedTotalDatasets,
unsigned char* imageData, int imageWidth, int imageHeight, int imagePixelFormat, int imageSetsTotal, double timeStamp)
{
w_ISource->ImageDataCallback(
rfDataChannelData, channelDatalinesPerDataset, channelDataSamplesPerChannel, channelDataTotalDatasets,
rfDataArrayBeamformed, beamformedLines, beamformedSamples, beamformedTotalDatasets,
imageData, imageWidth, imageHeight, imagePixelFormat, imageSetsTotal, timeStamp);
}
//----------------------------------------------------------------------------------------------------------------------------
bool mitk::USDiPhASDevice::OnConnection()
{
w_device = this;
w_ISource = m_ImageSource;
// Need those pointers for the forwarders to call member functions; createBeamformer expects non-member function pointers.
createBeamformer((StringMessageCallback)&WrapperMessageCallback, (NewDataCallback)&WrapperImageDataCallback);
InitializeScanMode();
initBeamformer(); //start the hardware connection
m_ImageSource->UpdateImageGeometry(); //make sure the image geometry is initialized!
// pass the new scanmode to the device:
setupScan(this->m_ScanMode);
return true;
}
bool mitk::USDiPhASDevice::OnDisconnection()
{
//close the beamformer so hardware is disconnected
closeBeamformer();
return true;
}
bool mitk::USDiPhASDevice::OnActivation()
{
// probe controls are available now
m_ControlsProbes->SetIsActive(true);
if (m_ControlsProbes->GetProbesCount() < 1)
{
MITK_WARN("USDevice")("USDiPhASDevice") << "No probe found.";
return false;
}
m_ControlsProbes->SelectProbe(0);
// toggle the beamformer of the API
if(!m_IsRunning)
m_IsRunning=toggleFreeze();
return true;
}
bool mitk::USDiPhASDevice::OnDeactivation()
{
if(m_IsRunning)
m_IsRunning=toggleFreeze();
return true;
}
void mitk::USDiPhASDevice::OnFreeze(bool freeze)
{
if(m_IsRunning==freeze)
m_IsRunning=toggleFreeze(); // toggleFreeze() returns true if it starts running the beamformer, otherwise false
}
void mitk::USDiPhASDevice::UpdateScanmode()
{
OnFreeze(true);
SetInterleaved(m_Interleaved); // update the beamforming parameters...
UpdateTransmitEvents();
if (!(dynamic_cast(this->m_ControlInterfaceCustom.GetPointer())->GetSilentUpdate()))
{
setupScan(this->m_ScanMode);
m_ImageSource->UpdateImageGeometry();
}
OnFreeze(false);
}
void mitk::USDiPhASDevice::UpdateTransmitEvents()
{
int numChannels = m_ScanMode.reconstructionLines;
// transmitEventsCount defines only the number of acoustic measurements (angles); there will be one event added to the start for OA measurement
m_ScanMode.TransmitEvents = new TransmitEventNative[m_ScanMode.transmitEventsCount];
for (int ev = 0; ev < m_ScanMode.transmitEventsCount; ++ev)
{
m_ScanMode.TransmitEvents[ev].transmitEventDelays = new float[numChannels];
m_ScanMode.TransmitEvents[ev].BurstHalfwaveClockCountPerChannel = new int[numChannels];
m_ScanMode.TransmitEvents[ev].BurstCountPerChannel = new int[numChannels];
m_ScanMode.TransmitEvents[ev].BurstUseNegativePolarityPerChannel = new bool[numChannels];
m_ScanMode.TransmitEvents[ev].ChannelMultiplexerSetups = nullptr;
float tiltStrength = ((m_ScanMode.transmitEventsCount - 1) / 2 - ev) * 20e-9f;
for (int i = 0; i < numChannels; ++i)
{
m_ScanMode.TransmitEvents[ev].BurstHalfwaveClockCountPerChannel[i] = m_BurstHalfwaveClockCount; // 120 MHz / (2 * (predefinedBurstHalfwaveClockCount + 1)) --> 7.5 MHz
m_ScanMode.TransmitEvents[ev].BurstCountPerChannel[i] = 1; // Burst with 1 cycle
m_ScanMode.TransmitEvents[ev].BurstUseNegativePolarityPerChannel[i] = true;
m_ScanMode.TransmitEvents[ev].transmitEventDelays[i] = 2e-6f + (i - numChannels / 2) * tiltStrength;
}
}
m_ScanMode.transmitSequenceCount = 1;
m_ScanMode.transmitSequences = new SequenceNative[m_ScanMode.transmitSequenceCount];
m_ScanMode.transmitSequences[0].startEvent = 0;
m_ScanMode.transmitSequences[0].endEvent = m_ScanMode.transmitEventsCount;
}
void mitk::USDiPhASDevice::InitializeScanMode()
{
// create a scanmode to be used for measurements:
m_ScanMode.scanModeName = "InterleavedMode";
// configure a linear transducer
m_ScanMode.transducerName = "L5-10";
m_ScanMode.transducerCurvedRadiusMeter = 0;
m_ScanMode.transducerElementCount = 128;
m_ScanMode.transducerFrequencyHz = 7500000;
m_ScanMode.transducerPitchMeter = 0.0003f;
m_ScanMode.transducerType = 1;
// configure the receive paramters:
m_ScanMode.receivePhaseLengthSeconds = 185e-6f; // about 15 cm imaging depth
m_ScanMode.tgcdB = new unsigned char[8];
for (int tgc = 0; tgc < 8; ++tgc)
m_ScanMode.tgcdB[tgc] = tgc * 2 + 10;
m_ScanMode.accumulation = 1;
m_ScanMode.bandpassApply = false;
m_ScanMode.averagingCount = 1;
// configure general processing:
m_ScanMode.transferChannelData = true;
// configure reconstruction processing:
m_ScanMode.averageSpeedOfSound = 1540;
m_ScanMode.computeBeamforming = true;
// setup beamforming parameters:
SetInterleaved(true);
m_ScanMode.reconstructedLinePitchMmOrAngleDegree = 0.3f;
m_ScanMode.reconstructionLines = 128;
m_ScanMode.reconstructionSamplesPerLine = 2048;
m_ScanMode.transferBeamformedData = true;
// configure the transmit sequence(s):
m_ScanMode.transmitEventsCount = 1;
m_ScanMode.transmitPhaseLengthSeconds = 1e-6f;
m_ScanMode.voltageV = 75;
UpdateTransmitEvents();
// configure bandpass:
m_ScanMode.bandpassApply = false;
m_ScanMode.bandpassFrequencyLowHz = 1e6f;
m_ScanMode.bandpassFrequencyHighHz = 20e6f;
// configure image generation:
m_ScanMode.imageWidth = 512;
m_ScanMode.imageHeight = 512;
m_ScanMode.imageMultiplier = 1;
m_ScanMode.imageLeveling = 0;
m_ScanMode.transferImageData = false;
// Trigger setup:
m_ScanMode.triggerSetup.enabled = true;
m_ScanMode.triggerSetup.constantPulseRepetitionRateHz = 20;
m_ScanMode.triggerSetup.triggerWidthMicroseconds = 15;
m_ScanMode.triggerSetup.delayTrigger2Microseconds = 300;
}
// callback for the DiPhAS API
void mitk::USDiPhASDevice::MessageCallback(const char* message)
{
MITK_INFO << "DiPhAS API: " << message << '\n';
}
void mitk::USDiPhASDevice::SetBursts(int bursts)
{
m_BurstHalfwaveClockCount = bursts;
}
bool mitk::USDiPhASDevice::IsInterleaved()
{
return m_Interleaved;
}
void mitk::USDiPhASDevice::SetInterleaved(bool interleaved)
{
m_Interleaved = interleaved;
if (interleaved) {
m_ScanMode.scanModeName = "Interleaved Beamforming Mode";
m_CurrentBeamformingAlgorithm = Beamforming::Interleaved_OA_US;
paramsInterleaved.SpeedOfSoundMeterPerSecond = m_ScanMode.averageSpeedOfSound;
paramsInterleaved.angleSkipFactor = 1;
paramsInterleaved.OptoacousticDelay = 0.0000003; // 300ns
paramsInterleaved.filter = Filter::None;
m_ScanMode.beamformingAlgorithmParameters = ¶msInterleaved;
}
else {
m_ScanMode.scanModeName = "Plane Wave Beamforming Mode";
m_CurrentBeamformingAlgorithm = Beamforming::PlaneWaveCompound;
paramsPlaneWave.SpeedOfSoundMeterPerSecond = m_ScanMode.averageSpeedOfSound;
paramsPlaneWave.angleSkipFactor = 0;
paramsPlaneWave.usePhaseCoherence = 0;
m_ScanMode.beamformingAlgorithmParameters = ¶msPlaneWave;
}
m_ScanMode.beamformingAlgorithm = m_CurrentBeamformingAlgorithm;
}
\ No newline at end of file
diff --git a/Modules/US/USHardwareDiPhAS/mitkUSDiPhASImageSource.cpp b/Modules/US/USHardwareDiPhAS/mitkUSDiPhASImageSource.cpp
index cba81bd664..549ce8ef16 100644
--- a/Modules/US/USHardwareDiPhAS/mitkUSDiPhASImageSource.cpp
+++ b/Modules/US/USHardwareDiPhAS/mitkUSDiPhASImageSource.cpp
@@ -1,894 +1,931 @@
/*===================================================================
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.
===================================================================*/
// std dependencies
#include
#include
#include
// mitk dependencies
#include "mitkUSDiPhASDevice.h"
#include "mitkUSDiPhASImageSource.h"
#include
#include "mitkUSDiPhASBModeImageFilter.h"
#include "ITKUltrasound/itkBModeImageFilter.h"
#include "mitkImageCast.h"
#include "mitkITKImageImport.h"
// itk dependencies
#include "itkImage.h"
#include "itkResampleImageFilter.h"
#include "itkCastImageFilter.h"
#include "itkCropImageFilter.h"
#include "itkRescaleIntensityImageFilter.h"
#include "itkIntensityWindowingImageFilter.h"
#include
#include "itkMultiplyImageFilter.h"
-
mitk::USDiPhASImageSource::USDiPhASImageSource(mitk::USDiPhASDevice* device)
: m_Device(device),
m_StartTime(((float)std::clock()) / CLOCKS_PER_SEC),
m_UseGUIOutPut(false),
m_DataType(DataType::Image_uChar),
m_GUIOutput(nullptr),
m_UseBModeFilter(false),
m_CurrentlyRecording(false),
m_DataTypeModified(true),
m_DataTypeNext(DataType::Image_uChar),
m_CurrentImageTimestamp(0),
m_PyroConnected(false),
m_ImageTimestampBuffer(),
m_VerticalSpacing(0),
m_UseBModeFilterModified(false),
m_UseBModeFilterNext(false),
m_ScatteringCoefficientModified(false),
m_CompensateForScatteringModified(false),
m_VerticalSpacingModified(false),
m_ScatteringCoefficient(15),
m_CompensateForScattering(false),
m_CompensateEnergy(false),
m_CompensateEnergyNext(false),
m_CompensateEnergyModified(false)
{
m_BufferSize = 100;
m_ImageTimestampBuffer.insert(m_ImageTimestampBuffer.begin(), m_BufferSize, 0);
m_LastWrittenImage = m_BufferSize - 1;
m_ImageBuffer.insert(m_ImageBuffer.begin(), m_BufferSize, nullptr);
us::ModuleResource resourceFile;
std::string name;
m_FluenceCompOriginal.insert(m_FluenceCompOriginal.begin(), 5, Image::New());
for (int i = 5; i <= 25; ++i)
{
name = "c:\\HomogeneousScatteringAssumptions\\Scattering" + std::to_string(i) + ".nrrd";
m_FluenceCompOriginal.push_back(mitk::IOUtil::LoadImage(name));
}
m_FluenceCompResized.insert(m_FluenceCompResized.begin(), 26, Image::New());
m_FluenceCompResizedItk.insert(m_FluenceCompResizedItk.begin(), 26, itk::Image::New());
}
mitk::USDiPhASImageSource::~USDiPhASImageSource()
{
// close the pyro
MITK_INFO("Pyro Debug") << "StopDataAcquisition: " << m_Pyro->StopDataAcquisition();
MITK_INFO("Pyro Debug") << "CloseConnection: " << m_Pyro->CloseConnection();
m_PyroConnected = false;
m_Pyro = nullptr;
}
-void mitk::USDiPhASImageSource::GetNextRawImage( mitk::Image::Pointer& image)
+void mitk::USDiPhASImageSource::GetNextRawImage(std::vector& imageVector)
{
// modify all settings that have been changed here, so we don't get multithreading issues
if (m_DataTypeModified)
{
SetDataType(m_DataTypeNext);
m_DataTypeModified = false;
UpdateImageGeometry();
}
if (m_UseBModeFilterModified)
{
SetUseBModeFilter(m_UseBModeFilterNext);
m_UseBModeFilterModified = false;
}
if (m_VerticalSpacingModified)
{
m_VerticalSpacing = m_VerticalSpacingNext;
m_VerticalSpacingModified = false;
}
if (m_ScatteringCoefficientModified)
{
m_ScatteringCoefficient = m_ScatteringCoefficientNext;
m_ScatteringCoefficientModified = false;
}
if (m_CompensateForScatteringModified)
{
m_CompensateForScattering = m_CompensateForScatteringNext;
m_CompensateForScatteringModified = false;
}
if (m_CompensateEnergyModified)
{
m_CompensateEnergy = m_CompensateEnergyNext;
m_CompensateEnergyModified = false;
}
+ if (imageVector.size() != 2)
+ {
+ imageVector.resize(2);
+ }
+
// make sure image is nullptr
- image = nullptr;
+ mitk::Image::Pointer image = nullptr;
float ImageEnergyValue = 0;
for (int i = 100; i > 90 && ImageEnergyValue <= 0; --i)
{
if (m_ImageTimestampBuffer[(m_LastWrittenImage + i) % 100] != 0)
{
ImageEnergyValue = m_Pyro->GetClosestEnergyInmJ(m_ImageTimestampBuffer[(m_LastWrittenImage + i) % 100]);
if (ImageEnergyValue > 0) {
image = &(*m_ImageBuffer[(m_LastWrittenImage + i) % 100]);
}
}
}
// if we did not get any usable Energy value, compensate using this default value
if (image == nullptr)
{
image = &(*m_ImageBuffer[m_LastWrittenImage]);
ImageEnergyValue = 40;
if (image == nullptr)
return;
}
// do image processing before displaying it
if (image.IsNotNull())
{
- typedef itk::Image< float, 3 > itkFloatImageType;
itkFloatImageType::Pointer itkImage;
mitk::CastToItkImage(image, itkImage);
image = mitk::GrabItkImageMemory(itkImage); //thereby using float images
+ image = CutOffTop(image, 165);
// now apply filters to the image, if the options have been selected.
if ((m_CompensateForScattering || m_UseBModeFilter) && m_DataType == DataType::Beamformed_Short)
{
if (m_Device->GetScanMode().beamformingAlgorithm == Beamforming::PlaneWaveCompound) // this is for ultrasound only mode
{
if (m_UseBModeFilter)
{
image = ApplyBmodeFilter(image, true);
if (m_VerticalSpacing)
image = ResampleOutputVertical(image, m_VerticalSpacing);
}
}
else
{
Image::Pointer imagePA = Image::New();
unsigned int dim[] = { image->GetDimension(0),image->GetDimension(1),1};
imagePA->Initialize(image->GetPixelType(), 3, dim);
imagePA->SetGeometry(image->GetGeometry());
Image::Pointer imageUS = Image::New();
imageUS->Initialize(image->GetPixelType(), 3, dim);
imageUS->SetGeometry(image->GetGeometry());
ImageReadAccessor inputReadAccessorCopyPA(image, image->GetSliceData(0));
imagePA->SetSlice(inputReadAccessorCopyPA.GetData(), 0);
ImageReadAccessor inputReadAccessorCopyUS(image, image->GetSliceData(1));
imageUS->SetSlice(inputReadAccessorCopyUS.GetData(), 0);
// first, seperate the PA image from the USImages
// then, we compensate the PAImage using our ImageEnergyValue
if(m_CompensateEnergy)
imagePA = MultiplyImage(imagePA, 1/ImageEnergyValue); // TODO: add the correct prefactor here!!!!
// now we apply the BModeFilter
if (m_UseBModeFilter)
{
imageUS = ApplyBmodeFilter(imageUS, true); // the US Images get a logarithmic filter
imagePA = ApplyBmodeFilter(imagePA, false);
}
ImageReadAccessor inputReadAccessorPA(imagePA, imagePA->GetSliceData(0));
image->SetSlice(inputReadAccessorPA.GetData(), 0);
ImageReadAccessor inputReadAccessorUS(imageUS, imageUS->GetSliceData(0));
image->SetSlice(inputReadAccessorUS.GetData(), 1);
if (m_VerticalSpacing)
{
image = ResampleOutputVertical(image, m_VerticalSpacing);
}
// and finally the scattering corrections
if (m_CompensateForScattering)
{
auto curResizeImage = m_FluenceCompResized.at(m_ScatteringCoefficient); // just for convenience
// update the fluence reference images!
bool doResampling = image->GetDimension(0) != curResizeImage->GetDimension(0) || image->GetDimension(1) != curResizeImage->GetDimension(1)
|| image->GetGeometry()->GetSpacing()[0] != curResizeImage->GetGeometry()->GetSpacing()[0] || image->GetGeometry()->GetSpacing()[1] != curResizeImage->GetGeometry()->GetSpacing()[1];
if (doResampling)
{
curResizeImage = ApplyResampling(m_FluenceCompOriginal.at(m_ScatteringCoefficient), image->GetGeometry()->GetSpacing(), image->GetDimensions());
double* rawOutputData = new double[image->GetDimension(0)*image->GetDimension(1)];
double* rawScatteringData = (double*)curResizeImage->GetData();
int sizeRawScatteringData = curResizeImage->GetDimension(0) * curResizeImage->GetDimension(1);
int imageSize = image->GetDimension(0)*image->GetDimension(1);
//everything above 1.5mm is still inside the transducer; therefore the fluence compensation image has to be positioned a little lower
float upperCutoffmm = 1.5;
int lowerBound = std::round(upperCutoffmm / image->GetGeometry()->GetSpacing()[1])*image->GetDimension(0);
int upperBound = lowerBound + sizeRawScatteringData;
for (int i = 0; i < lowerBound && i < imageSize; ++i)
{
rawOutputData[i] = 0; // everything than cannot be compensated shall be treated as garbage, here the upper 0.15mm
}
for (int i = lowerBound; i < upperBound && i < imageSize; ++i)
{
rawOutputData[i] = 1 / rawScatteringData[i-lowerBound];
}
for (int i = upperBound; i < imageSize; ++i)
{
rawOutputData[i] = 0; // everything than cannot be compensated shall be treated as garbage
}
unsigned int dim[] = { image->GetDimension(0), image->GetDimension(1), 1 };
curResizeImage->Initialize(mitk::MakeScalarPixelType(), 3, dim);
curResizeImage->SetGeometry(image->GetGeometry());
curResizeImage->SetSlice(rawOutputData,0);
delete[] rawOutputData;
mitk::CastToItkImage(curResizeImage, m_FluenceCompResizedItk.at(m_ScatteringCoefficient));
m_FluenceCompResized.at(m_ScatteringCoefficient) = mitk::GrabItkImageMemory(m_FluenceCompResizedItk.at(m_ScatteringCoefficient));
MITK_INFO << "Resized a fluence image.";
}
// actually apply the scattering compensation
imagePA = ApplyScatteringCompensation(imagePA, m_ScatteringCoefficient);
ImageReadAccessor inputReadAccessorPA(imagePA, imagePA->GetSliceData(0));
image->SetSlice(inputReadAccessorPA.GetData(), 0);
}
}
}
+
+ //TODO: completely rewrite this mess
+
+ imageVector[0] = Image::New();
+ unsigned int dim[] = { image->GetDimension(0),image->GetDimension(1),1 };
+ imageVector[0]->Initialize(image->GetPixelType(), 3, dim);
+ imageVector[0]->SetGeometry(image->GetGeometry());
+
+ imageVector[1] = Image::New();
+ imageVector[1]->Initialize(image->GetPixelType(), 3, dim);
+ imageVector[1]->SetGeometry(image->GetGeometry());
+
+ ImageReadAccessor inputReadAccessorCopyPA(image, image->GetSliceData(0));
+ imageVector[0]->SetSlice(inputReadAccessorCopyPA.GetData(), 0);
+ ImageReadAccessor inputReadAccessorCopyUS(image, image->GetSliceData(1));
+ imageVector[1]->SetSlice(inputReadAccessorCopyUS.GetData(), 0);
}
}
mitk::Image::Pointer mitk::USDiPhASImageSource::ApplyBmodeFilter(mitk::Image::Pointer image, bool useLogFilter)
{
// we use this seperate ApplyBmodeFilter Method for processing of two-dimensional images
// the image needs to be of floating point type for the envelope filter to work; the casting is done automatically by the CastToItkImage
- typedef itk::Image< float, 3 > itkFloatImageType;
-
+
typedef itk::BModeImageFilter < itkFloatImageType, itkFloatImageType > BModeFilterType;
BModeFilterType::Pointer bModeFilter = BModeFilterType::New(); // LogFilter
typedef itk::PhotoacousticBModeImageFilter < itkFloatImageType, itkFloatImageType > PhotoacousticBModeImageFilter;
PhotoacousticBModeImageFilter::Pointer photoacousticBModeFilter = PhotoacousticBModeImageFilter::New(); // No LogFilter
itkFloatImageType::Pointer itkImage;
-
- mitk::CastToItkImage(image, itkImage);
-
itkFloatImageType::Pointer bmode;
+ mitk::CastToItkImage(image, itkImage);
if (useLogFilter)
{
bModeFilter->SetInput(itkImage);
bModeFilter->SetDirection(1);
bmode = bModeFilter->GetOutput();
}
else
{
photoacousticBModeFilter->SetInput(itkImage);
photoacousticBModeFilter->SetDirection(1);
bmode = photoacousticBModeFilter->GetOutput();
}
return mitk::GrabItkImageMemory(bmode);
}
+mitk::Image::Pointer mitk::USDiPhASImageSource::CutOffTop(mitk::Image::Pointer image, int cutOffSize)
+{
+ typedef itk::CropImageFilter < itkFloatImageType, itkFloatImageType > CutImageFilter;
+ itkFloatImageType::SizeType cropSize;
+ itkFloatImageType::Pointer itkImage;
+ mitk::CastToItkImage(image, itkImage);
+
+ cropSize[0] = 0;
+ if(itkImage->GetLargestPossibleRegion().GetSize()[1] == 2048)
+ cropSize[1] = cutOffSize;
+ else
+ cropSize[1] = 0;
+ cropSize[2] = 0;
+ CutImageFilter::Pointer cutOffFilter = CutImageFilter::New();
+ cutOffFilter->SetInput(itkImage);
+ cutOffFilter->SetLowerBoundaryCropSize(cropSize);
+ cutOffFilter->UpdateLargestPossibleRegion();
+ return mitk::GrabItkImageMemory(cutOffFilter->GetOutput());
+}
+
mitk::Image::Pointer mitk::USDiPhASImageSource::ResampleOutputVertical(mitk::Image::Pointer image, float verticalSpacing)
{
- typedef itk::Image< float, 3 > itkFloatImageType;
typedef itk::ResampleImageFilter < itkFloatImageType, itkFloatImageType > ResampleImageFilter;
ResampleImageFilter::Pointer resampleImageFilter = ResampleImageFilter::New();
itkFloatImageType::Pointer itkImage;
mitk::CastToItkImage(image, itkImage);
itkFloatImageType::SpacingType outputSpacing;
itkFloatImageType::SizeType inputSize = itkImage->GetLargestPossibleRegion().GetSize();
itkFloatImageType::SizeType outputSize = inputSize;
outputSpacing[0] = itkImage->GetSpacing()[0] * (static_cast(inputSize[0]) / static_cast(outputSize[0]));
outputSpacing[1] = verticalSpacing;
outputSpacing[2] = itkImage->GetSpacing()[2];
outputSize[1] = inputSize[1] * itkImage->GetSpacing()[1] / outputSpacing[1];
typedef itk::IdentityTransform TransformType;
resampleImageFilter->SetInput(itkImage);
resampleImageFilter->SetSize(outputSize);
resampleImageFilter->SetOutputSpacing(outputSpacing);
resampleImageFilter->SetTransform(TransformType::New());
resampleImageFilter->UpdateLargestPossibleRegion();
return mitk::GrabItkImageMemory(resampleImageFilter->GetOutput());
}
mitk::Image::Pointer mitk::USDiPhASImageSource::ApplyScatteringCompensation(mitk::Image::Pointer inputImage, int scattering)
{
- typedef itk::Image< float, 3 > itkFloatImageType;
typedef itk::MultiplyImageFilter MultiplyImageFilterType;
itkFloatImageType::Pointer itkImage;
mitk::CastToItkImage(inputImage, itkImage);
MultiplyImageFilterType::Pointer multiplyFilter = MultiplyImageFilterType::New();
multiplyFilter->SetInput1(itkImage);
multiplyFilter->SetInput2(m_FluenceCompResizedItk.at(m_ScatteringCoefficient));
return mitk::GrabItkImageMemory(multiplyFilter->GetOutput());
}
mitk::Image::Pointer mitk::USDiPhASImageSource::ApplyResampling(mitk::Image::Pointer inputImage, mitk::Vector3D outputSpacing, unsigned int outputSize[3])
{
- typedef itk::Image< double, 3 > itkFloatImageType;
-
typedef itk::ResampleImageFilter < itkFloatImageType, itkFloatImageType > ResampleImageFilter;
ResampleImageFilter::Pointer resampleImageFilter = ResampleImageFilter::New();
itkFloatImageType::Pointer itkImage;
mitk::CastToItkImage(inputImage, itkImage);
itkFloatImageType::SpacingType outputSpacingItk;
itkFloatImageType::SizeType inputSizeItk = itkImage->GetLargestPossibleRegion().GetSize();
itkFloatImageType::SizeType outputSizeItk = inputSizeItk;
itkFloatImageType::SpacingType inputSpacing = itkImage->GetSpacing();
outputSizeItk[0] = outputSize[0];
outputSizeItk[1] = 10*(inputSpacing[1] * inputSizeItk[1]) / (outputSpacing[1]);
outputSizeItk[2] = 1;
outputSpacingItk[0] = 0.996 * inputSpacing[0] * (static_cast(inputSizeItk[0]) / static_cast(outputSizeItk[0])); // TODO: find out why the spacing is not correct, so we need that factor; ?!?!
outputSpacingItk[1] = inputSpacing[1] * (static_cast(inputSizeItk[1]) / static_cast(outputSizeItk[1]));
outputSpacingItk[2] = outputSpacing[2];
typedef itk::IdentityTransform TransformType;
resampleImageFilter->SetInput(itkImage);
resampleImageFilter->SetSize(outputSizeItk);
resampleImageFilter->SetOutputSpacing(outputSpacingItk);
resampleImageFilter->SetTransform(TransformType::New());
resampleImageFilter->UpdateLargestPossibleRegion();
return mitk::GrabItkImageMemory(resampleImageFilter->GetOutput());
}
mitk::Image::Pointer mitk::USDiPhASImageSource::MultiplyImage(mitk::Image::Pointer inputImage, double value)
{
- typedef itk::Image< float, 3 > itkFloatImageType;
typedef itk::MultiplyImageFilter MultiplyImageFilterType;
itkFloatImageType::Pointer itkImage;
mitk::CastToItkImage(inputImage, itkImage);
MultiplyImageFilterType::Pointer multiplyFilter = MultiplyImageFilterType::New();
multiplyFilter->SetInput1(itkImage);
multiplyFilter->SetConstant(value);
return mitk::GrabItkImageMemory(multiplyFilter->GetOutput());
}
void mitk::USDiPhASImageSource::ImageDataCallback(
short* rfDataChannelData,
int& channelDataChannelsPerDataset,
int& channelDataSamplesPerChannel,
int& channelDataTotalDatasets,
short* rfDataArrayBeamformed,
int& beamformedLines,
int& beamformedSamples,
int& beamformedTotalDatasets,
unsigned char* imageData,
int& imageWidth,
int& imageHeight,
int& imageBytesPerPixel,
int& imageSetsTotal,
double& timeStamp)
{
if (m_DataTypeModified)
return;
if (!m_PyroConnected)
{
m_Pyro = mitk::OphirPyro::New();
MITK_INFO << "[Pyro Debug] OpenConnection: " << m_Pyro->OpenConnection();
MITK_INFO << "[Pyro Debug] StartDataAcquisition: " << m_Pyro->StartDataAcquisition();
m_PyroConnected = true;
}
bool writeImage = ((m_DataType == DataType::Image_uChar) && (imageData != nullptr)) || ((m_DataType == DataType::Beamformed_Short) && (rfDataArrayBeamformed != nullptr));
if (writeImage)
{
//get the timestamp we might save later on
m_CurrentImageTimestamp = std::chrono::high_resolution_clock::now().time_since_epoch().count();
// create a new image and initialize it
mitk::Image::Pointer image = mitk::Image::New();
switch (m_DataType)
{
case DataType::Image_uChar: {
m_ImageDimensions[0] = imageWidth;
m_ImageDimensions[1] = imageHeight;
m_ImageDimensions[2] = imageSetsTotal;
image->Initialize(mitk::MakeScalarPixelType(), 3, m_ImageDimensions);
break;
}
case DataType::Beamformed_Short: {
m_ImageDimensions[0] = beamformedLines;
m_ImageDimensions[1] = beamformedSamples;
m_ImageDimensions[2] = beamformedTotalDatasets;
image->Initialize(mitk::MakeScalarPixelType(), 3, m_ImageDimensions);
break;
}
}
image->GetGeometry()->SetSpacing(m_ImageSpacing);
image->GetGeometry()->Modified();
// write the given buffer into the image
switch (m_DataType)
{
case DataType::Image_uChar: {
for (unsigned char i = 0; i < imageSetsTotal; i++) {
image->SetSlice(&imageData[i*imageHeight*imageWidth], i);
}
break;
}
case DataType::Beamformed_Short: {
short* flipme = new short[beamformedLines*beamformedSamples*beamformedTotalDatasets];
int pixelsPerImage = beamformedLines*beamformedSamples;
for (unsigned char currentSet = 0; currentSet < beamformedTotalDatasets; currentSet++)
{
for (unsigned short sample = 0; sample < beamformedSamples; sample++)
{
for (unsigned short line = 0; line < beamformedLines; line++)
{
flipme[sample*beamformedLines + line + pixelsPerImage*currentSet]
= rfDataArrayBeamformed[line*beamformedSamples + sample + pixelsPerImage*currentSet];
}
} // the beamformed pa image is flipped by 90 degrees; we need to flip it manually
}
for (unsigned char i = 0; i < beamformedTotalDatasets; i++) {
image->SetSlice(&flipme[i*beamformedLines*beamformedSamples], i);
// set every image to a different slice
}
delete[] flipme;
break;
}
}
if (m_SavingSettings.saveRaw && m_CurrentlyRecording && rfDataChannelData != nullptr)
{
unsigned int dim[3];
dim[0] = channelDataChannelsPerDataset;
dim[1] = channelDataSamplesPerChannel;
dim[2] = 1;
short offset = m_Device->GetScanMode().accumulation * 2048;
short* noOffset = new short[channelDataChannelsPerDataset*channelDataSamplesPerChannel*channelDataTotalDatasets];
- for (unsigned char set = 0; set < channelDataTotalDatasets; ++set)
+ for (unsigned char set = 0; set < 1; ++set)// channelDataTotalDatasets; ++set) // we ignore the raw US images for now
{
for (unsigned short sam = 0; sam < channelDataSamplesPerChannel; ++sam)
{
for (unsigned short chan = 0; chan < channelDataChannelsPerDataset; ++chan)
{
noOffset[set*channelDataSamplesPerChannel*channelDataChannelsPerDataset + sam * channelDataChannelsPerDataset + chan] =
rfDataChannelData[set*channelDataSamplesPerChannel*channelDataChannelsPerDataset + sam * channelDataChannelsPerDataset + chan] - offset; // this offset in the raw Images is given by the API...
}
}
}
// save the raw images when recording
- for (unsigned char i = 0; i < channelDataTotalDatasets; ++i)
+ for (unsigned char i = 0; i < 1; ++i)// channelDataTotalDatasets; ++i) // we ignore the raw US images for now
{
mitk::Image::Pointer rawImage = mitk::Image::New();
rawImage->Initialize(mitk::MakeScalarPixelType(), 3, dim);
rawImage->SetSlice(&noOffset[i*channelDataChannelsPerDataset*channelDataSamplesPerChannel]);
float& recordTime = m_Device->GetScanMode().receivePhaseLengthSeconds;
int& speedOfSound = m_Device->GetScanMode().averageSpeedOfSound;
mitk::Vector3D rawSpacing;
rawSpacing[0] = m_Device->GetScanMode().transducerPitchMeter * 1000; // save in mm
- rawSpacing[1] = recordTime / channelDataSamplesPerChannel / 2 * 1000000; // save in us
+ rawSpacing[1] = recordTime / channelDataSamplesPerChannel * 1000000; // save in us
rawSpacing[2] = 1;
rawImage->GetGeometry()->SetSpacing(rawSpacing);
rawImage->GetGeometry()->Modified();
m_RawRecordedImages.push_back(rawImage);
}
delete[] noOffset;
}
itk::Index<3> pixel = { {
(itk::Index<3>::IndexValueType)(image->GetDimension(0) / 2),
(itk::Index<3>::IndexValueType)(22.0/532.0*m_Device->GetScanMode().reconstructionSamplesPerLine),
0 } }; //22/532*2048 = 84
if (!m_Pyro->IsSyncDelaySet() &&(image->GetPixelValueByIndex(pixel) < -30)) // #MagicNumber
{
MITK_INFO << "Setting SyncDelay now";
m_Pyro->SetSyncDelay(m_CurrentImageTimestamp);
}
m_ImageTimestampBuffer[(m_LastWrittenImage + 1) % m_BufferSize] = m_CurrentImageTimestamp;
m_ImageBuffer[(m_LastWrittenImage + 1) % m_BufferSize] = image;
m_LastWrittenImage = (m_LastWrittenImage + 1) % m_BufferSize;
// if the user decides to start recording, we feed the vector the generated images
if (m_CurrentlyRecording) {
for (unsigned char index = 0; index < image->GetDimension(2); ++index)
{
if (image->IsSliceSet(index))
{
m_RecordedImages.push_back(Image::New());
unsigned int dim[] = { image ->GetDimension(0), image->GetDimension(1), 1};
m_RecordedImages.back()->Initialize(image->GetPixelType(), 3, dim);
m_RecordedImages.back()->SetGeometry(image->GetGeometry());
mitk::ImageReadAccessor inputReadAccessor(image, image->GetSliceData(index));
m_RecordedImages.back()->SetSlice(inputReadAccessor.GetData(),0);
}
}
m_ImageTimestampRecord.push_back(m_CurrentImageTimestamp);
// save timestamps for each laser image!
}
}
}
void mitk::USDiPhASImageSource::UpdateImageGeometry()
{
MITK_INFO << "Retreaving Image Geometry Information for Spacing...";
float& recordTime = m_Device->GetScanMode().receivePhaseLengthSeconds;
int& speedOfSound = m_Device->GetScanMode().averageSpeedOfSound;
float& pitch = m_Device->GetScanMode().reconstructedLinePitchMmOrAngleDegree;
int& reconstructionLines = m_Device->GetScanMode().reconstructionLines;
switch (m_DataType)
{
case DataType::Image_uChar : {
int& imageWidth = m_Device->GetScanMode().imageWidth;
int& imageHeight = m_Device->GetScanMode().imageHeight;
m_ImageSpacing[0] = pitch * reconstructionLines / imageWidth;
m_ImageSpacing[1] = recordTime * speedOfSound / 2 * 1000 / imageHeight;
break;
}
case DataType::Beamformed_Short : {
int& imageWidth = reconstructionLines;
int& imageHeight = m_Device->GetScanMode().reconstructionSamplesPerLine;
m_ImageSpacing[0] = pitch;
m_ImageSpacing[1] = recordTime * speedOfSound / 2 * 1000 / imageHeight;
break;
}
}
m_ImageSpacing[2] = 1;
MITK_INFO << "Retreaving Image Geometry Information for Spacing " << m_ImageSpacing[0] << " ... " << m_ImageSpacing[1] << " ... " << m_ImageSpacing[2] << " ...[DONE]";
}
void mitk::USDiPhASImageSource::ModifyDataType(DataType dataT)
{
m_DataTypeModified = true;
m_DataTypeNext = dataT;
}
void mitk::USDiPhASImageSource::ModifyUseBModeFilter(bool isSet)
{
m_UseBModeFilterModified = true;
m_UseBModeFilterNext = isSet;
}
void mitk::USDiPhASImageSource::ModifyScatteringCoefficient(int coeff)
{
m_ScatteringCoefficientNext = coeff;
m_ScatteringCoefficientModified = true;
}
void mitk::USDiPhASImageSource::ModifyCompensateForScattering(bool useIt)
{
m_CompensateForScatteringNext = useIt;
m_CompensateForScatteringModified = true;
}
void mitk::USDiPhASImageSource::ModifyEnergyCompensation(bool compensate)
{
m_CompensateEnergyNext = compensate;
m_CompensateEnergyModified = true;
}
void mitk::USDiPhASImageSource::SetDataType(DataType dataT)
{
if (dataT != m_DataType)
{
m_DataType = dataT;
MITK_INFO << "Setting new DataType..." << dataT;
switch (m_DataType)
{
case DataType::Image_uChar :
MITK_INFO << "height: " << m_Device->GetScanMode().imageHeight << " width: " << m_Device->GetScanMode().imageWidth;
break;
case DataType::Beamformed_Short :
MITK_INFO << "samples: " << m_Device->GetScanMode().reconstructionSamplesPerLine << " lines: " << m_Device->GetScanMode().reconstructionLines;
break;
}
}
}
void mitk::USDiPhASImageSource::SetGUIOutput(std::function out)
{
USDiPhASImageSource::m_GUIOutput = out;
m_StartTime = ((float)std::clock()) / CLOCKS_PER_SEC; //wait till the callback is available again
m_UseGUIOutPut = false;
}
void mitk::USDiPhASImageSource::SetUseBModeFilter(bool isSet)
{
m_UseBModeFilter = isSet;
}
void mitk::USDiPhASImageSource::SetVerticalSpacing(float mm)
{
m_VerticalSpacingNext = mm;
m_VerticalSpacingModified = true;
}
void mitk::USDiPhASImageSource::SetSavingSettings(SavingSettings settings)
{
m_SavingSettings = settings;
}
// this is just a little function to set the filenames below right
inline void replaceAll(std::string& str, const std::string& from, const std::string& to) {
if (from.empty())
return;
size_t start_pos = 0;
while ((start_pos = str.find(from, start_pos)) != std::string::npos) {
str.replace(start_pos, from.length(), to);
start_pos += to.length(); // In case 'to' contains 'from', like replacing 'x' with 'yx'
}
}
void mitk::USDiPhASImageSource::SetRecordingStatus(bool record)
{
// start the recording process
if (record)
{
m_RecordedImages.clear();
m_RawRecordedImages.clear(); // we make sure there are no leftovers
m_ImageTimestampRecord.clear(); // also for the timestamps
m_PixelValues.clear(); // aaaand for the pixel values
if (m_SavingSettings.saveRaw)
{
m_Device->GetScanMode().transferChannelData = true;
m_Device->UpdateScanmode();
// set the raw Data to be transfered
}
// tell the callback to start recording images
m_CurrentlyRecording = true;
}
// save images, end recording, and clean up
else
{
m_CurrentlyRecording = false;
m_Device->GetScanMode().transferChannelData = false; // make sure raw Channel Data is not transferred anymore!
m_Device->UpdateScanmode();
// get the time and date, put them into a nice string and create a folder for the images
time_t time = std::time(nullptr);
time_t* timeptr = &time;
std::string currentDate = std::ctime(timeptr);
replaceAll(currentDate, ":", "-");
currentDate.pop_back();
//std::string MakeFolder = "mkdir \"c:/DiPhASImageData/" + currentDate + "\"";
//system(MakeFolder.c_str());
// initialize file paths and the images
Image::Pointer PAImage = Image::New();
Image::Pointer USImage = Image::New();
std::string pathPA = "c:\\ImageData\\" + currentDate + "-" + "PAbeamformed" + ".nrrd";
std::string pathUS = "c:\\ImageData\\" + currentDate + "-" + "USImages" + ".nrrd";
std::string pathTS = "c:\\ImageData\\" + currentDate + "-" + "ts" + ".csv";
std::string pathS = "c:\\ImageData\\" + currentDate + "-" + "Settings" + ".txt";
// idon't forget the raw Images (if chosen to be saved)
Image::Pointer PAImageRaw = Image::New();
Image::Pointer USImageRaw = Image::New();
std::string pathPARaw = "c:\\ImageData\\" + currentDate + "-" + "PAraw" + ".nrrd";
std::string pathUSRaw = "c:\\ImageData\\" + currentDate + "-" + "USImagesRaw" + ".nrrd";
if (m_Device->GetScanMode().beamformingAlgorithm == (int)Beamforming::Interleaved_OA_US) // save a PAImage if we used interleaved mode
{
// first, save the data, so the pyro does not aquire more unneccessary timestamps
m_Pyro->SaveData();
// now order the images and save them
// the beamformed ones...
if (m_SavingSettings.saveBeamformed)
{
OrderImagesInterleaved(PAImage, USImage, m_RecordedImages, false);
mitk::IOUtil::Save(USImage, pathUS);
mitk::IOUtil::Save(PAImage, pathPA);
}
// ...and the raw images
if (m_SavingSettings.saveRaw)
{
OrderImagesInterleaved(PAImageRaw, USImageRaw, m_RawRecordedImages, true);
- mitk::IOUtil::Save(USImageRaw, pathUSRaw);
+ // mitk::IOUtil::Save(USImageRaw, pathUSRaw);
mitk::IOUtil::Save(PAImageRaw, pathPARaw);
}
// read the pixelvalues of the enveloped images at this position
itk::Index<3> pixel = { {
- (itk::Index<3>::IndexValueType)(m_RecordedImages.at(1)->GetDimension(0) / 2),
+ (itk::Index<3>::IndexValueType)(m_RecordedImages.at(0)->GetDimension(0) / 2),
(itk::Index<3>::IndexValueType)(22.0 / 532.0*m_Device->GetScanMode().reconstructionSamplesPerLine),
0 } }; //22/532*2048 = 84
+
GetPixelValues(pixel, m_PixelValues); // write the Pixelvalues to m_PixelValues
// save the timestamps!
ofstream timestampFile;
timestampFile.open(pathTS);
timestampFile << ",timestamp,pixelvalue"; // write the header
for (int index = 0; index < m_ImageTimestampRecord.size(); ++index)
{
timestampFile << "\n" << index << "," << m_ImageTimestampRecord.at(index) << "," << m_PixelValues.at(index);
}
timestampFile.close();
//save the settings!
ofstream settingsFile;
settingsFile.open(pathS);
auto& sM = m_Device->GetScanMode();
settingsFile << "[General Parameters]\n";
settingsFile << "Scan Depth [mm] = " << sM.receivePhaseLengthSeconds * sM.averageSpeedOfSound / 2 * 1000 << "\n";
settingsFile << "Speed of Sound [m/s] = " << sM.averageSpeedOfSound << "\n";
settingsFile << "Excitation Frequency [MHz] = " << sM.transducerFrequencyHz/1000000 << "\n";
settingsFile << "Voltage [V] = " << sM.voltageV << "\n";
- settingsFile << "TGC min = " << (int)sM.tgcdB[0] << " max = " << (int)sM.tgcdB[6] << "\n";
+ settingsFile << "TGC min = " << (int)sM.tgcdB[0] << " max = " << (int)sM.tgcdB[7] << "\n";
settingsFile << "[Beamforming Parameters]\n";
settingsFile << "Reconstructed Lines = " << sM.reconstructionLines << "\n";
settingsFile << "Samples per Line = " << sM.reconstructionSamplesPerLine << "\n";
settingsFile.close();
}
else if (m_Device->GetScanMode().beamformingAlgorithm == (int)Beamforming::PlaneWaveCompound) // save no PAImage if we used US only mode
{
OrderImagesUltrasound(USImage, m_RecordedImages);
mitk::IOUtil::Save(USImage, pathUS);
}
m_PixelValues.clear();
m_RawRecordedImages.clear(); // clean up the pixel values
m_RecordedImages.clear(); // clean up the images
m_ImageTimestampRecord.clear(); // clean up the timestamps
}
}
void mitk::USDiPhASImageSource::GetPixelValues(itk::Index<3> pixel, std::vector& values)
{
- unsigned int events = m_Device->GetScanMode().transmitEventsCount + 1; // the PA event is not included in the transmitEvents, so we add 1 here
+ unsigned int events = 2;
for (int index = 0; index < m_RecordedImages.size(); index += events) // omit sound images
{
Image::Pointer image = m_RecordedImages.at(index);
image = ApplyBmodeFilter(image);
values.push_back(image.GetPointer()->GetPixelValueByIndex(pixel));
}
}
void mitk::USDiPhASImageSource::OrderImagesInterleaved(Image::Pointer PAImage, Image::Pointer USImage, std::vector recordedList, bool raw)
{
unsigned int width = 32;
unsigned int height = 32;
unsigned int events = m_Device->GetScanMode().transmitEventsCount + 1; // the PA event is not included in the transmitEvents, so we add 1 here
+ if (!raw)
+ events = 2; // the beamformed image array contains only the resulting image of multiple events
if (raw)
{
width = recordedList.at(0)->GetDimension(0);
height = recordedList.at(0)->GetDimension(1);
}
else if (m_DataType == DataType::Beamformed_Short)
{
width = m_Device->GetScanMode().reconstructionLines;
height = m_Device->GetScanMode().reconstructionSamplesPerLine;
}
else if (m_DataType == DataType::Image_uChar)
{
width = m_Device->GetScanMode().imageWidth;
height = m_Device->GetScanMode().imageHeight;
}
unsigned int dimLaser[] = { (unsigned int)width, (unsigned int)height, (unsigned int)(recordedList.size() / events)};
unsigned int dimSound[] = { (unsigned int)width, (unsigned int)height, (unsigned int)(recordedList.size() / events * (events-1))};
PAImage->Initialize(recordedList.back()->GetPixelType(), 3, dimLaser);
PAImage->SetGeometry(recordedList.back()->GetGeometry());
USImage->Initialize(recordedList.back()->GetPixelType(), 3, dimSound);
USImage->SetGeometry(recordedList.back()->GetGeometry());
for (int index = 0; index < recordedList.size(); ++index)
{
mitk::ImageReadAccessor inputReadAccessor(recordedList.at(index));
+
if (index % events == 0)
{
PAImage->SetSlice(inputReadAccessor.GetData(), index / events);
}
else
{
- USImage->SetSlice(inputReadAccessor.GetData(), ((index - (index % events)) / events) + (index % events)-1);
+ if(!raw)
+ USImage->SetSlice(inputReadAccessor.GetData(), ((index - (index % events)) / events) + (index % events)-1);
}
}
}
void mitk::USDiPhASImageSource::OrderImagesUltrasound(Image::Pointer USImage, std::vector recordedList)
{
unsigned int width = 32;
unsigned int height = 32;
unsigned int events = m_Device->GetScanMode().transmitEventsCount;
if (m_DataType == DataType::Beamformed_Short)
{
width = (unsigned int)m_Device->GetScanMode().reconstructionLines;
height = (unsigned int)m_Device->GetScanMode().reconstructionSamplesPerLine;
}
else if (m_DataType == DataType::Image_uChar)
{
width = (unsigned int)m_Device->GetScanMode().imageWidth;
height = (unsigned int)m_Device->GetScanMode().imageHeight;
}
unsigned int dimSound[] = { (unsigned int)width, (unsigned int)height, (unsigned int)recordedList.size()};
USImage->Initialize(recordedList.back()->GetPixelType(), 3, dimSound);
USImage->SetGeometry(recordedList.back()->GetGeometry());
for (int index = 0; index < recordedList.size(); ++index)
{
mitk::ImageReadAccessor inputReadAccessor(recordedList.at(index));
USImage->SetSlice(inputReadAccessor.GetData(), index);
}
}
\ No newline at end of file
diff --git a/Modules/US/USHardwareDiPhAS/mitkUSDiPhASImageSource.h b/Modules/US/USHardwareDiPhAS/mitkUSDiPhASImageSource.h
index 3f75369e14..54ac576ffd 100644
--- a/Modules/US/USHardwareDiPhAS/mitkUSDiPhASImageSource.h
+++ b/Modules/US/USHardwareDiPhAS/mitkUSDiPhASImageSource.h
@@ -1,191 +1,193 @@
/*===================================================================
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 MITKUSDiPhASImageSource_H_HEADER_INCLUDED_
#define MITKUSDiPhASImageSource_H_HEADER_INCLUDED_
#include "mitkUSImageSource.h"
#include "mitkUSDiPhASCustomControls.h"
#include "Framework.IBMT.US.CWrapper.h"
#include "mitkImageReadAccessor.h"
#include "itkFastMutexLock.h"
#include
#include
#include
#include
#include
#include
#include
#include
namespace mitk {
class USDiPhASDevice;
/**
* \brief Implementation of mitk::USImageSource for DiPhAS API devices.
* The method mitk::USImageSource::GetNextRawImage() is implemented for
* getting images from the DiPhAS API.
*
* The image data is given to this class from the DiPhAS API by calling
* a callback method that writes the image data to an mitk::image
*/
class USDiPhASImageSource : public USImageSource
{
public:
mitkClassMacro(USDiPhASImageSource, USImageSource);
mitkNewMacro1Param(Self, mitk::USDiPhASDevice*);
itkCloneMacro(Self);
+ typedef itk::Image< float, 3 > itkFloatImageType;
typedef mitk::USDiPhASDeviceCustomControls::DataType DataType;
typedef mitk::USDiPhASDeviceCustomControls::SavingSettings SavingSettings;
/**
* Implementation of the superclass method. Returns the pointer
* to the mitk::Image filled by DiPhAS API callback.
*/
- virtual void GetNextRawImage( mitk::Image::Pointer& );
+ virtual void GetNextRawImage( std::vector& ) override;
/**
* The API calls this function to pass the image data to the
* user; here the m_Image is updated
*/
void mitk::USDiPhASImageSource::ImageDataCallback(
short* rfDataChannelData,
int& channelDataChannelsPerDataset,
int& channelDataSamplesPerChannel,
int& channelDataTotalDatasets,
short* rfDataArrayBeamformed,
int& beamformedLines,
int& beamformedSamples,
int& beamformedTotalDatasets,
unsigned char* imageData,
int& imageWidth,
int& imageHeight,
int& imagePixelFormat,
int& imageSetsTotal,
double& timeStamp);
void SetGUIOutput(std::function out);
/** This starts or ends the recording session*/
void SetRecordingStatus(bool record);
void SetSavingSettings(SavingSettings settings);
void SetVerticalSpacing(float mm);
void ModifyDataType(DataType dataT);
void ModifyUseBModeFilter(bool isSet);
void ModifyScatteringCoefficient(int coeff);
void ModifyCompensateForScattering(bool useIt);
void ModifyEnergyCompensation(bool compensate);
/**
* Sets the spacing used in the image based on the informations of the ScanMode in USDiPhAS Device
*/
void UpdateImageGeometry();
protected:
void SetDataType(DataType dataT);
void SetUseBModeFilter(bool isSet);
USDiPhASImageSource(mitk::USDiPhASDevice* device);
virtual ~USDiPhASImageSource( );
/** This vector holds all the images we record, if recording is set to active. */
std::vector m_RecordedImages;
std::vector m_RawRecordedImages;
std::vector m_ImageTimestampRecord;
std::vector m_ImageTimestampBuffer;
long long m_CurrentImageTimestamp;
bool m_CurrentlyRecording;
mitk::OphirPyro::Pointer m_Pyro;
bool m_PyroConnected;
std::vector m_FluenceCompOriginal;
std::vector m_FluenceCompResized;
std::vector::Pointer> m_FluenceCompResizedItk;
std::vector m_ImageBuffer;
int m_LastWrittenImage;
int m_BufferSize;
unsigned int m_ImageDimensions[3];
mitk::Vector3D m_ImageSpacing;
mitk::Image::Pointer ApplyBmodeFilter(mitk::Image::Pointer image, bool useLogFilter = false);
+ mitk::Image::Pointer CutOffTop(mitk::Image::Pointer image, int cutOffSize = 165);
mitk::Image::Pointer ResampleOutputVertical(mitk::Image::Pointer image, float verticalSpacing = 0.1);
mitk::Image::Pointer ApplyScatteringCompensation(mitk::Image::Pointer inputImage, int scatteringCoefficient);
mitk::Image::Pointer ApplyResampling(mitk::Image::Pointer inputImage, mitk::Vector3D outputSpacing, unsigned int outputSize[3]);
mitk::Image::Pointer MultiplyImage(mitk::Image::Pointer inputImage, double value);
void OrderImagesInterleaved(Image::Pointer PAImage, Image::Pointer USImage, std::vector recordedList, bool raw);
void OrderImagesUltrasound(Image::Pointer USImage, std::vector recordedList);
void GetPixelValues(itk::Index<3> pixel, std::vector& values);
float GetPixelValue(itk::Index<3> pixel);
std::vector m_PixelValues;
mitk::USDiPhASDevice* m_Device;
/** This is a callback to pass text data to the GUI. */
std::function m_GUIOutput;
/**
* Variables for management of current state.
*/
SavingSettings m_SavingSettings;
float m_StartTime;
bool m_UseGUIOutPut;
BeamformerStateInfoNative m_BeamformerInfos;
bool m_UseBModeFilter;
bool m_DataTypeModified;
DataType m_DataTypeNext;
bool m_UseBModeFilterModified;
bool m_UseBModeFilterNext;
float m_VerticalSpacing;
float m_VerticalSpacingNext;
bool m_VerticalSpacingModified;
int m_ScatteringCoefficient;
int m_ScatteringCoefficientNext;
bool m_ScatteringCoefficientModified;
bool m_CompensateForScattering;
bool m_CompensateForScatteringNext;
bool m_CompensateForScatteringModified;
bool m_CompensateEnergy;
bool m_CompensateEnergyNext;
bool m_CompensateEnergyModified;
DataType m_DataType;
};
} // namespace mitk
#endif // MITKUSDiPhASImageSource_H
diff --git a/Modules/US/USHardwareTelemed/mitkUSTelemedImageSource.cpp b/Modules/US/USHardwareTelemed/mitkUSTelemedImageSource.cpp
index 4bf27ede28..b30ca763b6 100644
--- a/Modules/US/USHardwareTelemed/mitkUSTelemedImageSource.cpp
+++ b/Modules/US/USHardwareTelemed/mitkUSTelemedImageSource.cpp
@@ -1,145 +1,145 @@
/*===================================================================
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 "mitkUSTelemedImageSource.h"
#include "mitkUSTelemedSDKHeader.h"
#include "MITKUSTelemedScanConverterPlugin.h"
#include "mitkImageReadAccessor.h"
mitk::USTelemedImageSource::USTelemedImageSource()
: m_Image(mitk::Image::New()),
m_ImageMutex(itk::FastMutexLock::New()),
m_Plugin(0),
m_PluginCallback(0),
m_UsgDataView(0),
m_ImageProperties(0),
m_DepthProperties(0),
m_OldnXPelsPerUnit(0),
m_OldnYPelsPerUnit(0)
{
}
mitk::USTelemedImageSource::~USTelemedImageSource( )
{
SAFE_RELEASE(m_PluginCallback);
SAFE_RELEASE(m_Plugin);
SAFE_RELEASE(m_ImageProperties);
SAFE_RELEASE(m_DepthProperties);
}
-void mitk::USTelemedImageSource::GetNextRawImage( mitk::Image::Pointer& image)
+void mitk::USTelemedImageSource::GetNextRawImage(std::vector& imageVector)
{
- if ( image.IsNull() ) { image = mitk::Image::New(); }
+ if (imageVector.empty() ) { imageVector.push_back( mitk::Image::New()); }
//get the actual resolution to check if it changed. We have to do this every time because the geometry takes a few frames to adapt
Usgfw2Lib::tagImageResolution resolutionInMetersActual;
m_ImageProperties->GetResolution(&resolutionInMetersActual, 0);
if (m_OldnXPelsPerUnit != resolutionInMetersActual.nXPelsPerUnit || m_OldnYPelsPerUnit != resolutionInMetersActual.nYPelsPerUnit)
{
//we can only update if the image exists and has a geometry
if (m_Image.IsNotNull() && m_Image->GetGeometry() != nullptr)
{
m_OldnXPelsPerUnit = resolutionInMetersActual.nXPelsPerUnit;
m_OldnYPelsPerUnit = resolutionInMetersActual.nYPelsPerUnit;
UpdateImageGeometry();
}
}
//now update image
if ( m_Image->IsInitialized() )
{
m_ImageMutex->Lock();
// copy contents of the given image into the member variable
- image->Initialize(m_Image->GetPixelType(), m_Image->GetDimension(), m_Image->GetDimensions());
+ imageVector.at(0)->Initialize(m_Image->GetPixelType(), m_Image->GetDimension(), m_Image->GetDimensions());
mitk::ImageReadAccessor inputReadAccessor(m_Image, m_Image->GetSliceData(0,0,0));
- image->SetSlice(inputReadAccessor.GetData());
- image->SetGeometry(m_Image->GetGeometry());
+ imageVector.at(0)->SetSlice(inputReadAccessor.GetData());
+ imageVector.at(0)->SetGeometry(m_Image->GetGeometry());
m_ImageMutex->Unlock();
}
}
void mitk::USTelemedImageSource::UpdateImageGeometry()
{
Usgfw2Lib::tagPixelsOrigin origin = Usgfw2Lib::tagPixelsOrigin();
Usgfw2Lib::tagImageResolution resolutionInMeters;
m_ImageProperties->GetResolution(&resolutionInMeters,0);
mitk::Vector3D spacing;
spacing[0] = ((double)1 / resolutionInMeters.nXPelsPerUnit) * 1000; //conversion: meters to millimeters
spacing[1] = ((double)1 / resolutionInMeters.nXPelsPerUnit) * 1000; //conversion: meters to millimeters
spacing[2] = 1;
m_ImageMutex->Lock();
if(m_Image.IsNotNull() && (m_Image->GetGeometry()!=nullptr))
{
m_Image->GetGeometry()->SetSpacing(spacing);
m_Image->GetGeometry()->Modified();
}
else
{MITK_WARN << "image or geometry was nullptr, can't adapt geometry";}
m_ImageMutex->Unlock();
MITK_DEBUG << "UpdateImageGeometry called!";
MITK_DEBUG << "depth: " << m_DepthProperties->GetCurrent();
MITK_DEBUG << "new spacing: " << spacing;
}
bool mitk::USTelemedImageSource::CreateAndConnectConverterPlugin(Usgfw2Lib::IUsgDataView* usgDataView, Usgfw2Lib::tagScanMode scanMode)
{
IUnknown* tmp_obj = nullptr;
// create control object from Telemed API
mitk::telemed::CreateUsgControl( usgDataView, Usgfw2Lib::IID_IUsgScanConverterPlugin, scanMode, 0, (void**)&tmp_obj );
if ( ! tmp_obj )
{
MITK_ERROR("USImageSource")("USTelemedImageSource") << "Could not create scan converter plugin.";
return false;
}
// create the callback object for the scan conversion
if ( ! m_PluginCallback )
{
m_PluginCallback = new USTelemedScanConverterPlugin();
// current image buffer should be copied to m_Image at every callback
m_PluginCallback->SetOutputImage(m_Image.GetPointer(), m_ImageMutex);
}
else
{
// make sure that the scan converter plugin is not set
// to the plugin callback any longer
m_PluginCallback->SetScanConverterPlugin(0);
}
// now the ScanConverterPlugin can be created and set as plugin
SAFE_RELEASE(m_Plugin);
m_Plugin = (Usgfw2Lib::IUsgScanConverterPlugin*)tmp_obj;
m_PluginCallback->SetScanConverterPlugin(m_Plugin);
//last: create some connections which are needed inside this class for communication with the telemed device
m_UsgDataView = usgDataView;
// create telemed controls
if (!m_DepthProperties) {CREATE_TelemedControl(m_DepthProperties, m_UsgDataView, Usgfw2Lib::IID_IUsgDepth, Usgfw2Lib::IUsgDepth, Usgfw2Lib::SCAN_MODE_B);}
if (!m_ImageProperties) {CREATE_TelemedControl(m_ImageProperties, m_UsgDataView, Usgfw2Lib::IID_IUsgImageProperties, Usgfw2Lib::IUsgImageProperties, Usgfw2Lib::SCAN_MODE_B);}
return true;
}
diff --git a/Modules/US/USHardwareTelemed/mitkUSTelemedImageSource.h b/Modules/US/USHardwareTelemed/mitkUSTelemedImageSource.h
index 0d2f27bbc1..e0270c4dfb 100644
--- a/Modules/US/USHardwareTelemed/mitkUSTelemedImageSource.h
+++ b/Modules/US/USHardwareTelemed/mitkUSTelemedImageSource.h
@@ -1,83 +1,83 @@
/*===================================================================
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 MITKUSTelemedImageSource_H_HEADER_INCLUDED_
#define MITKUSTelemedImageSource_H_HEADER_INCLUDED_
#include "mitkUSImageSource.h"
#include "mitkUSTelemedSDKHeader.h"
#include "mitkUSTelemedScanConverterPlugin.h"
#include "itkFastMutexLock.h"
namespace mitk {
/**
* \brief Implementation of mitk::USImageSource for Telemed API devices.
* The method mitk::USImageSource::GetNextRawImage() is implemented for
* getting images from the Telemed API.
*
* A method for connecting this ImageSource to the Telemed API is
* implemented (mitk::USTelemedImageSource::CreateAndConnectConverterPlugin()).
* This method is available for being used by mitk::USTelemedDevice.
*/
class USTelemedImageSource : public USImageSource
{
public:
mitkClassMacro(USTelemedImageSource, USImageSource);
itkFactorylessNewMacro(Self)
itkCloneMacro(Self)
/**
* Implementation of the superclass method. Returns the pointer
* to the mitk::Image filled by Telemed API callback.
*/
- virtual void GetNextRawImage( mitk::Image::Pointer& );
+ virtual void GetNextRawImage( std::vector& );
/**
* Updates the geometry of the current image from the API.
* Is used internally when a new image is initialized, but
* also needs to be called if, e.g., the zoom factor is changed.
*/
void UpdateImageGeometry();
/**
* \brief Connect this object to the Telemed API.
* This method is for being used by mitk::USTelemedDevice.
*/
bool CreateAndConnectConverterPlugin( Usgfw2Lib::IUsgDataView*, Usgfw2Lib::tagScanMode );
protected:
USTelemedImageSource( );
virtual ~USTelemedImageSource( );
Usgfw2Lib::IUsgScanConverterPlugin* m_Plugin;
USTelemedScanConverterPlugin* m_PluginCallback;
Usgfw2Lib::IUsgDataView* m_UsgDataView; // main SDK object for comminucating with the Telemed API
//API objects for communication, used to get the right geometry
Usgfw2Lib::IUsgImageProperties* m_ImageProperties;
Usgfw2Lib::IUsgDepth* m_DepthProperties;
long m_OldnXPelsPerUnit;
long m_OldnYPelsPerUnit;
mitk::Image::Pointer m_Image;
itk::FastMutexLock::Pointer m_ImageMutex;
};
} // namespace mitk
#endif // MITKUSTelemedImageSource_H
diff --git a/Modules/US/USModel/mitkUSDevice.cpp b/Modules/US/USModel/mitkUSDevice.cpp
index bfdd6783c3..5ad033faee 100644
--- a/Modules/US/USModel/mitkUSDevice.cpp
+++ b/Modules/US/USModel/mitkUSDevice.cpp
@@ -1,671 +1,670 @@
/*===================================================================
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_IsFreezed(false),
m_DeviceState(State_NoState),
+ m_NumberOfOutputs(1),
m_Manufacturer(manufacturer),
m_Name(model),
m_SpawnAcquireThread(true),
m_MultiThreader(itk::MultiThreader::New()),
m_ImageMutex(itk::FastMutexLock::New()),
m_ThreadID(-1),
m_UnregisteringStarted(false)
{
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);
+ this->SetNumberOfIndexedOutputs(m_NumberOfOutputs);
// 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_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;
}
void mitk::USDevice::SetManufacturer(std::string manufacturer)
{
m_Manufacturer = manufacturer;
if (m_DeviceState >= State_Initialized)
{
this->UpdateServiceProperty(
mitk::USDevice::GetPropertyKeys().US_PROPKEY_MANUFACTURER,
manufacturer);
}
}
void mitk::USDevice::SetName(std::string name)
{
m_Name = name;
if (m_DeviceState >= State_Initialized)
{
this->UpdateServiceProperty(
mitk::USDevice::GetPropertyKeys().US_PROPKEY_NAME, name);
}
}
void mitk::USDevice::SetComment(std::string comment)
{
m_Comment = comment;
if (m_DeviceState >= State_Initialized)
{
this->UpdateServiceProperty(
mitk::USDevice::GetPropertyKeys().US_PROPKEY_COMMENT, comment);
}
}
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[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()
{
MITK_DEBUG << "mitk::USDevice::Connect() called";
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());
// initialize the b mode control properties of the micro service
mitk::USControlInterfaceBMode::Pointer bmodeControls =
this->GetControlInterfaceBMode();
if (bmodeControls.IsNotNull())
{
bmodeControls->Initialize();
}
}
this->ProvideViaOIGTL();
return m_DeviceState == State_Activated;
}
void mitk::USDevice::ProvideViaOIGTL()
{
// create a new OpenIGTLink Server
if (m_IGTLServer.IsNull())
m_IGTLServer = mitk::IGTLServer::New(true);
m_IGTLServer->SetName(this->GetName());
// create a new OpenIGTLink Device source
if (m_IGTLMessageProvider.IsNull())
m_IGTLMessageProvider = mitk::IGTLMessageProvider::New();
// set the OpenIGTLink server as the source for the device source
m_IGTLMessageProvider->SetIGTLDevice(m_IGTLServer);
// register the provider so that it can be configured with the IGTL manager
// plugin. This could be hardcoded but now I already have the fancy plugin.
m_IGTLMessageProvider->RegisterAsMicroservice();
m_ImageToIGTLMsgFilter = mitk::ImageToIGTLMessageFilter::New();
m_ImageToIGTLMsgFilter->ConnectTo(this);
// set the name of this filter to identify it easier
m_ImageToIGTLMsgFilter->SetName(this->GetName());
// register this filter as micro service. The message provider looks for
// provided IGTLMessageSources, once it found this microservice and someone
// requested this data type then the provider will connect with this filter
// automatically.
m_ImageToIGTLMsgFilter->RegisterAsMicroservice();
}
void mitk::USDevice::Deactivate()
{
if (!this->GetIsActive())
{
MITK_WARN("mitkUSDevice")
<< "Cannot deactivate a device which is not activae.";
return;
}
if (!OnDeactivation())
{
return;
}
DisableOIGTL();
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::DisableOIGTL()
{
// TODO: This seems not to be enough cleanup to catch all cases. For example, if the device is disconnected
// from the OIGTL GUI, this won't get cleaned up correctly.
m_IGTLServer->CloseConnection();
m_IGTLMessageProvider->UnRegisterMicroservice();
m_ImageToIGTLMsgFilter->UnRegisterMicroservice();
}
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);
// send event to notify listeners about the changed property
m_PropertyChangedMessage(key, value);
}
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 nullptr;
return static_cast(this->ProcessObject::GetPrimaryOutput());
}
mitk::Image* mitk::USDevice::GetOutput(unsigned int idx)
{
if (this->GetNumberOfOutputs() < 1)
return nullptr;
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 nullptr pointer object" );
}
itk::DataObject* output = this->GetOutput(idx);
if ( !output )
{
itkExceptionMacro(<<"Requested to graft output that is a nullptr pointer" );
}
// Call Graft on USImage to copy member data
output->Graft( graft );
}
*/
void mitk::USDevice::GrabImage()
{
- mitk::Image::Pointer image = this->GetUSImageSource()->GetNextImage();
+ std::vector image = this->GetUSImageSource()->GetNextImage();
m_ImageMutex->Lock();
- this->SetImage(image);
+ this->SetImageVector(image);
m_ImageMutex->Unlock();
- // if (image.IsNotNull() && (image->GetGeometry()!=nullptr)){
- // MITK_INFO << "Spacing: " << image->GetGeometry()->GetSpacing();}
}
//########### 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 m_Manufacturer; }
std::string mitk::USDevice::GetDeviceModel() { return m_Name; }
std::string mitk::USDevice::GetDeviceComment() { return m_Comment; }
void mitk::USDevice::GenerateData()
{
m_ImageMutex->Lock();
- if (m_Image.IsNull() || !m_Image->IsInitialized())
+ for (unsigned int i = 0; i < m_ImageVector.size() && i < this->GetNumberOfIndexedOutputs(); ++i)
{
- m_ImageMutex->Unlock();
- return;
- }
+ auto& image = m_ImageVector[i];
+ if (image.IsNull() || !image->IsInitialized())
+ {
+ // skip image
+ }
+ else
+ {
+ mitk::Image::Pointer output = this->GetOutput(i);
- mitk::Image::Pointer output = this->GetOutput();
+ if (!output->IsInitialized() ||
+ output->GetDimension(0) != image->GetDimension(0) ||
+ output->GetDimension(1) != image->GetDimension(1) ||
+ output->GetDimension(2) != image->GetDimension(2) ||
+ output->GetPixelType() != image->GetPixelType())
+ {
+ output->Initialize(image->GetPixelType(), image->GetDimension(),
+ image->GetDimensions());
+ }
- if (!output->IsInitialized() ||
- output->GetDimension(0) != m_Image->GetDimension(0) ||
- output->GetDimension(1) != m_Image->GetDimension(1) ||
- output->GetDimension(2) != m_Image->GetDimension(2) ||
- output->GetPixelType() != m_Image->GetPixelType())
- {
- output->Initialize(m_Image->GetPixelType(), m_Image->GetDimension(),
- m_Image->GetDimensions());
- }
+ // copy contents of the given image into the member variable
+ mitk::ImageReadAccessor inputReadAccessor(image);
+ output->SetImportVolume(inputReadAccessor.GetData());
- // copy contents of the given image into the member variable, slice after slice
- for (unsigned int sliceNumber = 0; sliceNumber < m_Image->GetDimension(2); ++sliceNumber)
- {
- if (m_Image->IsSliceSet(sliceNumber)) {
- mitk::ImageReadAccessor inputReadAccessor(m_Image, m_Image->GetSliceData(sliceNumber, 0, 0));
- output->SetSlice(inputReadAccessor.GetData(), sliceNumber);
+ output->SetGeometry(image->GetGeometry());
}
- }
-
- output->SetGeometry(m_Image->GetGeometry());
+ }
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_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;
}
void mitk::USDevice::ProbeChanged(std::string probename)
{
this->UpdateServiceProperty(mitk::USDevice::GetPropertyKeys().US_PROPKEY_PROBES_SELECTED, probename);
}
void mitk::USDevice::DepthChanged(double depth)
{
this->UpdateServiceProperty(mitk::USDevice::GetPropertyKeys().US_PROPKEY_BMODE_DEPTH, depth);
}
diff --git a/Modules/US/USModel/mitkUSDevice.h b/Modules/US/USModel/mitkUSDevice.h
index a7ba223766..7563fb3728 100644
--- a/Modules/US/USModel/mitkUSDevice.h
+++ b/Modules/US/USModel/mitkUSDevice.h
@@ -1,470 +1,479 @@
/*===================================================================
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
#include "mitkUSImageSource.h"
// MitkIGTL
#include "mitkIGTLMessageProvider.h"
#include "mitkIGTLServer.h"
#include "mitkIGTLDeviceSource.h"
#include "mitkImageToIGTLMessageFilter.h"
// MITK
#include
#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_COMMENT(US_INTERFACE_NAME + ".comment"),
US_PROPKEY_LABEL(US_INTERFACE_NAME + ".label"),
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")
{}
};
/**
* \brief Event for being notified about changes of the micro service properties.
* This event can be used if no micro service context is available.
*/
mitkNewMessage2Macro(PropertyChanged, const std::string&, const std::string&)
/**
* \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 To be called when the used probe changed. Will update the service properties
* @param probename of the now used probe
*/
void ProbeChanged(std::string probename);
/**
* @brief To be called when the scanning depth of the probe changed. Will update the service properties
* @param depth that is now used
*/
void DepthChanged(double depth);
/**
* \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();
/** @return Returns the current image source of this device. */
virtual USImageSource::Pointer GetUSImageSource() = 0;
/** \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);
void SetManufacturer(std::string manufacturer);
void SetName(std::string name);
void SetComment(std::string comment);
itkGetMacro(DeviceState, DeviceStates)
itkGetMacro(ServiceProperties, us::ServiceProperties)
void GrabImage();
protected:
- itkSetMacro(Image, mitk::Image::Pointer);
+ virtual void SetImageVector(std::vector vec)
+ {
+ if (this->m_ImageVector != vec)
+ {
+ this->m_ImageVector = vec;
+ this->Modified();
+ }
+ }
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;
+ std::vector m_ImageVector;
+ //mitk::Image::Pointer m_OutputImage;
/**
* \brief Registers an OpenIGTLink device as a microservice so that we can send the images of
* this device via the network.
*/
void ProvideViaOIGTL();
/**
* \brief Deregisters the microservices for OpenIGTLink.
*/
void DisableOIGTL();
mitk::IGTLServer::Pointer m_IGTLServer;
mitk::IGTLMessageProvider::Pointer m_IGTLMessageProvider;
mitk::ImageToIGTLMessageFilter::Pointer m_ImageToIGTLMsgFilter;
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 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!
* \deprecated Use USDevice(std::string manufacturer, std::string model) instead.
*/
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() override;
std::string GetServicePropertyLabel();
+ unsigned int m_NumberOfOutputs;
+
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!
MITK_DECLARE_SERVICE_INTERFACE(mitk::USDevice, "org.mitk.services.UltrasoundDevice")
#endif // MITKUSDevice_H_HEADER_INCLUDED_
diff --git a/Modules/US/USModel/mitkUSVideoDevice.h b/Modules/US/USModel/mitkUSVideoDevice.h
index 840f624b4d..58ca76a857 100644
--- a/Modules/US/USModel/mitkUSVideoDevice.h
+++ b/Modules/US/USModel/mitkUSVideoDevice.h
@@ -1,225 +1,225 @@
/*===================================================================
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())
*/
virtual 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
*/
virtual 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
*/
virtual 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 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();
- itkGetMacro(Image, mitk::Image::Pointer);
+ 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);
virtual ~USVideoDevice();
/**
* \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.
*/
virtual 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.
*/
virtual 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.
*/
virtual bool OnDisconnection() override;
/**
* \brief Is called during the activation process. After this method is finsihed, the device should be generating images
*/
virtual 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.
*/
virtual bool OnDeactivation() 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/USNavigation/mitkUSCombinedModality.cpp b/Modules/US/USNavigation/mitkUSCombinedModality.cpp
index 0ddbef3fea..0acadcdb3c 100644
--- a/Modules/US/USNavigation/mitkUSCombinedModality.cpp
+++ b/Modules/US/USNavigation/mitkUSCombinedModality.cpp
@@ -1,581 +1,581 @@
/*===================================================================
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"
//Microservices
#include
#include
#include
#include
#include
//TempIncludes
#include
const std::string mitk::USCombinedModality::DeviceClassIdentifier = "org.mitk.modules.us.USCombinedModality";
const char* mitk::USCombinedModality::DefaultProbeIdentifier = "default";
const char* mitk::USCombinedModality::ProbeAndDepthSeperator = "_";
const std::string mitk::USCombinedModality::US_INTERFACE_NAME = "org.mitk.services.USCombinedModality";
const std::string mitk::USCombinedModality::US_PROPKEY_DEVICENAME = US_INTERFACE_NAME + ".devicename";
const std::string mitk::USCombinedModality::US_PROPKEY_CLASS = US_INTERFACE_NAME + ".class";
const std::string mitk::USCombinedModality::US_PROPKEY_ID = US_INTERFACE_NAME + ".id";
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()
{
if (m_ServiceRegistration != nullptr)
m_ServiceRegistration.Unregister();
m_ServiceRegistration = 0;
}
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(); }
if (m_ServiceRegistration != nullptr)
m_ServiceRegistration.Unregister();
m_ServiceRegistration = 0;
}
mitk::AffineTransform3D::Pointer mitk::USCombinedModality::GetCalibration()
{
return this->GetCalibration(this->GetCurrentDepthValue(), this->GetIdentifierForCurrentProbe());
}
mitk::AffineTransform3D::Pointer mitk::USCombinedModality::GetCalibration(std::string depth)
{
return this->GetCalibration(depth, this->GetIdentifierForCurrentProbe());
}
mitk::AffineTransform3D::Pointer mitk::USCombinedModality::GetCalibration(std::string depth, std::string probe)
{
// make sure that there is no '/' which would cause problems for TinyXML
std::replace(probe.begin(), probe.end(), '/', '-');
// create identifier for calibration from probe and depth
std::string calibrationKey = probe + mitk::USCombinedModality::ProbeAndDepthSeperator + depth;
// find calibration for combination of probe identifier and depth
std::map::iterator calibrationIterator
= m_Calibrations.find(calibrationKey);
if (calibrationIterator == m_Calibrations.end()) { 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;
}
bool mitk::USCombinedModality::RemoveCalibration()
{
return this->RemoveCalibration(this->GetCurrentDepthValue(), this->GetIdentifierForCurrentProbe());
}
bool mitk::USCombinedModality::RemoveCalibration(std::string depth)
{
return this->RemoveCalibration(depth, this->GetIdentifierForCurrentProbe());
}
bool mitk::USCombinedModality::RemoveCalibration(std::string depth, std::string probe)
{
// make sure that there is no '/' which would cause problems for TinyXML
std::replace(probe.begin(), probe.end(), '/', '-');
// create identifier for calibration from probe and depth
std::string calibrationKey = probe + mitk::USCombinedModality::ProbeAndDepthSeperator + depth;
return m_Calibrations.erase(calibrationKey) > 0;
}
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)
{
mitk::TrackingDeviceSource::Pointer trackingDeviceSource = dynamic_cast(m_TrackingDevice.GetPointer());
if (trackingDeviceSource.IsNull())
{
MITK_WARN("USCombinedModality")("USDevice") << "Cannot freeze tracking.";
}
else
{
if (freeze) { trackingDeviceSource->Freeze(); }
else { trackingDeviceSource->UnFreeze(); }
}
if (m_UltrasoundDevice.IsNull())
{
MITK_ERROR("USCombinedModality")("USDevice") << "UltrasoundDevice must not be null.";
mitkThrow() << "UltrasoundDevice must not be null.";
}
m_UltrasoundDevice->SetIsFreezed(freeze);
}
mitk::NavigationDataSource::Pointer mitk::USCombinedModality::GetNavigationDataSource()
{
return m_LastFilter.GetPointer();
}
bool mitk::USCombinedModality::GetIsCalibratedForCurrentStatus()
{
return m_Calibrations.find(this->GetIdentifierForCurrentCalibration()) != m_Calibrations.end();
}
bool mitk::USCombinedModality::GetContainsAtLeastOneCalibration()
{
return !m_Calibrations.empty();
}
void mitk::USCombinedModality::GenerateData()
{
if (m_UltrasoundDevice->GetIsFreezed()) { return; } //if the image is freezed: do nothing
//get next image from ultrasound image source
- mitk::Image::Pointer image = m_UltrasoundDevice->GetUSImageSource()->GetNextImage();
+ mitk::Image::Pointer image = m_UltrasoundDevice->GetUSImageSource()->GetNextImage()[0];
if (image.IsNull() || !image->IsInitialized()) //check the image
{
MITK_WARN << "Invalid image in USCombinedModality, aborting!";
return;
}
//get output and initialize it if it wasn't initialized before
mitk::Image::Pointer output = this->GetOutput();
if (!output->IsInitialized()) { output->Initialize(image); }
//now update image data
mitk::ImageReadAccessor inputReadAccessor(image, image->GetSliceData(0, 0, 0));
output->SetSlice(inputReadAccessor.GetData()); //copy image data
output->GetGeometry()->SetSpacing(image->GetGeometry()->GetSpacing()); //copy spacing because this might also change
//and update calibration (= transformation of the image)
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
this->GetOutput()->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_ERROR << "Empty string passed to Deserialize() method of CombinedModality. Aborting...";
mitkThrow() << "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_ERROR << "Unable to deserialize calibrations in CombinedModality. Error was: " << doc.ErrorDesc();
mitkThrow() << "Unable to deserialize calibrations in CombinedModality. Error was: " << doc.ErrorDesc();
return;
}
TiXmlElement* root = doc.FirstChildElement();
if (root == nullptr)
{
MITK_ERROR << "Unable to deserialize calibrations in CombinedModality. String contained no root element.";
mitkThrow() << "Unable to deserialize calibrations in CombinedModality. String contained no root element.";
return;
}
// Read Calibrations
for (TiXmlElement* elem = root->FirstChildElement(); elem != nullptr; 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()
{
return this->GetIdentifierForCurrentProbe()
+ mitk::USCombinedModality::ProbeAndDepthSeperator
+ this->GetCurrentDepthValue();
}
std::string mitk::USCombinedModality::GetIdentifierForCurrentProbe()
{
us::ServiceProperties usdeviceProperties = m_UltrasoundDevice->GetServiceProperties();
us::ServiceProperties::const_iterator probeIt = usdeviceProperties.find(
mitk::USCombinedModality::GetPropertyKeys().US_PROPKEY_PROBES_SELECTED);
// get probe identifier from control interface for probes
std::string probeName = mitk::USCombinedModality::DefaultProbeIdentifier;
if (probeIt != usdeviceProperties.end())
{
probeName = (probeIt->second).ToString();
}
// make sure that there is no '/' which would cause problems for TinyXML
std::replace(probeName.begin(), probeName.end(), '/', '-');
return probeName;
}
std::string mitk::USCombinedModality::GetCurrentDepthValue()
{
us::ServiceProperties usdeviceProperties = m_UltrasoundDevice->GetServiceProperties();
// get string for depth value from the micro service properties
std::string depth;
us::ServiceProperties::iterator depthIterator = usdeviceProperties.find(
mitk::USCombinedModality::GetPropertyKeys().US_PROPKEY_BMODE_DEPTH);
if (depthIterator != usdeviceProperties.end())
{
depth = depthIterator->second.ToString();
}
else
{
depth = "0";
}
return 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;
}
}
void mitk::USCombinedModality::RegisterAsMicroservice()
{
//Get Context
us::ModuleContext* context = us::GetModuleContext();
//Define ServiceProps
us::ServiceProperties props;
mitk::UIDGenerator uidGen =
mitk::UIDGenerator("org.mitk.services.USCombinedModality", 16);
props[US_PROPKEY_ID] = uidGen.GetUID();
props[US_PROPKEY_DEVICENAME] = this->GetName();
props[US_PROPKEY_CLASS] = this->GetDeviceClass();
m_ServiceProperties = props;
m_ServiceRegistration = context->RegisterService(this, props);
}
diff --git a/Plugins/org.mitk.gui.qt.igtexamples/src/internal/OpenIGTLinkPlugin.cpp b/Plugins/org.mitk.gui.qt.igtexamples/src/internal/OpenIGTLinkPlugin.cpp
index 4d4d5c753a..1a94578756 100644
--- a/Plugins/org.mitk.gui.qt.igtexamples/src/internal/OpenIGTLinkPlugin.cpp
+++ b/Plugins/org.mitk.gui.qt.igtexamples/src/internal/OpenIGTLinkPlugin.cpp
@@ -1,199 +1,199 @@
/*===================================================================
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.
===================================================================*/
// Blueberry
#include
#include
// Qmitk
#include "OpenIGTLinkPlugin.h"
// Qt
#include
//mitk image
#include
const std::string OpenIGTLinkPlugin::VIEW_ID = "org.mitk.views.openigtlinkplugin";
void OpenIGTLinkPlugin::SetFocus()
{
}
void OpenIGTLinkPlugin::CreateQtPartControl(QWidget *parent)
{
// create GUI widgets from the Qt Designer's .ui file
m_Controls.setupUi(parent);
connect(m_Controls.buttonConnect, SIGNAL(clicked()), this, SLOT(ConnectButtonClicked()));
connect(m_Controls.buttonReceive, SIGNAL(clicked()), this, SLOT(ReceivingButtonClicked()));
connect(&m_Timer, SIGNAL(timeout()), this, SLOT(UpdatePipeline()));
m_Image2dNode = mitk::DataNode::New();
m_State = IDLE;
StateChanged(m_State);
}
void OpenIGTLinkPlugin::UpdatePipeline()
{
m_NavigationDataObjectVisualizationFilter->Update();
- mitk::Image::Pointer image2d = m_ImageFilter2D->GetNextImage();
- mitk::Image::Pointer image3d = m_ImageFilter3D->GetNextImage();
+ mitk::Image::Pointer image2d = m_ImageFilter2D->GetNextImage().at(0);
+ mitk::Image::Pointer image3d = m_ImageFilter3D->GetNextImage().at(0);
m_Image2dNode->SetName("US Image Stream");
m_Image2dNode->SetData(image2d);
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
}
void OpenIGTLinkPlugin::OnSelectionChanged(berry::IWorkbenchPart::Pointer,
const QList &)
{
// iterate all selected objects, adjust warning visibility
}
void OpenIGTLinkPlugin::ConnectButtonClicked()
{
bool success;
switch (m_State)
{
case IDLE:
m_IGTLClient = mitk::IGTLClient::New(true);
m_IGTLClient->SetHostname(m_Controls.textEditHostname->text().toStdString());
m_IGTLClient->SetPortNumber(m_Controls.spinBoxPort->value());
success = m_IGTLClient->OpenConnection();
if (!success)
{
QMessageBox::warning(nullptr, QString("Connection failed"), QString("Client could not connect to given server."),
QMessageBox::Ok, QMessageBox::Abort);
}
else
{
m_State = CONNECTED;
StateChanged(m_State);
}
break;
case CONNECTED:
success = m_IGTLClient->CloseConnection();
m_State = IDLE;
StateChanged(m_State);
break;
case RECEIVING:
ReceivingButtonClicked();
success = m_IGTLClient->CloseConnection();
m_State = IDLE;
StateChanged(m_State);
break;
}
}
void OpenIGTLinkPlugin::ReceivingButtonClicked()
{
switch (m_State)
{
case IDLE:
QMessageBox::warning(nullptr, QString("Not ready.."), QString("The client must be connected to a server first."),
QMessageBox::Ok, QMessageBox::Abort);
break;
case CONNECTED:
m_IGTL2DImageDeviceSource = mitk::IGTL2DImageDeviceSource::New();
m_IGTL3DImageDeviceSource = mitk::IGTL3DImageDeviceSource::New();
m_IGTLTransformDeviceSource = mitk::IGTLTrackingDataDeviceSource::New();
m_IGTL2DImageDeviceSource->SetIGTLDevice(m_IGTLClient);
m_IGTL3DImageDeviceSource->SetIGTLDevice(m_IGTLClient);
m_IGTLTransformDeviceSource->SetIGTLDevice(m_IGTLClient);
this->GetDataStorage()->Add(m_Image2dNode);
m_IGTLMessageToNavigationDataFilter = mitk::IGTLMessageToNavigationDataFilter::New();
m_NavigationDataObjectVisualizationFilter = mitk::NavigationDataObjectVisualizationFilter::New();
m_ImageFilter2D = mitk::IGTLMessageToUSImageFilter::New();
m_ImageFilter3D = mitk::IGTLMessageToUSImageFilter::New();
m_IGTLMessageToNavigationDataFilter->SetNumberOfExpectedOutputs(3);
m_IGTLMessageToNavigationDataFilter->ConnectTo(m_IGTLTransformDeviceSource);
m_NavigationDataObjectVisualizationFilter->ConnectTo(m_IGTLMessageToNavigationDataFilter);
m_ImageFilter2D->ConnectTo(m_IGTL2DImageDeviceSource);
m_ImageFilter3D->ConnectTo(m_IGTL3DImageDeviceSource);
//create an object that will be moved respectively to the navigation data
for (size_t i = 0; i < m_IGTLMessageToNavigationDataFilter->GetNumberOfIndexedOutputs(); i++)
{
mitk::DataNode::Pointer newNode = mitk::DataNode::New();
QString name("DemoNode T");
name.append(QString::number(i));
newNode->SetName(name.toStdString());
//create small sphere and use it as surface
mitk::Surface::Pointer mySphere = mitk::Surface::New();
vtkSphereSource *vtkData = vtkSphereSource::New();
vtkData->SetRadius(2.0f);
vtkData->SetCenter(0.0, 0.0, 0.0);
vtkData->Update();
mySphere->SetProperty("color", mitk::ColorProperty::New(1, 0, 0));
mySphere->SetVtkPolyData(vtkData->GetOutput());
vtkData->Delete();
newNode->SetData(mySphere);
this->GetDataStorage()->Add(newNode);
m_NavigationDataObjectVisualizationFilter->SetRepresentationObject(i, mySphere);
}
m_IGTLClient->StartCommunication();
m_Timer.setInterval(10);
m_Timer.start();
m_State = RECEIVING;
StateChanged(m_State);
break;
case RECEIVING:
m_IGTLClient->StopCommunication();
this->GetDataStorage()->Remove(this->GetDataStorage()->GetAll());
m_Timer.stop();
m_State = CONNECTED;
StateChanged(m_State);
break;
}
}
void OpenIGTLinkPlugin::StateChanged(OpenIGTLinkPlugin::State newState)
{
switch (newState)
{
case IDLE:
m_Controls.buttonConnect->setText(QString("Connect To Server"));
m_Controls.buttonReceive->setText(QString("Start Receiving"));
m_Controls.buttonReceive->setDisabled(true);
break;
case CONNECTED:
m_Controls.buttonConnect->setText(QString("Disconnect From Server"));
m_Controls.buttonReceive->setText(QString("Start Receiving"));
m_Controls.buttonReceive->setDisabled(false);
break;
case RECEIVING:
m_Controls.buttonConnect->setText(QString("Disconnect From Server"));
m_Controls.buttonReceive->setText(QString("Stop Receiving"));
m_Controls.buttonReceive->setDisabled(false);
break;
}
}
diff --git a/Plugins/org.mitk.gui.qt.lasercontrol/CMakeLists.txt b/Plugins/org.mitk.gui.qt.lasercontrol/CMakeLists.txt
index 114e4aec48..e1e61eaca6 100644
--- a/Plugins/org.mitk.gui.qt.lasercontrol/CMakeLists.txt
+++ b/Plugins/org.mitk.gui.qt.lasercontrol/CMakeLists.txt
@@ -1,24 +1,24 @@
project(org_mitk_gui_qt_lasercontrol)
if(WIN32)
if(MITK_USE_GALIL_HARDWARE)
configure_file( ${MITK_GALIL_API_PATH}/dll/x64/gclib.dll ${MITK_BINARY_DIR}/bin/Debug/ COPYONLY )
configure_file( ${MITK_GALIL_API_PATH}/dll/x64/gclibo.dll ${MITK_BINARY_DIR}/bin/Debug/ COPYONLY )
configure_file( ${MITK_GALIL_API_PATH}/dll/x64/gclib.dll ${MITK_BINARY_DIR}/bin/Release/ COPYONLY )
configure_file( ${MITK_GALIL_API_PATH}/dll/x64/gclibo.dll ${MITK_BINARY_DIR}/bin/Release/ COPYONLY )
endif()
- if(MITK_USE_OPHIR_PRYO_HARDWARE)
+ if(MITK_USE_OPHIR_PYRO_HARDWARE)
configure_file( ${MITK_OPHIR_API_PATH}/Debug/OphirPyroWrapper.dll ${MITK_BINARY_DIR}/bin/Debug/ COPYONLY )
configure_file( ${MITK_OPHIR_API_PATH}/Release/OphirPyroWrapper.dll ${MITK_BINARY_DIR}/bin/Release/ COPYONLY )
configure_file( ${MITK_OPHIR_API_PATH}/Debug/OphirLMMeasurement.dll ${MITK_BINARY_DIR}/bin/Debug/ COPYONLY )
configure_file( ${MITK_OPHIR_API_PATH}/Release/OphirLMMeasurement.dll ${MITK_BINARY_DIR}/bin/Release/ COPYONLY )
configure_file( ${MITK_OPHIR_API_PATH}/Debug/Interop.OphirLMMeasurementLib.dll ${MITK_BINARY_DIR}/bin/Debug/ COPYONLY )
configure_file( ${MITK_OPHIR_API_PATH}/Release/Interop.OphirLMMeasurementLib.dll ${MITK_BINARY_DIR}/bin/Release/ COPYONLY )
endif()
endif()
mitk_create_plugin(
EXPORT_DIRECTIVE LASERCONTROL_EXPORT
EXPORTED_INCLUDE_SUFFIXES src
MODULE_DEPENDS MitkQtWidgetsExt MitkPhotoacousticsHardware
)
diff --git a/Plugins/org.mitk.gui.qt.lasercontrol/files.cmake b/Plugins/org.mitk.gui.qt.lasercontrol/files.cmake
index 55ea3038dc..ebb9b41a94 100644
--- a/Plugins/org.mitk.gui.qt.lasercontrol/files.cmake
+++ b/Plugins/org.mitk.gui.qt.lasercontrol/files.cmake
@@ -1,37 +1,37 @@
set(SRC_CPP_FILES
)
set(INTERNAL_CPP_FILES
mitkLaserControlPluginActivator.cpp
QmitkLaserControl.cpp
)
set(UI_FILES
src/internal/QmitkLaserControlControls.ui
)
set(MOC_H_FILES
src/internal/mitkLaserControlPluginActivator.h
src/internal/QmitkLaserControl.h
)
set(CACHED_RESOURCE_FILES
- resources/iconLaser.xpm
+ resources/iconLaserControl.svg
plugin.xml
)
set(QRC_FILES
)
set(CPP_FILES)
foreach(file ${SRC_CPP_FILES})
set(CPP_FILES ${CPP_FILES} src/${file})
endforeach(file ${SRC_CPP_FILES})
foreach(file ${INTERNAL_CPP_FILES})
set(CPP_FILES ${CPP_FILES} src/internal/${file})
endforeach(file ${INTERNAL_CPP_FILES})
diff --git a/Plugins/org.mitk.gui.qt.lasercontrol/plugin.xml b/Plugins/org.mitk.gui.qt.lasercontrol/plugin.xml
index e480fff300..e2c8781409 100644
--- a/Plugins/org.mitk.gui.qt.lasercontrol/plugin.xml
+++ b/Plugins/org.mitk.gui.qt.lasercontrol/plugin.xml
@@ -1,12 +1,12 @@
+ icon="resources/iconLaserControl.svg" />
diff --git a/Plugins/org.mitk.gui.qt.lasercontrol/resources/iconLaserControl.svg b/Plugins/org.mitk.gui.qt.lasercontrol/resources/iconLaserControl.svg
new file mode 100644
index 0000000000..949e311a9f
--- /dev/null
+++ b/Plugins/org.mitk.gui.qt.lasercontrol/resources/iconLaserControl.svg
@@ -0,0 +1,88 @@
+
+
\ No newline at end of file
diff --git a/Plugins/org.mitk.gui.qt.lasercontrol/src/internal/QmitkLaserControlControls.ui b/Plugins/org.mitk.gui.qt.lasercontrol/src/internal/QmitkLaserControlControls.ui
index 2854825c4f..8eb85c86e6 100644
--- a/Plugins/org.mitk.gui.qt.lasercontrol/src/internal/QmitkLaserControlControls.ui
+++ b/Plugins/org.mitk.gui.qt.lasercontrol/src/internal/QmitkLaserControlControls.ui
@@ -1,775 +1,775 @@
OPOLaserControlControls00343528009QmitkTemplate9OPOTEK Phocus Control1020301431true10Trigger Externallytrue10Init Laserfalse10Start Lampfalse10Start Laser1175trueLaser StatusCurrent Wavelength1075truePreferDefaulttrue750.0 nmQt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenterPulse Energyfalse1075truePreferDefaulttrue0 mJQt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter6900950051007500Qt::HorizontalQSlider::NoTicks100001690.000000000000000950.0000000000000000.500000000000000750.000000000000000nmfalseTune1050falseFast Tuning Wavelengths075167772157510trueQt::SolidLine42503030λ/nm12345678910111213141516171819202122232425262728293031323334353637383940
- 690
+ 700
- 690
+ 710
- 690
+ 720
- 690
+ 730
- 690
+ 740
- 800
+ 750
- 800
+ 760
- 800
+ 770
- 800
+ 780
- 800
+ 790800
- 800
+ 810
- 800
+ 820
- 800
+ 830
- 800
+ 840
-
+ 850
-
+ 860
-
+ 870
-
+ 880
-
+ 890
-
+ 900
-
+ 910
-
+ 920
-
+ 930
-
+ 940falseStart Fast TuningQt::Vertical2040calibrate OPO5000040024400
diff --git a/Plugins/org.mitk.gui.qt.photoacoustics.pausviewer/files.cmake b/Plugins/org.mitk.gui.qt.photoacoustics.pausviewer/files.cmake
index a9177ae3a3..eabd5d2d68 100644
--- a/Plugins/org.mitk.gui.qt.photoacoustics.pausviewer/files.cmake
+++ b/Plugins/org.mitk.gui.qt.photoacoustics.pausviewer/files.cmake
@@ -1,29 +1,29 @@
set(SRC_CPP_FILES
QmitkPAUSViewerView.cpp
)
set(INTERNAL_CPP_FILES
org_mitk_gui_qt_photoacoustics_pausviewer_Activator.cpp
)
set(UI_FILES
src/internal/QmitkPAUSViewerViewControls.ui
)
set(MOC_H_FILES
src/QmitkPAUSViewerView.h
src/internal/org_mitk_gui_qt_photoacoustics_pausviewer_Activator.h
)
set(CACHED_RESOURCE_FILES
- resources/PAUSViewer.png
+ resources/iconPAUSViewer.svg
plugin.xml
)
foreach(file ${SRC_CPP_FILES})
set(CPP_FILES ${CPP_FILES} src/${file})
endforeach(file ${SRC_CPP_FILES})
foreach(file ${INTERNAL_CPP_FILES})
set(CPP_FILES ${CPP_FILES} src/internal/${file})
-endforeach(file ${INTERNAL_CPP_FILES})
\ No newline at end of file
+endforeach(file ${INTERNAL_CPP_FILES})
diff --git a/Plugins/org.mitk.gui.qt.photoacoustics.pausviewer/plugin.xml b/Plugins/org.mitk.gui.qt.photoacoustics.pausviewer/plugin.xml
index 915faef1ce..841dacc1b8 100644
--- a/Plugins/org.mitk.gui.qt.photoacoustics.pausviewer/plugin.xml
+++ b/Plugins/org.mitk.gui.qt.photoacoustics.pausviewer/plugin.xml
@@ -1,12 +1,12 @@
+ icon="resources/iconPAUSViewer.svg" />
diff --git a/Plugins/org.mitk.gui.qt.photoacoustics.pausviewer/resources/iconPAUSViewer.svg b/Plugins/org.mitk.gui.qt.photoacoustics.pausviewer/resources/iconPAUSViewer.svg
new file mode 100644
index 0000000000..8e87197c19
--- /dev/null
+++ b/Plugins/org.mitk.gui.qt.photoacoustics.pausviewer/resources/iconPAUSViewer.svg
@@ -0,0 +1,62 @@
+
+
\ No newline at end of file
diff --git a/Plugins/org.mitk.gui.qt.ultrasound/CMakeLists.txt b/Plugins/org.mitk.gui.qt.ultrasound/CMakeLists.txt
index b7b4f50565..82a82e480f 100644
--- a/Plugins/org.mitk.gui.qt.ultrasound/CMakeLists.txt
+++ b/Plugins/org.mitk.gui.qt.ultrasound/CMakeLists.txt
@@ -1,25 +1,7 @@
project(org_mitk_gui_qt_ultrasound)
-include_directories(${CTK_INCLUDE_DIRS})
-
-IF(WIN32)
- IF(MITK_USE_US_DiPhAS_SDK)
- configure_file( ${MITK_US_DiPhAS_SDK_PATH}/Debug/Framework.IBMT.US.Core.dll ${MITK_BINARY_DIR}/bin/Debug/ COPYONLY )
- configure_file( ${MITK_US_DiPhAS_SDK_PATH}/Debug/Framework.IBMT.US.CWrapper.dll ${MITK_BINARY_DIR}/bin/Debug/ COPYONLY )
- configure_file( ${MITK_US_DiPhAS_SDK_PATH}/Debug/Framework.IBMT.US.OpenCL.dll ${MITK_BINARY_DIR}/bin/Debug/ COPYONLY )
- configure_file( ${MITK_US_DiPhAS_SDK_PATH}/Debug/Framework.IBMT.US.PCIeInterface.dll ${MITK_BINARY_DIR}/bin/Debug/ COPYONLY )
- configure_file( ${MITK_US_DiPhAS_SDK_PATH}/Debug/openclext.dll ${MITK_BINARY_DIR}/bin/Debug/ COPYONLY )
-
- configure_file( ${MITK_US_DiPhAS_SDK_PATH}/Release/Framework.IBMT.US.Core.dll ${MITK_BINARY_DIR}/bin/Release/ COPYONLY )
- configure_file( ${MITK_US_DiPhAS_SDK_PATH}/Release/Framework.IBMT.US.CWrapper.dll ${MITK_BINARY_DIR}/bin/Release/ COPYONLY )
- configure_file( ${MITK_US_DiPhAS_SDK_PATH}/Release/Framework.IBMT.US.OpenCL.dll ${MITK_BINARY_DIR}/bin/Release/ COPYONLY )
- configure_file( ${MITK_US_DiPhAS_SDK_PATH}/Release/Framework.IBMT.US.PCIeInterface.dll ${MITK_BINARY_DIR}/bin/Release/ COPYONLY )
- configure_file( ${MITK_US_DiPhAS_SDK_PATH}/Release/openclext.dll ${MITK_BINARY_DIR}/bin/Release/ COPYONLY )
- ENDIF(MITK_USE_US_DiPhAS_SDK)
-ENDIF(WIN32)
-
mitk_create_plugin(
EXPORT_DIRECTIVE ULTRASOUND_EXPORT
EXPORTED_INCLUDE_SUFFIXES src
MODULE_DEPENDS MitkQtWidgetsExt MitkUS MitkUSUI
)
diff --git a/Plugins/org.mitk.gui.qt.ultrasound/manifest_headers.cmake b/Plugins/org.mitk.gui.qt.ultrasound/manifest_headers.cmake
index ef169719cb..182113f62b 100644
--- a/Plugins/org.mitk.gui.qt.ultrasound/manifest_headers.cmake
+++ b/Plugins/org.mitk.gui.qt.ultrasound/manifest_headers.cmake
@@ -1,5 +1,5 @@
set(Plugin-Name "Ultrasound")
set(Plugin-Version "0.1")
set(Plugin-Vendor "DKFZ, Medical and Biological Informatics")
set(Plugin-ContactAddress "")
-set(Require-Plugin org.mitk.gui.qt.common org.mitk.gui.qt.photoacoustics.pausviewer)
+set(Require-Plugin org.mitk.gui.qt.common)
diff --git a/Plugins/org.mitk.gui.qt.ultrasound/src/internal/QmitkUltrasoundSupport.cpp b/Plugins/org.mitk.gui.qt.ultrasound/src/internal/QmitkUltrasoundSupport.cpp
index 1d491333e2..fa7d24f1d9 100644
--- a/Plugins/org.mitk.gui.qt.ultrasound/src/internal/QmitkUltrasoundSupport.cpp
+++ b/Plugins/org.mitk.gui.qt.ultrasound/src/internal/QmitkUltrasoundSupport.cpp
@@ -1,697 +1,523 @@
/*===================================================================
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.
===================================================================*/
// Blueberry
#include
#include
-#include
//Mitk
#include
#include
#include
#include
#include
-#include
-#include
-#include "QmitkRegisterClasses.h"
-#include "QmitkRenderWindow.h"
-#include
-#include
// Qmitk
#include "QmitkUltrasoundSupport.h"
+
// Qt
#include
#include
#include
// Ultrasound
#include "mitkUSDevice.h"
#include "QmitkUSAbstractCustomWidget.h"
#include
#include
#include "usServiceReference.h"
#include "internal/org_mitk_gui_qt_ultrasound_Activator.h"
-#include "mitkNodePredicateDataType.h"
-#include
const std::string QmitkUltrasoundSupport::VIEW_ID = "org.mitk.views.ultrasoundsupport";
-void QmitkUltrasoundSupport::SetFocus()
-{
-}
-
-void QmitkUltrasoundSupport::CreateQtPartControl(QWidget *parent)
+QmitkUltrasoundSupport::QmitkUltrasoundSupport()
+ : m_Controls(nullptr), m_ControlCustomWidget(0), m_ControlBModeWidget(0),
+ m_ControlProbesWidget(0), m_ImageAlreadySetToNode(false),
+ m_CurrentImageWidth(0), m_CurrentImageHeight(0)
{
- //initialize timers
- m_UpdateTimer = new QTimer(this);
- m_RenderingTimer2d = new QTimer(this);
- m_RenderingTimer3d = new QTimer(this);
-
- // create GUI widgets from the Qt Designer's .ui file
- m_Controls.setupUi(parent);
-
- //load persistence data before connecting slots (so no slots are called in this phase...)
- LoadUISettings();
-
- //connect signals and slots...
- connect(m_Controls.m_DeviceManagerWidget, SIGNAL(NewDeviceButtonClicked()), this, SLOT(OnClickedAddNewDevice())); // Change Widget Visibilities
- connect(m_Controls.m_DeviceManagerWidget, SIGNAL(NewDeviceButtonClicked()), this->m_Controls.m_NewVideoDeviceWidget, SLOT(CreateNewDevice())); // Init NewDeviceWidget
- connect(m_Controls.m_ActiveVideoDevices, SIGNAL(ServiceSelectionChanged(us::ServiceReferenceU)), this, SLOT(OnChangedActiveDevice()));
- connect(m_Controls.m_RunImageTimer, SIGNAL(clicked()), this, SLOT(OnChangedActiveDevice()));
- connect(m_Controls.m_ShowImageStream, SIGNAL(clicked()), this, SLOT(OnChangedActiveDevice()));
- connect(m_Controls.m_NewVideoDeviceWidget, SIGNAL(Finished()), this, SLOT(OnNewDeviceWidgetDone())); // After NewDeviceWidget finished editing
- connect(m_Controls.m_FrameRatePipeline, SIGNAL(valueChanged(int)), this, SLOT(OnChangedFramerateLimit()));
- connect(m_Controls.m_FrameRate2d, SIGNAL(valueChanged(int)), this, SLOT(OnChangedFramerateLimit()));
- connect(m_Controls.m_FrameRate3d, SIGNAL(valueChanged(int)), this, SLOT(OnChangedFramerateLimit()));
- connect(m_Controls.m_FreezeButton, SIGNAL(clicked()), this, SLOT(OnClickedFreezeButton()));
- connect(m_UpdateTimer, SIGNAL(timeout()), this, SLOT(UpdateImage()));
- connect(m_RenderingTimer2d, SIGNAL(timeout()), this, SLOT(RenderImage2d()));
- connect(m_RenderingTimer3d, SIGNAL(timeout()), this, SLOT(RenderImage3d()));
- connect(m_Controls.m_Update2DView, SIGNAL(clicked()), this, SLOT(StartTimers()));
- connect(m_Controls.m_Update3DView, SIGNAL(clicked()), this, SLOT(StartTimers()));
- connect(m_Controls.m_DeviceManagerWidget, SIGNAL(EditDeviceButtonClicked(mitk::USDevice::Pointer)), this, SLOT(OnClickedEditDevice())); //Change Widget Visibilities
- connect(m_Controls.m_DeviceManagerWidget, SIGNAL(EditDeviceButtonClicked(mitk::USDevice::Pointer)), this->m_Controls.m_NewVideoDeviceWidget, SLOT(EditDevice(mitk::USDevice::Pointer)));
-
- // Initializations
- m_Controls.m_NewVideoDeviceWidget->setVisible(false);
- std::string filter = "(&(" + us::ServiceConstants::OBJECTCLASS() + "="
- + "org.mitk.services.UltrasoundDevice)("
- + mitk::USDevice::GetPropertyKeys().US_PROPKEY_ISACTIVE + "=true))";
- m_Controls.m_ActiveVideoDevices->Initialize(
- mitk::USDevice::GetPropertyKeys().US_PROPKEY_LABEL, filter);
- m_Controls.m_ActiveVideoDevices->SetAutomaticallySelectFirstEntry(true);
- m_FrameCounterPipeline = 0;
- m_FrameCounter2d = 0;
- m_FrameCounter3d = 0;
-
- m_Controls.tabWidget->setTabEnabled(1, false);
-}
+ ctkPluginContext* pluginContext = mitk::PluginActivator::GetContext();
-void QmitkUltrasoundSupport::CreateWindows()
-{
- auto pausViewer = GetSite()->GetWorkbenchWindow()->GetActivePage()->FindView("org.mitk.views.photoacoustics.pausviewer");
- if (pausViewer != nullptr)
+ if (pluginContext)
{
- m_PausViewerView = dynamic_cast(pausViewer.GetPointer());
- m_PausViewerView->SetPADataStorage(m_PADataStorage);
- m_PausViewerView->SetUSDataStorage(m_USDataStorage);
-
- m_PausViewerView->InitWindows();
- m_PausViewerView->SetUltrasoundReference(&m_PausViewerView);
- UpdateLevelWindows();
-
- m_ForceRequestUpdateAll = true;
+ // to be notified about service event of an USDevice
+ pluginContext->connectServiceListener(this, "OnDeciveServiceEvent",
+ QString::fromStdString("(" + us::ServiceConstants::OBJECTCLASS() + "=" + us_service_interface_iid() + ")"));
}
}
-void QmitkUltrasoundSupport::InitNewNode()
-{
- m_Node.push_back(nullptr);
- auto& Node = m_Node.back();
-
- Node = mitk::DataNode::New();
- Node->SetName("No Data received yet ...");
- //create a dummy image (gray values 0..255) for correct initialization of level window, etc.
- mitk::Image::Pointer dummyImage = mitk::ImageGenerator::GenerateRandomImage(100, 100, 1, 1, 1, 1, 1, 255, 0);
- Node->SetData(dummyImage);
- m_OldGeometry = dynamic_cast(dummyImage->GetGeometry());
-
- // Add to Control Datastorage
- this->GetDataStorage()->Add(Node);
-
- // Add to Display Datastorage
- if (m_Node.size() > 1)
- m_USDataStorage->Add(Node);
- else if (m_Node.size() == 1)
- m_PADataStorage->Add(Node);
-}
-
-void QmitkUltrasoundSupport::DestroyLastNode()
-{
- auto& Node = m_Node.back();
-
- // Remove from Control Datastorage
- this->GetDataStorage()->Remove(Node);
-
- // Remove from Display Datastorage
- if (m_Node.size() > 1)
- m_USDataStorage->Remove(Node);
- else if (m_Node.size() == 1)
- m_PADataStorage->Remove(Node);
-
- // clean up
- Node->ReleaseData();
- m_Node.pop_back();
-}
-
-void QmitkUltrasoundSupport::UpdateLevelWindows()
+QmitkUltrasoundSupport::~QmitkUltrasoundSupport()
{
- mitk::LevelWindow levelWindow;
-
- if (m_Node.size() > 1)
+ try
{
- for (unsigned int index = 0; index < m_AmountOfOutputs; ++index)
+ StoreUISettings();
+ StopTimers();
+
+ // Get all active devicesand deactivate them to prevent freeze
+ std::vector devices = this->m_Controls->m_ActiveVideoDevices->GetAllServices();
+ for (int i = 0; i < devices.size(); i++)
{
- m_Node.at(index)->GetLevelWindow(levelWindow);
- if (!m_curOutput.at(index)->IsEmpty())
- //levelWindow.SetWindowBounds(0, 4 * (index+1));
- levelWindow.SetToImageRange(m_curOutput.at(index));
- m_Node.at(index)->SetLevelWindow(levelWindow);
+ mitk::USDevice::Pointer device = devices[i];
+ if (device.IsNotNull() && device->GetIsActive())
+ {
+ device->Deactivate();
+ device->Disconnect();
+ }
}
}
- else if (m_Node.size() == 1)
+ catch (std::exception &e)
{
- m_Node.back()->GetLevelWindow(levelWindow);
- if (!m_curOutput.at(0)->IsEmpty())
- levelWindow.SetToImageRange(m_curOutput.at(0));
- m_Node.back()->SetLevelWindow(levelWindow);
+ MITK_ERROR << "Exception during call of destructor! Message: " << e.what();
}
}
-void QmitkUltrasoundSupport::SetColormap(mitk::DataNode::Pointer node, mitk::LookupTable::LookupTableType type)
+void QmitkUltrasoundSupport::SetFocus()
{
- // consider removing this, unused for now, and probably forever
+}
- mitk::LookupTable::Pointer lookupTable = mitk::LookupTable::New();
- mitk::LookupTableProperty::Pointer lookupTableProperty = mitk::LookupTableProperty::New();
- lookupTable->SetType(type);
- lookupTableProperty->SetLookupTable(lookupTable);
- node->SetProperty("LookupTable", lookupTableProperty);
+void QmitkUltrasoundSupport::CreateQtPartControl(QWidget *parent)
+{
+ //initialize timers
+ m_UpdateTimer = new QTimer(this);
+ m_RenderingTimer2d = new QTimer(this);
+ m_RenderingTimer3d = new QTimer(this);
+
+ // build up qt view, unless already done
+ if (!m_Controls)
+ {
+ // create GUI widgets from the Qt Designer's .ui file
+ m_Controls = new Ui::UltrasoundSupportControls;
+
+ // create GUI widgets from the Qt Designer's .ui file
+ m_Controls->setupUi(parent);
+
+ //load persistence data before connecting slots (so no slots are called in this phase...)
+ LoadUISettings();
+
+ //connect signals and slots...
+ connect(m_Controls->m_DeviceManagerWidget, SIGNAL(NewDeviceButtonClicked()), this, SLOT(OnClickedAddNewDevice())); // Change Widget Visibilities
+ connect(m_Controls->m_DeviceManagerWidget, SIGNAL(NewDeviceButtonClicked()), this->m_Controls->m_NewVideoDeviceWidget, SLOT(CreateNewDevice())); // Init NewDeviceWidget
+ connect(m_Controls->m_ActiveVideoDevices, SIGNAL(ServiceSelectionChanged(us::ServiceReferenceU)), this, SLOT(OnChangedActiveDevice()));
+ connect(m_Controls->m_RunImageTimer, SIGNAL(clicked()), this, SLOT(OnChangedActiveDevice()));
+ connect(m_Controls->m_ShowImageStream, SIGNAL(clicked()), this, SLOT(OnChangedActiveDevice()));
+ connect(m_Controls->m_NewVideoDeviceWidget, SIGNAL(Finished()), this, SLOT(OnNewDeviceWidgetDone())); // After NewDeviceWidget finished editing
+ connect(m_Controls->m_FrameRatePipeline, SIGNAL(valueChanged(int)), this, SLOT(OnChangedFramerateLimit()));
+ connect(m_Controls->m_FrameRate2d, SIGNAL(valueChanged(int)), this, SLOT(OnChangedFramerateLimit()));
+ connect(m_Controls->m_FrameRate3d, SIGNAL(valueChanged(int)), this, SLOT(OnChangedFramerateLimit()));
+ connect(m_Controls->m_FreezeButton, SIGNAL(clicked()), this, SLOT(OnClickedFreezeButton()));
+ connect(m_UpdateTimer, SIGNAL(timeout()), this, SLOT(UpdateImage()));
+ connect(m_RenderingTimer2d, SIGNAL(timeout()), this, SLOT(RenderImage2d()));
+ connect(m_RenderingTimer3d, SIGNAL(timeout()), this, SLOT(RenderImage3d()));
+ connect(m_Controls->m_Update2DView, SIGNAL(clicked()), this, SLOT(StartTimers()));
+ connect(m_Controls->m_Update3DView, SIGNAL(clicked()), this, SLOT(StartTimers()));
+ connect(m_Controls->m_DeviceManagerWidget, SIGNAL(EditDeviceButtonClicked(mitk::USDevice::Pointer)), this, SLOT(OnClickedEditDevice())); //Change Widget Visibilities
+ connect(m_Controls->m_DeviceManagerWidget, SIGNAL(EditDeviceButtonClicked(mitk::USDevice::Pointer)), this->m_Controls->m_NewVideoDeviceWidget, SLOT(EditDevice(mitk::USDevice::Pointer)));
+
+ // Initializations
+ m_Controls->m_NewVideoDeviceWidget->setVisible(false);
+ std::string filter = "(&(" + us::ServiceConstants::OBJECTCLASS() + "="
+ + "org.mitk.services.UltrasoundDevice)("
+ + mitk::USDevice::GetPropertyKeys().US_PROPKEY_ISACTIVE + "=true))";
+ m_Controls->m_ActiveVideoDevices->Initialize(
+ mitk::USDevice::GetPropertyKeys().US_PROPKEY_LABEL, filter);
+ m_Controls->m_ActiveVideoDevices->SetAutomaticallySelectFirstEntry(true);
+ m_FrameCounterPipeline = 0;
+ m_FrameCounter2d = 0;
+ m_FrameCounter3d = 0;
- mitk::RenderingModeProperty::Pointer renderingMode =
- dynamic_cast(node->GetProperty("Image Rendering.Mode"));
- renderingMode->SetValue(mitk::RenderingModeProperty::LOOKUPTABLE_LEVELWINDOW_COLOR);
+ m_Controls->tabWidget->setTabEnabled(1, false);
+ }
}
void QmitkUltrasoundSupport::OnClickedAddNewDevice()
{
- m_Controls.m_NewVideoDeviceWidget->setVisible(true);
- m_Controls.m_DeviceManagerWidget->setVisible(false);
- m_Controls.m_Headline->setText("Add New Video Device:");
- m_Controls.m_WidgetActiveDevices->setVisible(false);
+ m_Controls->m_NewVideoDeviceWidget->setVisible(true);
+ m_Controls->m_DeviceManagerWidget->setVisible(false);
+ m_Controls->m_Headline->setText("Add New Video Device:");
+ m_Controls->m_WidgetActiveDevices->setVisible(false);
}
void QmitkUltrasoundSupport::OnClickedEditDevice()
{
- m_Controls.m_NewVideoDeviceWidget->setVisible(true);
- m_Controls.m_DeviceManagerWidget->setVisible(false);
- m_Controls.m_WidgetActiveDevices->setVisible(false);
- m_Controls.m_Headline->setText("Edit Video Device:");
-}
-
-void QmitkUltrasoundSupport::UpdateAmountOfOutputs()
-{
- // Update the amount of Nodes; there should be one Node for every slide that is set. Note that we must check whether the slices are set,
- // just using the m_Image->dimension(3) will produce nullpointers on slices of the image that were not set
- bool isSet = true;
- m_AmountOfOutputs = 0;
- while (isSet) {
- isSet = m_Image->IsSliceSet(m_AmountOfOutputs);
- if (isSet)
- ++m_AmountOfOutputs;
- }
-
- // correct the amount of Nodes to display data
- while (m_Node.size() < m_AmountOfOutputs) {
- InitNewNode();
- }
- while (m_Node.size() > m_AmountOfOutputs) {
- DestroyLastNode();
- }
-
- // correct the amount of image outputs that we feed the nodes with
- while (m_curOutput.size() < m_AmountOfOutputs) {
- m_curOutput.push_back(mitk::Image::New());
-
- // initialize the slice images as 2d images with the size of m_Images
- unsigned int* dimOld = m_Image->GetDimensions();
- unsigned int dim[2] = { dimOld[0], dimOld[1] };
- m_curOutput.back()->Initialize(m_Image->GetPixelType(), 2, dim);
- }
- while (m_curOutput.size() > m_AmountOfOutputs) {
- m_curOutput.pop_back();
- }
+ m_Controls->m_NewVideoDeviceWidget->setVisible(true);
+ m_Controls->m_DeviceManagerWidget->setVisible(false);
+ m_Controls->m_WidgetActiveDevices->setVisible(false);
+ m_Controls->m_Headline->setText("Edit Video Device:");
}
void QmitkUltrasoundSupport::UpdateImage()
{
- if(m_Controls.m_ShowImageStream->isChecked())
- {
- m_Device->Modified();
- m_Device->Update();
- // Update device
-
- m_Image = m_Device->GetOutput();
- // get the Image data to display
- UpdateAmountOfOutputs();
- // create as many Nodes and Outputs as there are slices in m_Image
+ //Update device
+ m_Device->Modified();
+ m_Device->Update();
- if (m_AmountOfOutputs == 0)
- return;
- // if there is no image to be displayed, skip the rest of this method
-
- for (unsigned int index = 0; index < m_AmountOfOutputs; ++index)
+ //Only update the view if the image is shown
+ if (m_Controls->m_ShowImageStream->isChecked())
+ {
+ //Update data nodes
+ for (size_t i = 0; i < m_AmountOfOutputs; i++)
{
- if (m_curOutput.at(index)->GetDimension(0) != m_Image->GetDimension(0) ||
- m_curOutput.at(index)->GetDimension(1) != m_Image->GetDimension(1) ||
- m_curOutput.at(index)->GetDimension(2) != m_Image->GetDimension(2) ||
- m_curOutput.at(index)->GetPixelType() != m_Image->GetPixelType())
- {
- unsigned int* dimOld = m_Image->GetDimensions();
- unsigned int dim[2] = { dimOld[0], dimOld[1]};
- m_curOutput.at(index)->Initialize(m_Image->GetPixelType(), 2, dim);
- // if we switched image resolution or type the outputs must be reinitialized!
- }
-
- if (!m_Image->IsEmpty())
+ mitk::Image::Pointer curOutput = m_Device->GetOutput(i);
+ if (curOutput->IsEmpty())
{
- mitk::ImageReadAccessor inputReadAccessor(m_Image, m_Image->GetSliceData(index,0,0,nullptr,mitk::Image::ReferenceMemory));
- // just reference the slices, to get a small performance gain
- m_curOutput.at(index)->SetSlice(inputReadAccessor.GetData());
- m_curOutput.at(index)->GetGeometry()->SetIndexToWorldTransform(m_Image->GetSlicedGeometry()->GetIndexToWorldTransform());
- // Update the image Output with seperate slices
- }
-
- if (m_curOutput.at(index)->IsEmpty())
- {
- m_Node.at(index)->SetName("No Data received yet ...");
- // create a noise image for correct initialization of level window, etc.
+ m_Node.at(i)->SetName("No Data received yet ...");
+ //create a noise image for correct initialization of level window, etc.
mitk::Image::Pointer randomImage = mitk::ImageGenerator::GenerateRandomImage(32, 32, 1, 1, 1, 1, 1, 255, 0);
- m_Node.at(index)->SetData(randomImage);
- m_curOutput.at(index)->SetGeometry(randomImage->GetGeometry());
+ m_Node.at(i)->SetData(randomImage);
+ curOutput->SetGeometry(randomImage->GetGeometry());
}
else
{
- char name[30];
- sprintf(name, "US Viewing Stream - Image %d", index);
- m_Node.at(index)->SetName(name);
- m_Node.at(index)->SetData(m_curOutput.at(index));
- // set the name of the Output
+ std::stringstream nodeName;
+ nodeName << "US Viewing Stream - Image " << i;
+ m_Node.at(i)->SetName(nodeName.str());
+ m_Node.at(i)->SetData(curOutput);
+ m_Node.at(i)->Modified();
}
- }
-
- float eps = 0.000001f;
- // if the geometry changed: reinitialize the ultrasound image. we use the m_curOutput.at(0) to readjust the geometry
- if (((m_OldGeometry.IsNotNull()) &&
- (m_curOutput.at(0)->GetGeometry() != nullptr)) &&
- (
- (abs(m_OldGeometry->GetSpacing()[0] - m_curOutput.at(0)->GetGeometry()->GetSpacing()[0]) > eps )||
- (abs(m_OldGeometry->GetSpacing()[1] - m_curOutput.at(0)->GetGeometry()->GetSpacing()[1]) > eps )||
- (abs(m_OldGeometry->GetCenter()[0] - m_curOutput.at(0)->GetGeometry()->GetCenter()[0]) > eps) ||
- (abs(m_OldGeometry->GetCenter()[1] - m_curOutput.at(0)->GetGeometry()->GetCenter()[1]) > eps) ||
- m_ForceRequestUpdateAll))
- {
- MITK_INFO << "now";
- mitk::IRenderWindowPart* renderWindow = this->GetRenderWindowPart();
- if ((renderWindow != nullptr) && (m_curOutput.at(0)->GetTimeGeometry()->IsValid()) && (m_Controls.m_ShowImageStream->isChecked()))
+ // if the geometry changed: reinitialize the ultrasound image
+ if ((i==0) && (m_OldGeometry.IsNotNull()) &&
+ (curOutput->GetGeometry() != NULL) &&
+ (!mitk::Equal(m_OldGeometry.GetPointer(), curOutput->GetGeometry(), 0.0001, false))
+ )
{
- renderWindow->GetRenderingManager()->InitializeViews(
- m_curOutput.at(0)->GetGeometry(), mitk::RenderingManager::REQUEST_UPDATE_ALL, true);
- renderWindow->GetRenderingManager()->RequestUpdateAll();
+ mitk::IRenderWindowPart* renderWindow = this->GetRenderWindowPart();
+ if ((renderWindow != NULL) && (curOutput->GetTimeGeometry()->IsValid()) && (m_Controls->m_ShowImageStream->isChecked()))
+ {
+ renderWindow->GetRenderingManager()->InitializeViews(
+ curOutput->GetGeometry(), mitk::RenderingManager::REQUEST_UPDATE_ALL, true);
+ renderWindow->GetRenderingManager()->RequestUpdateAll();
+ }
+ m_CurrentImageWidth = curOutput->GetDimension(0);
+ m_CurrentImageHeight = curOutput->GetDimension(1);
+ m_OldGeometry = dynamic_cast(curOutput->GetGeometry());
}
- m_CurrentImageWidth = m_curOutput.at(0)->GetDimension(0);
- m_CurrentImageHeight = m_curOutput.at(0)->GetDimension(1);
- m_OldGeometry = dynamic_cast(m_curOutput.at(0)->GetGeometry());
- UpdateLevelWindows();
- m_ForceRequestUpdateAll = false;
}
}
//Update frame counter
m_FrameCounterPipeline++;
if (m_FrameCounterPipeline >= 10)
{
- // compute framerate of pipeline update
+ //compute framerate of pipeline update
int nMilliseconds = m_Clock.restart();
int fps = 10000.0f / (nMilliseconds);
m_FPSPipeline = fps;
m_FrameCounterPipeline = 0;
- // display lowest framerate in UI
+ //display lowest framerate in UI
int lowestFPS = m_FPSPipeline;
- if (m_Controls.m_Update2DView->isChecked() && (m_FPS2d < lowestFPS)) { lowestFPS = m_FPS2d; }
- if (m_Controls.m_Update3DView->isChecked() && (m_FPS3d < lowestFPS)) { lowestFPS = m_FPS3d; }
- m_Controls.m_FramerateLabel->setText("Current Framerate: " + QString::number(lowestFPS) + " FPS");
+ if (m_Controls->m_Update2DView->isChecked() && (m_FPS2d < lowestFPS)) { lowestFPS = m_FPS2d; }
+ if (m_Controls->m_Update3DView->isChecked() && (m_FPS3d < lowestFPS)) { lowestFPS = m_FPS3d; }
+ m_Controls->m_FramerateLabel->setText("Current Framerate: " + QString::number(lowestFPS) + " FPS");
}
}
void QmitkUltrasoundSupport::RenderImage2d()
{
- if (!m_Controls.m_Update2DView->isChecked())
+ if (!m_Controls->m_Update2DView->isChecked())
return;
- if (m_PausViewerView != nullptr)
- {
- auto renderingManager = mitk::RenderingManager::GetInstance();
- renderingManager->RequestUpdate(m_PausViewerView->GetPARenderWindow());
- renderingManager->RequestUpdate(m_PausViewerView->GetUSRenderWindow());
- }
- else
- {
- CreateWindows(); // try to check whether the PausViwer has been opened by now
- }
-
- //mitk::IRenderWindowPart* renderWindow = this->GetRenderWindowPart();
- //renderWindow->GetRenderingManager()->RequestUpdate(mitk::BaseRenderer::GetInstance(mitk::BaseRenderer::GetRenderWindowByName("stdmulti.widget1"))->GetRenderWindow());
- // TODO: figure out how to proceed with the standard display
- //this->RequestRenderWindowUpdate(mitk::RenderingManager::REQUEST_UPDATE_2DWINDOWS);
-
+ this->RequestRenderWindowUpdate(mitk::RenderingManager::REQUEST_UPDATE_2DWINDOWS);
m_FrameCounter2d++;
if (m_FrameCounter2d >= 10)
{
- // compute framerate of 2d render window update
+ //compute framerate of 2d render window update
int nMilliseconds = m_Clock2d.restart();
int fps = 10000.0f / (nMilliseconds);
m_FPS2d = fps;
m_FrameCounter2d = 0;
}
}
void QmitkUltrasoundSupport::RenderImage3d()
{
- if (!m_Controls.m_Update3DView->isChecked())
+ if (!m_Controls->m_Update3DView->isChecked())
return;
this->RequestRenderWindowUpdate(mitk::RenderingManager::REQUEST_UPDATE_3DWINDOWS);
m_FrameCounter3d++;
if (m_FrameCounter3d >= 10)
{
- // compute framerate of 2d render window update
+ //compute framerate of 2d render window update
int nMilliseconds = m_Clock3d.restart();
int fps = 10000.0f / (nMilliseconds);
m_FPS3d = fps;
m_FrameCounter3d = 0;
}
}
void QmitkUltrasoundSupport::OnChangedFramerateLimit()
{
StopTimers();
- int intervalPipeline = (1000 / m_Controls.m_FrameRatePipeline->value());
- int interval2D = (1000 / m_Controls.m_FrameRate2d->value());
- int interval3D = (1000 / m_Controls.m_FrameRate3d->value());
+ int intervalPipeline = (1000 / m_Controls->m_FrameRatePipeline->value());
+ int interval2D = (1000 / m_Controls->m_FrameRate2d->value());
+ int interval3D = (1000 / m_Controls->m_FrameRate3d->value());
SetTimerIntervals(intervalPipeline, interval2D, interval3D);
StartTimers();
}
void QmitkUltrasoundSupport::OnClickedFreezeButton()
{
if (m_Device.IsNull())
{
MITK_WARN("UltrasoundSupport") << "Freeze button clicked though no device is selected.";
return;
}
if (m_Device->GetIsFreezed())
{
m_Device->SetIsFreezed(false);
- m_Controls.m_FreezeButton->setText("Freeze");
+ m_Controls->m_FreezeButton->setText("Freeze");
}
else
{
m_Device->SetIsFreezed(true);
- m_Controls.m_FreezeButton->setText("Start Viewing Again");
+ m_Controls->m_FreezeButton->setText("Start Viewing Again");
}
}
void QmitkUltrasoundSupport::OnChangedActiveDevice()
{
- //clean up, delete nodes and stop timer
+ //clean up and stop timer
StopTimers();
this->RemoveControlWidgets();
- for (auto& Node : m_Node)
+ for (size_t j = 0; j < m_Node.size(); j++)
{
- this->GetDataStorage()->Remove(Node);
- Node->ReleaseData();
+ this->GetDataStorage()->Remove(m_Node.at(j));
+ m_Node.at(j)->ReleaseData();
}
m_Node.clear();
-
- // disconnect from the PausViewer
- m_PausViewerView = nullptr;
-
//get current device, abort if it is invalid
- m_Device = m_Controls.m_ActiveVideoDevices->GetSelectedService();
+ m_Device = m_Controls->m_ActiveVideoDevices->GetSelectedService();
if (m_Device.IsNull())
{
- m_Controls.tabWidget->setTabEnabled(1, false);
+ m_Controls->tabWidget->setTabEnabled(1, false);
return;
}
+ m_AmountOfOutputs = m_Device->GetNumberOfIndexedOutputs();
+ // clear data storage, create new nodes and add
+ for (size_t i = 0; i < m_AmountOfOutputs; i++)
+ {
+ mitk::DataNode::Pointer currentNode = mitk::DataNode::New();
+ std::stringstream nodeName;
+ nodeName << "US Viewing Stream - Image " << i;
+ currentNode->SetName(nodeName.str());
+ //create a dummy image (gray values 0..255) for correct initialization of level window, etc.
+ mitk::Image::Pointer dummyImage = mitk::ImageGenerator::GenerateRandomImage(100, 100, 1, 1, 1, 1, 1, 255, 0);
+ currentNode->SetData(dummyImage);
+ m_OldGeometry = dynamic_cast(dummyImage->GetGeometry());
+ m_Node.push_back(currentNode);
+ //show node if the option is enabled
+ if (m_Controls->m_ShowImageStream->isChecked())
+ {
+ this->GetDataStorage()->Add(m_Node.at(i));
+ }
+ }
//create the widgets for this device and enable the widget tab
this->CreateControlWidgets();
- m_Controls.tabWidget->setTabEnabled(1, true);
+ m_Controls->tabWidget->setTabEnabled(1, true);
//start timer
- if (m_Controls.m_RunImageTimer->isChecked())
+ if (m_Controls->m_RunImageTimer->isChecked())
{
- int intervalPipeline = (1000 / m_Controls.m_FrameRatePipeline->value());
- int interval2D = (1000 / m_Controls.m_FrameRate2d->value());
- int interval3D = (1000 / m_Controls.m_FrameRate3d->value());
+ int intervalPipeline = (1000 / m_Controls->m_FrameRatePipeline->value());
+ int interval2D = (1000 / m_Controls->m_FrameRate2d->value());
+ int interval3D = (1000 / m_Controls->m_FrameRate3d->value());
SetTimerIntervals(intervalPipeline, interval2D, interval3D);
StartTimers();
- m_Controls.m_TimerWidget->setEnabled(true);
+ m_Controls->m_TimerWidget->setEnabled(true);
}
else
{
- m_Controls.m_TimerWidget->setEnabled(false);
+ m_Controls->m_TimerWidget->setEnabled(false);
}
-
- // connect to PausViewer and Set it up
- CreateWindows();
}
void QmitkUltrasoundSupport::OnNewDeviceWidgetDone()
{
- m_Controls.m_NewVideoDeviceWidget->setVisible(false);
- m_Controls.m_DeviceManagerWidget->setVisible(true);
- m_Controls.m_Headline->setText("Ultrasound Devices:");
- m_Controls.m_WidgetActiveDevices->setVisible(true);
+ m_Controls->m_NewVideoDeviceWidget->setVisible(false);
+ m_Controls->m_DeviceManagerWidget->setVisible(true);
+ m_Controls->m_Headline->setText("Ultrasound Devices:");
+ m_Controls->m_WidgetActiveDevices->setVisible(true);
}
void QmitkUltrasoundSupport::CreateControlWidgets()
{
- m_ControlProbesWidget = new QmitkUSControlsProbesWidget(m_Device->GetControlInterfaceProbes(), m_Controls.m_ToolBoxControlWidgets);
- m_Controls.probesWidgetContainer->addWidget(m_ControlProbesWidget);
+ m_ControlProbesWidget = new QmitkUSControlsProbesWidget(m_Device->GetControlInterfaceProbes(), m_Controls->m_ToolBoxControlWidgets);
+ m_Controls->probesWidgetContainer->addWidget(m_ControlProbesWidget);
// create b mode widget for current device
- m_ControlBModeWidget = new QmitkUSControlsBModeWidget(m_Device->GetControlInterfaceBMode(), m_Controls.m_ToolBoxControlWidgets);
-
- if (m_Device->GetControlInterfaceBMode())
+ m_ControlBModeWidget = new QmitkUSControlsBModeWidget(m_Device->GetControlInterfaceBMode(), m_Controls->m_ToolBoxControlWidgets);
+ m_Controls->m_ToolBoxControlWidgets->addItem(m_ControlBModeWidget, "B Mode Controls");
+ if (!m_Device->GetControlInterfaceBMode())
{
- m_Controls.m_ToolBoxControlWidgets->addItem(m_ControlBModeWidget, "B Mode Controls");
- //m_Controls.m_ToolBoxControlWidgets->setItemEnabled(m_Controls.m_ToolBoxControlWidgets->count() - 1, false);
+ m_Controls->m_ToolBoxControlWidgets->setItemEnabled(m_Controls->m_ToolBoxControlWidgets->count() - 1, false);
}
// create doppler widget for current device
- m_ControlDopplerWidget = new QmitkUSControlsDopplerWidget(m_Device->GetControlInterfaceDoppler(), m_Controls.m_ToolBoxControlWidgets);
-
- if (m_Device->GetControlInterfaceDoppler())
+ m_ControlDopplerWidget = new QmitkUSControlsDopplerWidget(m_Device->GetControlInterfaceDoppler(), m_Controls->m_ToolBoxControlWidgets);
+ m_Controls->m_ToolBoxControlWidgets->addItem(m_ControlDopplerWidget, "Doppler Controls");
+ if (!m_Device->GetControlInterfaceDoppler())
{
- m_Controls.m_ToolBoxControlWidgets->addItem(m_ControlDopplerWidget, "Doppler Controls");
- //m_Controls.m_ToolBoxControlWidgets->setItemEnabled(m_Controls.m_ToolBoxControlWidgets->count() - 1, false);
+ m_Controls->m_ToolBoxControlWidgets->setItemEnabled(m_Controls->m_ToolBoxControlWidgets->count() - 1, false);
}
ctkPluginContext* pluginContext = mitk::PluginActivator::GetContext();
if (pluginContext)
{
std::string filter = "(org.mitk.services.UltrasoundCustomWidget.deviceClass=" + m_Device->GetDeviceClass() + ")";
QString interfaceName = QString::fromStdString(us_service_interface_iid());
m_CustomWidgetServiceReference = pluginContext->getServiceReferences(interfaceName, QString::fromStdString(filter));
if (m_CustomWidgetServiceReference.size() > 0)
{
m_ControlCustomWidget = pluginContext->getService
- (m_CustomWidgetServiceReference.at(0))->CloneForQt(m_Controls.tab2);
+ (m_CustomWidgetServiceReference.at(0))->CloneForQt(m_Controls->tab2);
m_ControlCustomWidget->SetDevice(m_Device);
- m_Controls.m_ToolBoxControlWidgets->addItem(m_ControlCustomWidget, "Custom Controls");
+ m_Controls->m_ToolBoxControlWidgets->addItem(m_ControlCustomWidget, "Custom Controls");
}
else
{
- m_Controls.m_ToolBoxControlWidgets->addItem(new QWidget(m_Controls.m_ToolBoxControlWidgets), "Custom Controls");
- m_Controls.m_ToolBoxControlWidgets->setItemEnabled(m_Controls.m_ToolBoxControlWidgets->count() - 1, false);
+ m_Controls->m_ToolBoxControlWidgets->addItem(new QWidget(m_Controls->m_ToolBoxControlWidgets), "Custom Controls");
+ m_Controls->m_ToolBoxControlWidgets->setItemEnabled(m_Controls->m_ToolBoxControlWidgets->count() - 1, false);
}
}
// select first enabled control widget
- for (int n = 0; n < m_Controls.m_ToolBoxControlWidgets->count(); ++n)
+ for (int n = 0; n < m_Controls->m_ToolBoxControlWidgets->count(); ++n)
{
- if (m_Controls.m_ToolBoxControlWidgets->isItemEnabled(n))
+ if (m_Controls->m_ToolBoxControlWidgets->isItemEnabled(n))
{
- m_Controls.m_ToolBoxControlWidgets->setCurrentIndex(n);
+ m_Controls->m_ToolBoxControlWidgets->setCurrentIndex(n);
break;
}
}
}
void QmitkUltrasoundSupport::RemoveControlWidgets()
{
if (!m_ControlProbesWidget) { return; } //widgets do not exist... nothing to do
// remove all control widgets from the tool box widget
- while (m_Controls.m_ToolBoxControlWidgets->count() > 0)
+ while (m_Controls->m_ToolBoxControlWidgets->count() > 0)
{
- m_Controls.m_ToolBoxControlWidgets->removeItem(0);
+ m_Controls->m_ToolBoxControlWidgets->removeItem(0);
}
// remove probes widget (which is not part of the tool box widget)
- m_Controls.probesWidgetContainer->removeWidget(m_ControlProbesWidget);
+ m_Controls->probesWidgetContainer->removeWidget(m_ControlProbesWidget);
delete m_ControlProbesWidget;
m_ControlProbesWidget = 0;
delete m_ControlBModeWidget;
m_ControlBModeWidget = 0;
delete m_ControlDopplerWidget;
m_ControlDopplerWidget = 0;
// delete custom widget if it is present
if (m_ControlCustomWidget)
{
ctkPluginContext* pluginContext = mitk::PluginActivator::GetContext();
delete m_ControlCustomWidget; m_ControlCustomWidget = 0;
if (m_CustomWidgetServiceReference.size() > 0)
{
pluginContext->ungetService(m_CustomWidgetServiceReference.at(0));
}
}
}
void QmitkUltrasoundSupport::OnDeciveServiceEvent(const ctkServiceEvent event)
{
- if (m_Device.IsNull() || event.getType() != static_cast(us::ServiceEvent::MODIFIED))
+ if (m_Device.IsNull() || event.getType() != us::ServiceEvent::MODIFIED)
{
return;
}
ctkServiceReference service = event.getServiceReference();
if (m_Device->GetManufacturer() != service.getProperty(QString::fromStdString(mitk::USDevice::GetPropertyKeys().US_PROPKEY_MANUFACTURER)).toString().toStdString()
&& m_Device->GetName() != service.getProperty(QString::fromStdString(mitk::USDevice::GetPropertyKeys().US_PROPKEY_NAME)).toString().toStdString())
{
return;
}
if (!m_Device->GetIsActive() && m_UpdateTimer->isActive())
{
StopTimers();
}
if (m_CurrentDynamicRange != service.getProperty(QString::fromStdString(mitk::USDevice::GetPropertyKeys().US_PROPKEY_BMODE_DYNAMIC_RANGE)).toDouble())
{
m_CurrentDynamicRange = service.getProperty(QString::fromStdString(mitk::USDevice::GetPropertyKeys().US_PROPKEY_BMODE_DYNAMIC_RANGE)).toDouble();
// update level window for the current dynamic range
mitk::LevelWindow levelWindow;
- for (auto& Node : m_Node)
- {
- Node->GetLevelWindow(levelWindow);
- levelWindow.SetAuto(m_Image, true, true);
- levelWindow.SetWindowBounds(55, 125,true);
- Node->SetLevelWindow(levelWindow);
- }
- }
-}
-
-QmitkUltrasoundSupport::QmitkUltrasoundSupport()
- : m_ControlCustomWidget(0), m_ControlBModeWidget(0),
- m_ControlProbesWidget(0), m_ImageAlreadySetToNode(false),
- m_CurrentImageWidth(0), m_CurrentImageHeight(0), m_AmountOfOutputs(0),
- m_PADataStorage(mitk::StandaloneDataStorage::New()), m_USDataStorage(mitk::StandaloneDataStorage::New()), m_ForceRequestUpdateAll(false)
-{
- ctkPluginContext* pluginContext = mitk::PluginActivator::GetContext();
-
- if (pluginContext)
- {
- // to be notified about service event of an USDevice
- pluginContext->connectServiceListener(this, "OnDeciveServiceEvent",
- QString::fromStdString("(" + us::ServiceConstants::OBJECTCLASS() + "=" + us_service_interface_iid() + ")"));
- }
-}
-
-QmitkUltrasoundSupport::~QmitkUltrasoundSupport()
-{
- try
- {
- StoreUISettings();
- StopTimers();
-
- // Get all active devicesand deactivate them to prevent freeze
- for (auto device : this->m_Controls.m_ActiveVideoDevices->GetAllServices())
- {
- if (device != nullptr && device->GetIsActive())
- {
- device->Deactivate();
- device->Disconnect();
- }
- }
- }
- catch (std::exception &e)
- {
- MITK_ERROR << "Exception during call of destructor! Message: " << e.what();
+ m_Node.at(0)->GetLevelWindow(levelWindow);
+ levelWindow.SetAuto(m_curOutput.at(0), true, true);
+ m_Node.at(0)->SetLevelWindow(levelWindow);
}
}
void QmitkUltrasoundSupport::StoreUISettings()
{
QSettings settings;
settings.beginGroup(QString::fromStdString(VIEW_ID));
- settings.setValue("DisplayImage", QVariant(m_Controls.m_ShowImageStream->isChecked()));
- settings.setValue("RunImageTimer", QVariant(m_Controls.m_RunImageTimer->isChecked()));
- settings.setValue("Update2DView", QVariant(m_Controls.m_Update2DView->isChecked()));
- settings.setValue("Update3DView", QVariant(m_Controls.m_Update3DView->isChecked()));
- settings.setValue("UpdateRatePipeline", QVariant(m_Controls.m_FrameRatePipeline->value()));
- settings.setValue("UpdateRate2d", QVariant(m_Controls.m_FrameRate2d->value()));
- settings.setValue("UpdateRate3d", QVariant(m_Controls.m_FrameRate3d->value()));
+ settings.setValue("DisplayImage", QVariant(m_Controls->m_ShowImageStream->isChecked()));
+ settings.setValue("RunImageTimer", QVariant(m_Controls->m_RunImageTimer->isChecked()));
+ settings.setValue("Update2DView", QVariant(m_Controls->m_Update2DView->isChecked()));
+ settings.setValue("Update3DView", QVariant(m_Controls->m_Update3DView->isChecked()));
+ settings.setValue("UpdateRatePipeline", QVariant(m_Controls->m_FrameRatePipeline->value()));
+ settings.setValue("UpdateRate2d", QVariant(m_Controls->m_FrameRate2d->value()));
+ settings.setValue("UpdateRate3d", QVariant(m_Controls->m_FrameRate3d->value()));
settings.endGroup();
}
void QmitkUltrasoundSupport::LoadUISettings()
{
QSettings settings;
settings.beginGroup(QString::fromStdString(VIEW_ID));
- m_Controls.m_ShowImageStream->setChecked(settings.value("DisplayImage", true).toBool());
- m_Controls.m_RunImageTimer->setChecked(settings.value("RunImageTimer", true).toBool());
- m_Controls.m_Update2DView->setChecked(settings.value("Update2DView", true).toBool());
- m_Controls.m_Update3DView->setChecked(settings.value("Update3DView", true).toBool());
- m_Controls.m_FrameRatePipeline->setValue(settings.value("UpdateRatePipeline", 50).toInt());
- m_Controls.m_FrameRate2d->setValue(settings.value("UpdateRate2d", 20).toInt());
- m_Controls.m_FrameRate3d->setValue(settings.value("UpdateRate3d", 5).toInt());
+ m_Controls->m_ShowImageStream->setChecked(settings.value("DisplayImage", true).toBool());
+ m_Controls->m_RunImageTimer->setChecked(settings.value("RunImageTimer", true).toBool());
+ m_Controls->m_Update2DView->setChecked(settings.value("Update2DView", true).toBool());
+ m_Controls->m_Update3DView->setChecked(settings.value("Update3DView", true).toBool());
+ m_Controls->m_FrameRatePipeline->setValue(settings.value("UpdateRatePipeline", 50).toInt());
+ m_Controls->m_FrameRate2d->setValue(settings.value("UpdateRate2d", 20).toInt());
+ m_Controls->m_FrameRate3d->setValue(settings.value("UpdateRate3d", 5).toInt());
settings.endGroup();
}
void QmitkUltrasoundSupport::StartTimers()
{
m_UpdateTimer->start();
- if (m_Controls.m_Update2DView->isChecked()) { m_RenderingTimer2d->start(); }
- if (m_Controls.m_Update3DView->isChecked()) { m_RenderingTimer3d->start(); }
+ if (m_Controls->m_Update2DView->isChecked()) { m_RenderingTimer2d->start(); }
+ if (m_Controls->m_Update3DView->isChecked()) { m_RenderingTimer3d->start(); }
}
void QmitkUltrasoundSupport::StopTimers()
{
m_UpdateTimer->stop();
m_RenderingTimer2d->stop();
m_RenderingTimer3d->stop();
}
void QmitkUltrasoundSupport::SetTimerIntervals(int intervalPipeline, int interval2D, int interval3D)
{
m_UpdateTimer->setInterval(intervalPipeline);
m_RenderingTimer2d->setInterval(interval2D);
m_RenderingTimer3d->setInterval(interval3D);
}
diff --git a/Plugins/org.mitk.gui.qt.ultrasound/src/internal/QmitkUltrasoundSupport.h b/Plugins/org.mitk.gui.qt.ultrasound/src/internal/QmitkUltrasoundSupport.h
index a404b8851d..9b2b817390 100644
--- a/Plugins/org.mitk.gui.qt.ultrasound/src/internal/QmitkUltrasoundSupport.h
+++ b/Plugins/org.mitk.gui.qt.ultrasound/src/internal/QmitkUltrasoundSupport.h
@@ -1,186 +1,174 @@
/*===================================================================
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 QmitkUltrasoundSupport_h
#define QmitkUltrasoundSupport_h
#include
#include
#include
#include
#include "ui_QmitkUltrasoundSupportControls.h"
#include "QmitkUSAbstractCustomWidget.h"
#include "QmitkUSControlsBModeWidget.h"
#include "QmitkUSControlsDopplerWidget.h"
#include "QmitkUSControlsProbesWidget.h"
#include
#include "QmitkRenderWindow.h"
#include
#include
#include
-#include
#include
#include
/*!
\brief UltrasoundSupport
This plugin provides functionality to manage Ultrasound devices, create video devices and to view device images.
\ingroup ${plugin_target}_internal
*/
class QmitkUltrasoundSupport : public QmitkAbstractView
{
// this is needed for all Qt objects that should have a Qt meta-object
// (everything that derives from QObject and wants to have signal/slots)
Q_OBJECT
public:
virtual void SetFocus() override;
static const std::string VIEW_ID;
virtual void CreateQtPartControl(QWidget *parent) override;
QmitkUltrasoundSupport();
virtual ~QmitkUltrasoundSupport();
public slots:
/*
* \brief This is called when the newDeviceWidget is closed
*/
void OnNewDeviceWidgetDone();
protected slots:
void OnClickedAddNewDevice();
void OnChangedFramerateLimit();
void OnClickedEditDevice();
/*
*\brief Called, when the selection in the list of the active devices changes.
*/
void OnChangedActiveDevice();
void OnClickedFreezeButton();
void OnDeciveServiceEvent(const ctkServiceEvent event);
/*
* \brief This is the main imaging loop that updates the image and is called regularily during the imaging process
*/
void UpdateImage();
void RenderImage2d();
void RenderImage3d();
void StartTimers();
void StopTimers();
protected:
void CreateControlWidgets();
void RemoveControlWidgets();
- void CreateWindows();
-
- QmitkPAUSViewerView* m_PausViewerView;
-
- Ui::UltrasoundSupportControls m_Controls;
+ Ui::UltrasoundSupportControls* m_Controls;
QmitkUSAbstractCustomWidget* m_ControlCustomWidget;
QmitkUSControlsBModeWidget* m_ControlBModeWidget;
QmitkUSControlsDopplerWidget* m_ControlDopplerWidget;
QmitkUSControlsProbesWidget* m_ControlProbesWidget;
bool m_ImageAlreadySetToNode;
unsigned int m_CurrentImageWidth;
unsigned int m_CurrentImageHeight;
/** Keeps track of the amount of output Nodes*/
unsigned int m_AmountOfOutputs;
- mitk::StandaloneDataStorage::Pointer m_PADataStorage;
- mitk::StandaloneDataStorage::Pointer m_USDataStorage;
-
/** The device that is currently used to aquire images */
mitk::USDevice::Pointer m_Device;
void SetTimerIntervals(int intervalPipeline, int interval2D, int interval3D);
/** This timer triggers periodic updates to the pipeline */
QTimer* m_UpdateTimer;
QTimer* m_RenderingTimer2d;
QTimer* m_RenderingTimer3d;
/** These clocks are used to compute the framerate in the methods DisplayImage(),RenderImage2d() and RenderImage3d(). */
QTime m_Clock;
QTime m_Clock2d;
QTime m_Clock3d;
/** A counter to comute the framerate. */
int m_FrameCounterPipeline;
int m_FrameCounter2d;
int m_FrameCounter3d;
int m_FPSPipeline, m_FPS2d, m_FPS3d;
/** Stores the properties of some QWidgets (and the tool storage file name) to QSettings.*/
void StoreUISettings();
/** Loads the properties of some QWidgets (and the tool storage file name) from QSettings.*/
void LoadUISettings();
/** The nodes that we feed images into.*/
std::vector m_Node;
/** Adds a new node to the m_Nodes vector*/
void InitNewNode();
/** Destroys the last node in the m_Nodes vector */
void DestroyLastNode();
/** Checks the amount of slices in the image from the USDevice and creates as many Nodes as there are slices */
void UpdateAmountOfOutputs();
/** This function just checks how many nodes there are currently and sets the laser image to a jet transparent colormap. */
void UpdateLevelWindows();
bool m_ForceRequestUpdateAll;
void SetColormap(mitk::DataNode::Pointer node, mitk::LookupTable::LookupTableType type);
- /** The image that holds all data given by the USDevice.*/
- mitk::Image::Pointer m_Image;
-
-
/** The seperated slices from m_Image */
std::vector m_curOutput;
/** The old geometry of m_Image. It is needed to check if the geometry changed (e.g. because
* the zoom factor was modified) and the image needs to be reinitialized. */
mitk::SlicedGeometry3D::Pointer m_OldGeometry;
QList m_CustomWidgetServiceReference;
double m_CurrentDynamicRange;
};
#endif // UltrasoundSupport_h