12 #define _USE_MATH_DEFINES 23 #include "../ITKFilter/ITKUltrasound/itkFFT1DRealToComplexConjugateImageFilter.h" 26 #include "itkComplexToModulusImageFilter.h" 30 CPPUNIT_TEST_SUITE(mitkBandpassFilterTestSuite);
33 CPPUNIT_TEST_SUITE_END();
37 mitk::PhotoacousticFilterService::Pointer m_FilterService;
38 const unsigned int NUM_ITERATIONS = 10;
39 const unsigned int DATA_XY_DIM = 512;
40 const unsigned int DATA_Z_DIM = 8;
41 const float TIME_SPACING = 0.00625;
42 float FREQUENCY_RESOLUTION = 1 / (TIME_SPACING / 1e6 * DATA_XY_DIM);
43 const float MAX_FREQUENCY = FREQUENCY_RESOLUTION * DATA_XY_DIM / 2.f;
44 const float HIGHPASS_FREQENCY = MAX_FREQUENCY * 0.8f;
45 const float LOWPASS_FREQENCY = MAX_FREQUENCY * 0.1f;
46 const float ALPHA = 0.01;
47 const float EPSILON_FFT = 0.0001f;
56 void test(
float HighPass,
float LowPass,
float HighPassAlpha,
float LowPassAlpha,
bool useLow,
bool useHigh)
59 std::default_random_engine randGen(r());
60 std::uniform_real_distribution<float> randDistrHighPass(HighPass * 0.01f, HighPass * 0.2f);
61 std::uniform_real_distribution<float> randDistrLowPass(LowPass * 1.5f, LowPass * 2.f);
62 float* data =
new float[DATA_XY_DIM*DATA_XY_DIM*DATA_Z_DIM];
65 unsigned int dimension[3]{ DATA_XY_DIM, DATA_XY_DIM, DATA_Z_DIM };
66 inputImage->Initialize(mitk::MakeScalarPixelType<float>(), 3, dimension);
69 spacing[1] = TIME_SPACING;
71 inputImage->SetSpacing(spacing);
73 for (
unsigned int iteration = 0; iteration < NUM_ITERATIONS; ++iteration)
76 for (
unsigned int i = 0; i < DATA_XY_DIM*DATA_XY_DIM*DATA_Z_DIM; ++i)
83 addFrequency(randDistrHighPass(randGen), TIME_SPACING, data, dimension);
85 addFrequency(randDistrLowPass(randGen), TIME_SPACING, data, dimension);
87 inputImage->SetImportVolume(data, 0, 0, mitk::Image::ImportMemoryManagementType::CopyMemory);
93 LowPass = MAX_FREQUENCY;
95 mitk::Image::Pointer outputImage = m_FilterService->ApplyBandpassFilter(inputImage, HighPass, LowPass, HighPassAlpha, LowPassAlpha, TIME_SPACING / 1e6, 0,
false);
98 typedef itk::Image< float, 3 > RealImageType;
99 RealImageType::Pointer
image;
105 ForwardFFTFilterType::Pointer forwardFFTFilter = ForwardFFTFilterType::New();
106 forwardFFTFilter->SetInput(image);
107 forwardFFTFilter->SetDirection(1);
108 forwardFFTFilter->UpdateOutputInformation();
109 forwardFFTFilter->Update();
111 auto fftResult = forwardFFTFilter->GetOutput();
120 for (
unsigned int z = 0; z < DATA_Z_DIM; ++z)
122 for (
unsigned int y = 0; y < DATA_XY_DIM / 2; ++y)
124 if (y < (
unsigned int)std::floor(0.95 * HighPass / FREQUENCY_RESOLUTION) || y >(
unsigned int)std::ceil(1.05 * LowPass / FREQUENCY_RESOLUTION))
126 for (
unsigned int x = 0; x < DATA_XY_DIM; ++x)
129 std::complex<float> value = fftResult->GetPixel({ x,y,z });
130 CPPUNIT_ASSERT_MESSAGE(std::string(
"Expected 0, got (" + std::to_string(value.real()) +
" + " + std::to_string(value.imag()) +
"i) at " + std::to_string(x) +
"-" + std::to_string(y) +
"-" + std::to_string(z)),
131 (value.real() < EPSILON_FFT) && (value.imag() < EPSILON_FFT));
136 for (
unsigned int y = DATA_XY_DIM / 2; y < DATA_XY_DIM; ++y)
138 if (y > DATA_XY_DIM - (
unsigned int)std::floor(HighPass / FREQUENCY_RESOLUTION) || y < DATA_XY_DIM - (
unsigned int)std::ceil(LowPass / FREQUENCY_RESOLUTION))
140 for (
unsigned int x = 0; x < DATA_XY_DIM; ++x)
143 std::complex<float> value = fftResult->GetPixel({ x,y,z });
144 CPPUNIT_ASSERT_MESSAGE(std::string(
"Expected 0, got (" + std::to_string(value.real()) +
" + " + std::to_string(value.imag()) +
"i) at " + std::to_string(x) +
"-" + std::to_string(y) +
"-" + std::to_string(z)),
145 (value.real() < EPSILON_FFT) && (value.imag() < EPSILON_FFT));
156 void addFrequency(
float freq,
float timeSpacing,
float* data,
unsigned int* dim)
158 for (
unsigned int z = 0; z < dim[2]; ++z)
160 for (
unsigned int y = 0; y < dim[1]; ++y)
162 for (
unsigned int x = 0; x < dim[0]; ++x)
164 data[x + y * dim[0] + z * dim[0] * dim[1]] += std::sin(freq * timeSpacing * y);
173 test(HIGHPASS_FREQENCY, 0, ALPHA, ALPHA,
false,
true);
179 test(0, LOWPASS_FREQENCY, ALPHA, ALPHA,
true,
false);
182 void tearDown()
override 184 m_FilterService =
nullptr;
MITK_TEST_SUITE_REGISTRATION(mitkImageToItk)
Perform the Fast Fourier Transform, in the forward direction, with real inputs, but only along one di...
Follow Up Storage - Class to facilitate loading/accessing structured follow-up data.
#define MITK_TEST(TESTMETHOD)
Adds a test to the current test suite.
Test fixture for parameterized tests.
mitk::Image::Pointer image
void MITKCORE_EXPORT CastToItkImage(const mitk::Image *mitkImage, itk::SmartPointer< ItkOutputImageType > &itkOutputImage)
Cast an mitk::Image to an itk::Image with a specific type.