13 #define _USE_MATH_DEFINES 18 #include "../ITKFilter/ITKUltrasound/itkFFT1DComplexConjugateToRealImageFilter.h" 19 #include "../ITKFilter/ITKUltrasound/itkFFT1DRealToComplexConjugateImageFilter.h" 20 #include "itkComplexToModulusImageFilter.h" 21 #include "itkMultiplyImageFilter.h" 33 MITK_INFO <<
"Instantiating BandpassFilter...";
34 SetNumberOfIndexedInputs(1);
35 SetNumberOfIndexedOutputs(1);
36 MITK_INFO <<
"Instantiating BandpassFilter...[Done]";
41 MITK_INFO <<
"Destructed BandpassFilter.";
48 std::string type = input->GetPixelType().GetTypeAsString();
49 if (!(type ==
"scalar (float)" || type ==
" (float)"))
51 MITK_ERROR <<
"This filter can currently only handle float type images.";
52 mitkThrow() <<
"This filter can currently only handle float type images.";
56 MITK_ERROR <<
"High Pass is higher than Low Pass; aborting.";
57 mitkThrow() <<
"High Pass is higher than Low Pass; aborting.";
62 float cutoffFrequencyPixelHighPass,
63 float cutoffFrequencyPixelLowPass,
67 float *imageData =
new float[reference->GetDimension(0) * reference->GetDimension(1)];
69 float width = cutoffFrequencyPixelLowPass - cutoffFrequencyPixelHighPass;
70 float center = cutoffFrequencyPixelHighPass + width / 2.f;
72 for (
unsigned int n = 0; n < reference->GetDimension(1); ++n)
74 imageData[reference->GetDimension(0) * n] = 0;
76 for (
int n = 0; n < width; ++n)
78 imageData[reference->GetDimension(0) * (int)(n + center - (width / 2.f))] = 1;
79 if (n <= (alphaHighPass * (width - 1)) / 2.f)
81 if (alphaHighPass > 0.00001f)
83 imageData[reference->GetDimension(0) * (int)(n + center - (width / 2.f))] =
84 (1 + cos(itk::Math::pi * (2 * n / (alphaHighPass * (width - 1)) - 1))) / 2;
88 imageData[reference->GetDimension(0) * (int)(n + center - (width / 2.f))] = 1;
91 else if (n >= (width - 1) * (1 - alphaLowPass / 2.f))
93 if (alphaLowPass > 0.00001f)
95 imageData[reference->GetDimension(0) * (int)(n + center - (width / 2.f))] =
96 (1 + cos(itk::Math::pi * (2 * n / (alphaLowPass * (width - 1)) + 1 - 2 / alphaLowPass))) / 2;
100 imageData[reference->GetDimension(0) * (int)(n + center - (width / 2.f))] = 1;
105 for (
unsigned int n = reference->GetDimension(1) / 2; n < reference->GetDimension(1); ++n)
107 imageData[reference->GetDimension(0) * n] =
108 imageData[(reference->GetDimension(1) - (n + 1)) * reference->GetDimension(0)];
111 for (
unsigned int line = 1;
line < reference->GetDimension(0); ++
line)
113 for (
unsigned int sample = 0; sample < reference->GetDimension(1); ++sample)
115 imageData[reference->GetDimension(0) * sample +
line] = imageData[reference->GetDimension(0) * sample];
120 ImageType::RegionType region;
121 ImageType::IndexType start;
124 region.SetIndex(start);
126 ImageType::SizeType size;
127 size[0] = reference->GetDimension(0);
128 size[1] = reference->GetDimension(1);
129 size[2] = reference->GetDimension(2);
131 region.SetSize(size);
133 ImageType::SpacingType SpacingItk;
134 SpacingItk[0] = reference->GetGeometry()->GetSpacing()[0];
135 SpacingItk[1] = reference->GetGeometry()->GetSpacing()[1];
136 SpacingItk[2] = reference->GetGeometry()->GetSpacing()[2];
138 ImageType::Pointer
image = ImageType::New();
139 image->SetRegions(region);
141 image->FillBuffer(itk::NumericTraits<float>::Zero);
142 image->SetSpacing(SpacingItk);
144 ImageType::IndexType pixelIndex;
146 for (
unsigned int slice = 0; slice < reference->GetDimension(2); ++slice)
148 for (
unsigned int line = 0;
line < reference->GetDimension(0); ++
line)
150 for (
unsigned int sample = 0; sample < reference->GetDimension(1); ++sample)
152 pixelIndex[0] =
line;
153 pixelIndex[1] = sample;
154 pixelIndex[2] = slice;
156 image->SetPixel(pixelIndex, imageData[
line + sample * reference->GetDimension(0)]);
173 double powerOfTwo = std::log2(input->GetDimension(1));
175 double spacingResize = 1;
178 if (std::fmod(powerOfTwo, 1.0) >= std::numeric_limits<double>::epsilon())
180 finalSize = (int)pow(2, std::ceil(powerOfTwo));
181 double dim[2] = {(double)input->GetDimension(0), (double)finalSize };
183 spacingResize = (double)input->GetDimension(1) / finalSize;
187 typedef itk::Image<float, 3> RealImageType;
188 RealImageType::Pointer
image;
191 typedef ForwardFFTFilterType::OutputImageType ComplexImageType;
192 ForwardFFTFilterType::Pointer forwardFFTFilter = ForwardFFTFilterType::New();
193 forwardFFTFilter->SetInput(image);
194 forwardFFTFilter->SetDirection(1);
198 forwardFFTFilter->UpdateOutputInformation();
200 catch (itk::ExceptionObject &error)
202 std::cerr <<
"Error: " << error << std::endl;
203 MITK_ERROR <<
"Bandpass could not be applied";
208 mitkThrow() <<
"High pass frequency higher than low pass frequency, abort";
210 float singleVoxel = spacingResize / (
m_TimeSpacing * resampledInput->GetDimension(1));
212 singleVoxel = spacingResize / (resampledInput->GetGeometry()->GetSpacing()[1] / 1e3 /
m_SpeedOfSound * resampledInput->GetDimension(1));
213 float cutoffPixelHighPass =
std::min((
m_HighPass / singleVoxel), (
float)resampledInput->GetDimension(1) / 2.0f);
214 float cutoffPixelLowPass =
std::min((
m_LowPass / singleVoxel), (
float)resampledInput->GetDimension(1) / 2.0f);
216 MITK_INFO <<
"SingleVoxel: " << singleVoxel;
220 MITK_INFO <<
"cutoffPixelHighPass: " << cutoffPixelHighPass;
221 MITK_INFO <<
"cutoffPixelLowPass: " << cutoffPixelLowPass;
223 RealImageType::Pointer fftMultiplicator =
226 typedef itk::MultiplyImageFilter<ComplexImageType, RealImageType, ComplexImageType> MultiplyFilterType;
227 MultiplyFilterType::Pointer multiplyFilter = MultiplyFilterType::New();
228 multiplyFilter->SetInput1(forwardFFTFilter->GetOutput());
229 multiplyFilter->SetInput2(fftMultiplicator);
247 InverseFilterType::Pointer inverseFFTFilter = InverseFilterType::New();
248 inverseFFTFilter->SetInput(multiplyFilter->GetOutput());
249 inverseFFTFilter->SetDirection(1);
253 double dim[2] = { (double)input->GetDimension(0), (double)input->GetDimension(1) };
254 auto resampledOutput =
m_FilterService->ApplyResamplingToDim(output, dim);
256 output->Initialize(mitk::MakeScalarPixelType<float>(), 3, input->GetDimensions());
257 output->SetSpacing(resampledOutput->GetGeometry()->GetSpacing());
259 output->SetImportVolume(copy.
GetData());
itk::Image< float, 3U >::Pointer BPFunction(mitk::Image::Pointer reference, float cutoffFrequencyPixelHighPass, float cutoffFrequencyPixelLowPass, float alphaHighPass, float alphaLowPass)
Perform the Fast Fourier Transform, in the forward direction, with real inputs, but only along one di...
Class holding methods to apply all Filters within the Photoacoustics Algorithms Module.
itk::Image< unsigned char, 3 > ImageType
DataCollection - Class to facilitate loading/accessing structured data.
Perform the Fast Fourier Transform, in the reverse direction, with real output, but only along one di...
Image::Pointer GrabItkImageMemory(itk::SmartPointer< ItkOutputImageType > &itkimage, mitk::Image *mitkImage=nullptr, const BaseGeometry *geometry=nullptr, bool update=true)
Grabs the memory of an itk::Image (with a specific type) and puts it into an mitk::Image.The memory is managed by the mitk::Image after calling this function. The itk::Image remains valid until the mitk::Image decides to free the memory.
~BandpassFilter() override
mitk::Image::Pointer image
InputImageType * GetInput(void)
void SanityCheckPreconditions()
mitk::PhotoacousticFilterService::Pointer m_FilterService
void MITKCORE_EXPORT CastToItkImage(const mitk::Image *mitkImage, itk::SmartPointer< ItkOutputImageType > &itkOutputImage)
Cast an mitk::Image to an itk::Image with a specific type.
void GenerateData() override
OutputType * GetOutput()
Get the output data of this image source object.
ImageReadAccessor class to get locked read access for a particular image part.
const void * GetData() const
Gives const access to the data.