diff --git a/Modules/PhotoacousticsAlgorithms/Algorithms/mitkPhotoacousticBeamformingDASFilter.cpp b/Modules/PhotoacousticsAlgorithms/Algorithms/mitkPhotoacousticBeamformingDASFilter.cpp new file mode 100644 index 0000000000..d4b36b7802 --- /dev/null +++ b/Modules/PhotoacousticsAlgorithms/Algorithms/mitkPhotoacousticBeamformingDASFilter.cpp @@ -0,0 +1,120 @@ +/*=================================================================== + +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 "mitkPhotoacousticBeamformingDASFilter.h" +#include "mitkProperties.h" +#include "mitkImageReadAccessor.h" + +#include + + +mitk::BeamformingDASFilter::BeamformingDASFilter() : m_OutputData(nullptr), m_InputData(nullptr) +{ + this->SetNumberOfIndexedInputs(1); + this->SetNumberOfRequiredInputs(1); + + m_Conf.Pitch = 0.0003; + m_Conf.SpeedOfSound = 1540; + m_Conf.SamplesPerLine = 2048; + m_Conf.ReconstructionLines = 128; + m_Conf.RecordTime = 0.00006; + m_Conf.TransducerElements = 128; +} + +mitk::BeamformingDASFilter::~BeamformingDASFilter() +{ +} + +void mitk::BeamformingDASFilter::GenerateInputRequestedRegion() +{ + Superclass::GenerateInputRequestedRegion(); + + mitk::Image* output = this->GetOutput(); + mitk::Image* input = const_cast< mitk::Image * > (this->GetInput()); + if (!output->IsInitialized()) + { + return; + } + + input->SetRequestedRegionToLargestPossibleRegion(); + + //GenerateTimeInInputRegion(output, input); +} + +void mitk::BeamformingDASFilter::GenerateOutputInformation() +{ + mitk::Image::ConstPointer input = this->GetInput(); + mitk::Image::Pointer output = this->GetOutput(); + + if ((output->IsInitialized()) && (this->GetMTime() <= m_TimeOfHeaderInitialization.GetMTime())) + return; + + itkDebugMacro(<< "GenerateOutputInformation()"); + + unsigned int dim[] = { m_Conf.ReconstructionLines, m_Conf.SamplesPerLine, input->GetDimension(2) }; + output->Initialize(mitk::MakeScalarPixelType(), 3, dim); + + mitk::Vector3D spacing; + spacing[0] = m_Conf.Pitch * m_Conf.TransducerElements * 1000 / m_Conf.ReconstructionLines; + spacing[1] = m_Conf.RecordTime * m_Conf.SpeedOfSound / 2 * 1000 / m_Conf.SamplesPerLine; + spacing[2] = 1; + + output->GetGeometry()->SetSpacing(spacing); + output->GetGeometry()->Modified(); + output->SetPropertyList(input->GetPropertyList()->Clone()); + + m_TimeOfHeaderInitialization.Modified(); +} + + +void mitk::BeamformingDASFilter::GenerateData() +{ + mitk::Image::ConstPointer input = this->GetInput(); + mitk::Image::Pointer output = this->GetOutput(); + + if (!output->IsInitialized()) + { + return; + } + + for (int i = 0; i < input->GetDimension(2); ++i) // seperate Slices should get Beamforming seperately applied + { + mitk::ImageReadAccessor inputReadAccessor(input, input->GetSliceData(i)); + m_InputData = (double*)inputReadAccessor.GetData(); + m_OutputData = new double[m_Conf.ReconstructionLines*m_Conf.SamplesPerLine]; + + for (int a = 0; a < m_Conf.ReconstructionLines; ++a) + { + for (int b = 0; b < m_Conf.SamplesPerLine; ++b) + { + m_OutputData[a*m_Conf.SamplesPerLine + b] = 1; + } + } + + output->SetSlice(m_OutputData, i); + + delete[] m_OutputData; + m_OutputData = nullptr; + m_InputData = nullptr; + } + m_TimeOfHeaderInitialization.Modified(); +} + +void mitk::BeamformingDASFilter::Configure(beamformingSettings settings) +{ + m_Conf = settings; +} \ No newline at end of file diff --git a/Modules/PhotoacousticsAlgorithms/Algorithms/mitkPhotoacousticBeamformingDASFilter.h b/Modules/PhotoacousticsAlgorithms/Algorithms/mitkPhotoacousticBeamformingDASFilter.h new file mode 100644 index 0000000000..b33be6f510 --- /dev/null +++ b/Modules/PhotoacousticsAlgorithms/Algorithms/mitkPhotoacousticBeamformingDASFilter.h @@ -0,0 +1,72 @@ +/*=================================================================== + +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 MITK_PHOTOACOUSTICS_BEAMFORMING_DAS_FILTER +#define MITK_PHOTOACOUSTICS_BEAMFORMING_DAS_FILTER + +#include "mitkImageToImageFilter.h" + +namespace mitk { + + //##Documentation + //## @brief + //## @ingroup Process + class BeamformingDASFilter : public ImageToImageFilter + { + public: + mitkClassMacro(BeamformingDASFilter, ImageToImageFilter); + + itkFactorylessNewMacro(Self) + itkCloneMacro(Self) + + struct beamformingSettings + { + double Pitch = 0.0003; // [m] + float SpeedOfSound = 1540; // [m/s] + unsigned int SamplesPerLine = 2048; + unsigned int ReconstructionLines = 128; + double RecordTime = 0.00006; // [s] + unsigned int TransducerElements = 128; + }; + + void Configure(beamformingSettings settings); + + protected: + + BeamformingDASFilter(); + + ~BeamformingDASFilter(); + + virtual void GenerateInputRequestedRegion() override; + + virtual void GenerateOutputInformation() override; + + virtual void GenerateData() override; + + //##Description + //## @brief Time when Header was last initialized + itk::TimeStamp m_TimeOfHeaderInitialization; + + double* m_OutputData; + double* m_InputData; + + beamformingSettings m_Conf; + }; + +} // namespace mitk + +#endif MITK_PHOTOACOUSTICS_BEAMFORMING_DAS_FILTER diff --git a/Modules/PhotoacousticsAlgorithms/Algorithms/mitkPhotoacousticBeamformingDMASFilter.cpp b/Modules/PhotoacousticsAlgorithms/Algorithms/mitkPhotoacousticBeamformingDMASFilter.cpp new file mode 100644 index 0000000000..989ddc8b7d --- /dev/null +++ b/Modules/PhotoacousticsAlgorithms/Algorithms/mitkPhotoacousticBeamformingDMASFilter.cpp @@ -0,0 +1,122 @@ +/*=================================================================== + +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 "mitkPhotoacousticBeamformingDMASFilter.h" +#include "mitkProperties.h" +#include "mitkImageReadAccessor.h" + +#include + + +mitk::BeamformingDMASFilter::BeamformingDMASFilter() : m_OutputData(nullptr), m_InputData(nullptr) +{ + this->SetNumberOfIndexedInputs(1); + this->SetNumberOfRequiredInputs(1); + + m_Conf.Pitch = 0.0003; + m_Conf.SpeedOfSound = 1540; + m_Conf.SamplesPerLine = 2048; + m_Conf.ReconstructionLines = 128; + m_Conf.RecordTime = 0.00006; + m_Conf.TransducerElements = 128; +} + +mitk::BeamformingDMASFilter::~BeamformingDMASFilter() +{ +} + +void mitk::BeamformingDMASFilter::GenerateInputRequestedRegion() +{ + Superclass::GenerateInputRequestedRegion(); + + mitk::Image* output = this->GetOutput(); + mitk::Image* input = const_cast< mitk::Image * > (this->GetInput()); + if (!output->IsInitialized()) + { + return; + } + + input->SetRequestedRegionToLargestPossibleRegion(); + + //GenerateTimeInInputRegion(output, input); +} + +void mitk::BeamformingDMASFilter::GenerateOutputInformation() +{ + mitk::Image::ConstPointer input = this->GetInput(); + mitk::Image::Pointer output = this->GetOutput(); + + if ((output->IsInitialized()) && (this->GetMTime() <= m_TimeOfHeaderInitialization.GetMTime())) + return; + + itkDebugMacro(<< "GenerateOutputInformation()"); + + unsigned int dim[] = { m_Conf.ReconstructionLines, m_Conf.SamplesPerLine, input->GetDimension(2) }; + output->Initialize(mitk::MakeScalarPixelType(), 3, dim); + + mitk::Vector3D spacing; + spacing[0] = m_Conf.Pitch * m_Conf.TransducerElements * 1000 / m_Conf.ReconstructionLines; + spacing[1] = m_Conf.RecordTime * m_Conf.SpeedOfSound / 2 * 1000 / m_Conf.SamplesPerLine; + spacing[2] = 1; + + output->GetGeometry()->SetSpacing(spacing); + output->GetGeometry()->Modified(); + output->SetPropertyList(input->GetPropertyList()->Clone()); + + m_TimeOfHeaderInitialization.Modified(); +} + + +void mitk::BeamformingDMASFilter::GenerateData() +{ + mitk::Image::ConstPointer input = this->GetInput(); + mitk::Image::Pointer output = this->GetOutput(); + + if (!output->IsInitialized()) + { + return; + } + + for (int i = 0; i < input->GetDimension(2); ++i) // seperate Slices should get Beamforming seperately applied + { + mitk::ImageReadAccessor inputReadAccessor(input, input->GetSliceData(i)); + m_InputData = (double*)inputReadAccessor.GetData(); + m_OutputData = new double[m_Conf.ReconstructionLines*m_Conf.SamplesPerLine]; + + for (int a = 0; a < m_Conf.ReconstructionLines; ++a) + { + for (int b = 0; b < m_Conf.SamplesPerLine; ++b) + { + m_OutputData[a*m_Conf.SamplesPerLine + b] = 1; + } + } + + MITK_INFO << "DMAS"; + + output->SetSlice(m_OutputData, i); + + delete[] m_OutputData; + m_OutputData = nullptr; + m_InputData = nullptr; + } + m_TimeOfHeaderInitialization.Modified(); +} + +void mitk::BeamformingDMASFilter::Configure(beamformingSettings settings) +{ + m_Conf = settings; +} \ No newline at end of file diff --git a/Modules/PhotoacousticsAlgorithms/Algorithms/mitkPhotoacousticBeamformingDMASFilter.h b/Modules/PhotoacousticsAlgorithms/Algorithms/mitkPhotoacousticBeamformingDMASFilter.h new file mode 100644 index 0000000000..99f1ea76d4 --- /dev/null +++ b/Modules/PhotoacousticsAlgorithms/Algorithms/mitkPhotoacousticBeamformingDMASFilter.h @@ -0,0 +1,72 @@ +/*=================================================================== + +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 MITK_PHOTOACOUSTICS_BEAMFORMING_DMAS_FILTER +#define MITK_PHOTOACOUSTICS_BEAMFORMING_DMAS_FILTER + +#include "mitkImageToImageFilter.h" + +namespace mitk { + + //##Documentation + //## @brief + //## @ingroup Process + class BeamformingDMASFilter : public ImageToImageFilter + { + public: + mitkClassMacro(BeamformingDMASFilter, ImageToImageFilter); + + itkFactorylessNewMacro(Self) + itkCloneMacro(Self) + + struct beamformingSettings + { + double Pitch = 0.0003; // [m] + float SpeedOfSound = 1540; // [m/s] + unsigned int SamplesPerLine = 2048; + unsigned int ReconstructionLines = 128; + double RecordTime = 0.00006; // [s] + unsigned int TransducerElements = 128; + }; + + void Configure(beamformingSettings settings); + + protected: + + BeamformingDMASFilter(); + + ~BeamformingDMASFilter(); + + virtual void GenerateInputRequestedRegion() override; + + virtual void GenerateOutputInformation() override; + + virtual void GenerateData() override; + + //##Description + //## @brief Time when Header was last initialized + itk::TimeStamp m_TimeOfHeaderInitialization; + + double* m_OutputData; + double* m_InputData; + + beamformingSettings m_Conf; + }; + +} // namespace mitk + +#endif MITK_PHOTOACOUSTICS_BEAMFORMING_DMAS_FILTER diff --git a/Modules/PhotoacousticsAlgorithms/files.cmake b/Modules/PhotoacousticsAlgorithms/files.cmake index 25184dbf33..69ecc38714 100644 --- a/Modules/PhotoacousticsAlgorithms/files.cmake +++ b/Modules/PhotoacousticsAlgorithms/files.cmake @@ -1,3 +1,6 @@ set(CPP_FILES mitkPhotoacousticImage.cpp + + Algorithms/mitkPhotoacousticBeamformingDASFilter.cpp + Algorithms/mitkPhotoacousticBeamformingDMASFilter.cpp ) diff --git a/Modules/PhotoacousticsAlgorithms/mitkPhotoacousticImage.cpp b/Modules/PhotoacousticsAlgorithms/mitkPhotoacousticImage.cpp index 07f7fc4655..d1f7cd6954 100644 --- a/Modules/PhotoacousticsAlgorithms/mitkPhotoacousticImage.cpp +++ b/Modules/PhotoacousticsAlgorithms/mitkPhotoacousticImage.cpp @@ -1,153 +1,177 @@ /*=================================================================== 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 "mitkPhotoacousticImage.h" #include "Algorithms/ITKUltrasound/itkBModeImageFilter.h" #include "Algorithms/itkPhotoacousticBModeImageFilter.h" #include "mitkImageCast.h" #include "mitkITKImageImport.h" +#include "Algorithms/mitkPhotoacousticBeamformingDASFilter.h" +#include "Algorithms/mitkPhotoacousticBeamformingDMASFilter.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::PhotoacousticImage::PhotoacousticImage() { MITK_INFO << "[PhotoacousticImage Debug] created that image"; } mitk::PhotoacousticImage::~PhotoacousticImage() { MITK_INFO << "[PhotoacousticImage Debug] destroyed that image"; } mitk::Image::Pointer mitk::PhotoacousticImage::ApplyBmodeFilter(mitk::Image::Pointer inputImage, bool UseLogFilter, float resampleSpacing) { // 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 typedef itk::ResampleImageFilter < itkFloatImageType, itkFloatImageType > ResampleImageFilter; ResampleImageFilter::Pointer resampleImageFilter = ResampleImageFilter::New(); itkFloatImageType::Pointer itkImage; mitk::CastToItkImage(inputImage, itkImage); itkFloatImageType::Pointer bmode; if (UseLogFilter) { bModeFilter->SetInput(itkImage); bModeFilter->SetDirection(1); bmode = bModeFilter->GetOutput(); } else { photoacousticBModeFilter->SetInput(itkImage); photoacousticBModeFilter->SetDirection(1); bmode = photoacousticBModeFilter->GetOutput(); } // resampleSpacing == 0 means: do no resampling if (resampleSpacing == 0) { return mitk::GrabItkImageMemory(bmode); } itkFloatImageType::SpacingType outputSpacing; itkFloatImageType::SizeType inputSize = itkImage->GetLargestPossibleRegion().GetSize(); itkFloatImageType::SizeType outputSize = inputSize; outputSize[0] = 256; outputSpacing[0] = itkImage->GetSpacing()[0] * (static_cast(inputSize[0]) / static_cast(outputSize[0])); outputSpacing[1] = resampleSpacing; outputSpacing[2] = 0.6; outputSize[1] = inputSize[1] * itkImage->GetSpacing()[1] / outputSpacing[1]; typedef itk::IdentityTransform TransformType; resampleImageFilter->SetInput(bmode); resampleImageFilter->SetSize(outputSize); resampleImageFilter->SetOutputSpacing(outputSpacing); resampleImageFilter->SetTransform(TransformType::New()); resampleImageFilter->UpdateLargestPossibleRegion(); return mitk::GrabItkImageMemory(resampleImageFilter->GetOutput()); } //mitk::Image::Pointer mitk::PhotoacousticImage::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::PhotoacousticImage::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] = (inputSizeItk[1] * outputSize[0] / inputSizeItk[1]); outputSizeItk[2] = 1; outputSpacingItk[0] = inputSpacing[0] * (double)inputSizeItk[0] / (double)outputSize[0]; outputSpacingItk[1] = inputSpacing[1] * (double)inputSizeItk[1] / (double)outputSize[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::PhotoacousticImage::ApplyBeamformingDAS(mitk::Image::Pointer inputImage, BeamformingDASFilter::beamformingSettings config) +{ + BeamformingDASFilter::Pointer Beamformer = BeamformingDASFilter::New(); + + Beamformer->SetInput(inputImage); + Beamformer->Configure(config); + + Beamformer->UpdateLargestPossibleRegion(); + return Beamformer->GetOutput(); +} + +mitk::Image::Pointer mitk::PhotoacousticImage::ApplyBeamformingDMAS(mitk::Image::Pointer inputImage, BeamformingDMASFilter::beamformingSettings config) +{ + BeamformingDMASFilter::Pointer Beamformer = BeamformingDMASFilter::New(); + + Beamformer->SetInput(inputImage); + Beamformer->Configure(config); + + Beamformer->UpdateLargestPossibleRegion(); + return Beamformer->GetOutput(); +} \ No newline at end of file diff --git a/Modules/PhotoacousticsAlgorithms/mitkPhotoacousticImage.h b/Modules/PhotoacousticsAlgorithms/mitkPhotoacousticImage.h index 9b742895c5..150ff1bc37 100644 --- a/Modules/PhotoacousticsAlgorithms/mitkPhotoacousticImage.h +++ b/Modules/PhotoacousticsAlgorithms/mitkPhotoacousticImage.h @@ -1,44 +1,49 @@ /*=================================================================== 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 mitkPhotoacousticImage_H_HEADER_INCLUDED #define mitkPhotoacousticImage_H_HEADER_INCLUDED #include "itkObject.h" #include "mitkCommon.h" #include "mitkImage.h" +#include "Algorithms/mitkPhotoacousticBeamformingDASFilter.h" +#include "Algorithms/mitkPhotoacousticBeamformingDMASFilter.h" + #include "MitkPhotoacousticsAlgorithmsExports.h" namespace mitk { class MITKPHOTOACOUSTICSALGORITHMS_EXPORT PhotoacousticImage : public itk::Object { public: mitkClassMacroItkParent(mitk::PhotoacousticImage, itk::Object); itkFactorylessNewMacro(Self); mitk::Image::Pointer ApplyBmodeFilter(mitk::Image::Pointer inputImage, bool UseLogFilter = false, float resampleSpacing = 0.15); // 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 ApplyBeamformingDAS(mitk::Image::Pointer inputImage, BeamformingDASFilter::beamformingSettings config); + mitk::Image::Pointer ApplyBeamformingDMAS(mitk::Image::Pointer inputImage, BeamformingDMASFilter::beamformingSettings config); protected: PhotoacousticImage(); virtual ~PhotoacousticImage(); }; } // namespace mitk #endif /* mitkPhotoacousticImage_H_HEADER_INCLUDED */ diff --git a/Plugins/org.mitk.gui.qt.photoacoustics.imageprocessing/src/internal/PAImageProcessing.cpp b/Plugins/org.mitk.gui.qt.photoacoustics.imageprocessing/src/internal/PAImageProcessing.cpp index 38088e66ea..0e289aa159 100644 --- a/Plugins/org.mitk.gui.qt.photoacoustics.imageprocessing/src/internal/PAImageProcessing.cpp +++ b/Plugins/org.mitk.gui.qt.photoacoustics.imageprocessing/src/internal/PAImageProcessing.cpp @@ -1,143 +1,227 @@ /*=================================================================== 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 "PAImageProcessing.h" // Qt #include //mitk image #include #include "mitkPhotoacousticImage.h" +#include "Algorithms\mitkPhotoacousticBeamformingDASFilter.h" +#include "Algorithms\mitkPhotoacousticBeamformingDMASFilter.h" const std::string PAImageProcessing::VIEW_ID = "org.mitk.views.paimageprocessing"; PAImageProcessing::PAImageProcessing() : m_ResampleSpacing(0), m_UseLogfilter(false) { } void PAImageProcessing::SetFocus() { m_Controls.buttonApplyBModeFilter->setFocus(); } void PAImageProcessing::CreateQtPartControl( QWidget *parent ) { // create GUI widgets from the Qt Designer's .ui file m_Controls.setupUi( parent ); connect( m_Controls.buttonApplyBModeFilter, SIGNAL(clicked()), this, SLOT(ApplyBModeFilter()) ); connect(m_Controls.DoResampling, SIGNAL(clicked()), this, SLOT(UseResampling())); connect(m_Controls.Logfilter, SIGNAL(clicked()), this, SLOT(UseLogfilter())); connect(m_Controls.ResamplingValue, SIGNAL(valueChanged(double)), this, SLOT(SetResampling())); + connect(m_Controls.buttonApplyBeamforming, SIGNAL(clicked()), this, SLOT(ApplyBeamforming())); m_Controls.DoResampling->setChecked(false); m_Controls.ResamplingValue->setEnabled(false); + + UpdateBFSettings(); } void PAImageProcessing::OnSelectionChanged( berry::IWorkbenchPart::Pointer /*source*/, const QList& nodes ) { // iterate all selected objects, adjust warning visibility foreach( mitk::DataNode::Pointer node, nodes ) { if( node.IsNotNull() && dynamic_cast(node->GetData()) ) { m_Controls.labelWarning->setVisible( false ); m_Controls.buttonApplyBModeFilter->setEnabled( true ); return; } } m_Controls.labelWarning->setVisible( true ); m_Controls.buttonApplyBModeFilter->setEnabled( false ); } void PAImageProcessing::UseResampling() { if (m_Controls.DoResampling->isChecked()) { m_Controls.ResamplingValue->setEnabled(true); m_ResampleSpacing = m_Controls.ResamplingValue->value(); } else { m_Controls.ResamplingValue->setEnabled(false); m_ResampleSpacing = 0; } } void PAImageProcessing::UseLogfilter() { m_UseLogfilter = m_Controls.Logfilter->isChecked(); } void PAImageProcessing::SetResampling() { m_ResampleSpacing = m_Controls.ResamplingValue->value(); } void PAImageProcessing::ApplyBModeFilter() { QList nodes = this->GetDataManagerSelection(); if (nodes.empty()) return; mitk::DataNode::Pointer node = nodes.front(); if (!node) { // Nothing selected. Inform the user and return QMessageBox::information( NULL, "Template", "Please load and select an image before starting image processing."); return; } mitk::BaseData* data = node->GetData(); if (data) { // test if this data item is an image or not (could also be a surface or something totally different) mitk::Image* image = dynamic_cast(data); if (image) { std::stringstream message; std::string name; message << "Performing image processing for image "; if (node->GetName(name)) { // a property called "name" was found for this DataNode message << "'" << name << "'"; } message << "."; MITK_INFO << message.str(); mitk::PhotoacousticImage::Pointer filterbank = mitk::PhotoacousticImage::New(); node->SetData(filterbank->ApplyBmodeFilter(image, m_UseLogfilter, m_ResampleSpacing)); // update level window for the current dynamic range mitk::LevelWindow levelWindow; node->GetLevelWindow(levelWindow); data = node->GetData(); levelWindow.SetAuto(dynamic_cast(data),true,true); node->SetLevelWindow(levelWindow); // update rendering + mitk::RenderingManager::GetInstance()->InitializeViews( + dynamic_cast(data)->GetGeometry(), mitk::RenderingManager::REQUEST_UPDATE_ALL, true); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } } } + +void PAImageProcessing::ApplyBeamforming() +{ + UpdateBFSettings(); + + QList nodes = this->GetDataManagerSelection(); + if (nodes.empty()) return; + + mitk::DataNode::Pointer node = nodes.front(); + + if (!node) + { + // Nothing selected. Inform the user and return + QMessageBox::information(NULL, "Template", "Please load and select an image before starting image processing."); + return; + } + + mitk::BaseData* data = node->GetData(); + if (data) + { + // test if this data item is an image or not (could also be a surface or something totally different) + mitk::Image* image = dynamic_cast(data); + if (image) + { + std::stringstream message; + std::string name; + message << "Performing beamforming for image "; + if (node->GetName(name)) + { + // a property called "name" was found for this DataNode + message << "'" << name << "'"; + } + message << "."; + MITK_INFO << message.str(); + mitk::PhotoacousticImage::Pointer filterbank = mitk::PhotoacousticImage::New(); + + if(m_CurrentBeamformingAlgorithm == BeamformingAlgorithms::DAS) + node->SetData(filterbank->ApplyBeamformingDAS(image, DASconfig)); + else if(m_CurrentBeamformingAlgorithm == BeamformingAlgorithms::DMAS) + node->SetData(filterbank->ApplyBeamformingDMAS(image, DMASconfig)); + + // update level window for the current dynamic range + mitk::LevelWindow levelWindow; + node->GetLevelWindow(levelWindow); + data = node->GetData(); + levelWindow.SetAuto(dynamic_cast(data), true, true); + node->SetLevelWindow(levelWindow); + + // update rendering + mitk::RenderingManager::GetInstance()->InitializeViews( + dynamic_cast(data)->GetGeometry(), mitk::RenderingManager::REQUEST_UPDATE_ALL, true); + mitk::RenderingManager::GetInstance()->RequestUpdateAll(); + } + } +} + +void PAImageProcessing::UpdateBFSettings() +{ + if ("Delay and Sum" == m_Controls.BFAlgorithm->currentText()) + m_CurrentBeamformingAlgorithm = BeamformingAlgorithms::DAS; + else if ("Delay, Multiply and Sum" == m_Controls.BFAlgorithm->currentText()) + m_CurrentBeamformingAlgorithm = BeamformingAlgorithms::DMAS; + + DASconfig.Pitch = m_Controls.Pitch->value(); // [m] + DASconfig.SpeedOfSound = m_Controls.SpeedOfSound->value(); // [m/s] + DASconfig.SamplesPerLine = m_Controls.Samples->value(); + DASconfig.ReconstructionLines = m_Controls.Lines->value(); + DASconfig.RecordTime = m_Controls.ScanDepth->value() / DASconfig.SpeedOfSound * 2; // [s] + DASconfig.TransducerElements = m_Controls.ElementCount->value(); + + DMASconfig.Pitch = m_Controls.Pitch->value(); // [m] + DMASconfig.SpeedOfSound = m_Controls.SpeedOfSound->value(); // [m/s] + DMASconfig.SamplesPerLine = m_Controls.Samples->value(); + DMASconfig.ReconstructionLines = m_Controls.Lines->value(); + DMASconfig.RecordTime = m_Controls.ScanDepth->value() / DMASconfig.SpeedOfSound * 2; // [s] + DMASconfig.TransducerElements = m_Controls.ElementCount->value(); +} \ No newline at end of file diff --git a/Plugins/org.mitk.gui.qt.photoacoustics.imageprocessing/src/internal/PAImageProcessing.h b/Plugins/org.mitk.gui.qt.photoacoustics.imageprocessing/src/internal/PAImageProcessing.h index 6ae138643f..f377b2b577 100644 --- a/Plugins/org.mitk.gui.qt.photoacoustics.imageprocessing/src/internal/PAImageProcessing.h +++ b/Plugins/org.mitk.gui.qt.photoacoustics.imageprocessing/src/internal/PAImageProcessing.h @@ -1,63 +1,76 @@ /*=================================================================== 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 PAImageProcessing_h #define PAImageProcessing_h #include #include #include "ui_PAImageProcessingControls.h" +#include "Algorithms\mitkPhotoacousticBeamformingDASFilter.h" +#include "Algorithms\mitkPhotoacousticBeamformingDMASFilter.h" + class PAImageProcessing : 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: static const std::string VIEW_ID; PAImageProcessing(); protected slots: /// \brief Called when the user clicks the GUI button void ApplyBModeFilter(); void UseResampling(); void UseLogfilter(); void SetResampling(); + void ApplyBeamforming(); + protected: virtual void CreateQtPartControl(QWidget *parent) override; virtual void SetFocus() override; /// \brief called by QmitkFunctionality when DataManager's selection has changed virtual void OnSelectionChanged( berry::IWorkbenchPart::Pointer source, const QList& nodes ) override; Ui::PAImageProcessingControls m_Controls; float m_ResampleSpacing; bool m_UseLogfilter; + mitk::BeamformingDMASFilter::beamformingSettings DMASconfig; + mitk::BeamformingDASFilter::beamformingSettings DASconfig; + + enum BeamformingAlgorithms {DAS, DMAS}; + + BeamformingAlgorithms m_CurrentBeamformingAlgorithm; + + void UpdateBFSettings(); }; #endif // PAImageProcessing_h diff --git a/Plugins/org.mitk.gui.qt.photoacoustics.imageprocessing/src/internal/PAImageProcessingControls.ui b/Plugins/org.mitk.gui.qt.photoacoustics.imageprocessing/src/internal/PAImageProcessingControls.ui index a954fb2ec7..dbb9984f98 100644 --- a/Plugins/org.mitk.gui.qt.photoacoustics.imageprocessing/src/internal/PAImageProcessingControls.ui +++ b/Plugins/org.mitk.gui.qt.photoacoustics.imageprocessing/src/internal/PAImageProcessingControls.ui @@ -1,159 +1,326 @@ PAImageProcessingControls 0 0 615 678 0 0 QmitkTemplate <html><head/><body><p><span style=" font-size:10pt; font-weight:600;">B-mode Filter</span></p></body></html> <html><head/><body><p><span style=" font-weight:600;">Filter Settings</span></p></body></html> Do Resampling 0.010000000000000 1.000000000000000 0.010000000000000 0.150000000000000 Resample Spacing [mm] Add Logfilter QLabel { color: rgb(255, 0, 0) } <html><head/><body><p align="center"><span style=" font-size:10pt; font-weight:600;">Please select an image!</span></p></body></html> Do image processing Apply B-mode Filter - - - - Qt::Vertical - - - - 20 - 40 - - - - + + + + Qt::Horizontal + + + <html><head/><body><p><span style=" font-size:10pt; font-weight:600;">Beamforming</span></p></body></html> - + - Dummy + <html><head/><body><p><span style=" font-weight:600;">Settings</span></p></body></html> - - - Qt::Vertical - - - - 20 - 40 - + + + + + Speed of Sound [m/s] + + + + + + + Scan Depth [mm] + + + + + + + 1 + + + 0.100000000000000 + + + 2.000000000000000 + + + 0.100000000000000 + + + 0.300000000000000 + + + + + + + 1 + + + 200.000000000000000 + + + 3000.000000000000000 + + + 0.100000000000000 + + + 1540.000000000000000 + + + + + + + Beamforming Method + + + + + + + Transducer Element Count + + + + + + + 1 + + + 0.100000000000000 + + + 50.000000000000000 + + + + + + + + Delay and Sum + + + + + Delay, Multiply and Sum + + + + + + + + Transducer Pitch[mm] + + + + + + + 1 + + + 1024 + + + 128 + + + 128 + + + + + + + 256 + + + 16384 + + + 256 + + + 2048 + + + + + + + 128 + + + 2048 + + + 128 + + + 128 + + + + + + + Samples + + + + + + + Reconstruction Lines + + + + + + + + + Apply Beamforming - + + + + + Qt::Vertical + + + + 20 + 40 + + + +