22 class SyntheticPAImageData
25 SyntheticPAImageData(
float spacing_x,
float spacing_y,
unsigned int samples,
unsigned int num_transducers,
float speedOfSound)
27 m_Spacing_x = spacing_x;
28 m_Spacing_y = spacing_y;
29 m_TransducerElements = num_transducers;
31 m_SpeedOfSound = speedOfSound;
32 m_Data =
new float[m_Samples*m_TransducerElements];
34 for (
size_t i = 0; i < m_Samples * m_TransducerElements; ++i)
40 ~SyntheticPAImageData()
45 void AddWave(
float origin_depth,
float origin_x,
float base_value= 10000)
47 AddLine(origin_depth, origin_x, base_value);
48 AddLine(origin_depth + 0.0001f, origin_x, -base_value);
51 const float* GetData()
53 return (
const float*)m_Data;
57 void AddLine(
float origin_depth,
unsigned int origin_x,
float base_value = 10000)
59 for (
unsigned int x = 0; x < m_TransducerElements; ++x)
61 float distance = std::abs((
int)x - (
int)origin_x);
62 float delay_in_seconds = std::sqrt(std::pow(origin_depth, 2) + std::pow(distance*m_Spacing_x, 2)) / m_SpeedOfSound;
63 int pixels = std::round(delay_in_seconds / m_Spacing_y);
65 for (
int index = -4; index < 9; ++index)
67 if ((
int)pixels + index < (
int)m_Samples && (
int)pixels + index > 0)
69 m_Data[(size_t)(x + (pixels + index)*m_TransducerElements)] += base_value / std::sqrt(distance + 1);
78 unsigned int m_TransducerElements;
79 unsigned int m_Samples;
85 CPPUNIT_TEST_SUITE(mitkBeamformingFilterTestSuite);
92 CPPUNIT_TEST_SUITE_END();
97 const unsigned int NUM_ITERATIONS = 15;
98 const unsigned int SAMPLES = 5000 * 2;
99 const unsigned int RECONSTRUCTED_SAMPLES = 2048;
100 const unsigned int ELEMENTS = 128;
101 const unsigned int RECONSTRUCTED_LINES = 128;
102 const float SPEED_OF_SOUND = 1540;
103 const float SPACING_X = 0.3;
104 const float SPACING_Y = 0.00625 / 2;
105 const unsigned int GPU_BATCH_SIZE = 16;
109 void setUp()
override 116 std::random_device r;
117 std::default_random_engine randGen(r());
118 float maxDepthInMeters = SAMPLES * (SPACING_Y / 1000000) * SPEED_OF_SOUND / 2;
119 std::uniform_real_distribution<float> randDistrDepth(maxDepthInMeters*0.1, maxDepthInMeters*0.8);
121 for (
unsigned int iteration = 0; iteration < NUM_ITERATIONS; ++iteration)
124 float depth_in_meters1 = randDistrDepth(randGen);
125 float depth_in_meters2 = randDistrDepth(randGen);
126 float depth_in_meters3 = randDistrDepth(randGen);
128 unsigned int element1 = 29;
129 unsigned int element2 = 63;
130 unsigned int element3 = 98;
132 SyntheticPAImageData
image(SPACING_X / 1000.f, SPACING_Y / 1000000.f, SAMPLES, ELEMENTS, SPEED_OF_SOUND);
133 image.AddWave(depth_in_meters1, 29);
134 image.AddWave(depth_in_meters2, 63);
135 image.AddWave(depth_in_meters3, 98);
138 unsigned int dimension[3]{ ELEMENTS, SAMPLES, 1 };
139 inputImage->Initialize(mitk::MakeScalarPixelType<float>(), 3, dimension);
141 spacing[0] = SPACING_X;
142 spacing[1] = SPACING_Y;
144 inputImage->SetSpacing(spacing);
148 m_BeamformingFilter->SetInput(inputImage);
149 m_BeamformingFilter->Update();
153 const float* outputData = (
const float*)readAccess.GetData();
155 unsigned int pos1[3] = { element1, (
unsigned int)std::round(depth_in_meters1 * 1000.f / outputImage->GetGeometry()->GetSpacing()[1]), 0 };
156 unsigned int pos2[3] = { element2, (
unsigned int)std::round(depth_in_meters2 * 1000.f / outputImage->GetGeometry()->GetSpacing()[1]), 0 };
157 unsigned int pos3[3] = { element3, (
unsigned int)std::round(depth_in_meters3 * 1000.f / outputImage->GetGeometry()->GetSpacing()[1]), 0 };
161 for (
unsigned int i = 0; i < RECONSTRUCTED_LINES*RECONSTRUCTED_SAMPLES; ++i)
163 average += outputData[i] / (RECONSTRUCTED_LINES*RECONSTRUCTED_SAMPLES);
166 CPPUNIT_ASSERT_MESSAGE(std::string(
"Iteration " + std::to_string(iteration) +
": first point source incorrectly reconstructed; should be > average*100, is " +
167 std::to_string(abs(outputData[pos1[0] + pos1[1] * RECONSTRUCTED_LINES]))) +
" < " + std::to_string(average) +
"*100" 168 , abs(outputData[pos1[0] + pos1[1]*RECONSTRUCTED_LINES] / average) > 100);
169 CPPUNIT_ASSERT_MESSAGE(std::string(
"Iteration " + std::to_string(iteration) +
": second point source incorrectly reconstructed; should be > average*100, is " +
170 std::to_string(abs(outputData[pos2[0] + pos2[1] * RECONSTRUCTED_LINES]))) +
" < " + std::to_string(average) +
"*100" 171 , abs(outputData[pos2[0] + pos2[1] * RECONSTRUCTED_LINES] / average) > 100);
172 CPPUNIT_ASSERT_MESSAGE(std::string(
"Iteration " + std::to_string(iteration) +
": third point source incorrectly reconstructed; should be > average*100, is " +
173 std::to_string(abs(outputData[pos3[0] + pos3[1] * RECONSTRUCTED_LINES]))) +
" < " + std::to_string(average) +
"*100" 174 , abs(outputData[pos3[0] + pos3[1] * RECONSTRUCTED_LINES] / average) > 100);
185 RECONSTRUCTED_SAMPLES,
188 SPEED_OF_SOUND * (SPACING_Y / 1000000) * SAMPLES,
191 mitk::BeamformingSettings::DelayCalc::Spherical,
192 mitk::BeamformingSettings::Apodization::Box,
197 void testBeamformingCPU_DAS()
200 unsigned int* inputDim =
new unsigned int[3];
201 inputDim[0] = ELEMENTS;
202 inputDim[1] = SAMPLES;
204 m_BeamformingFilter =
mitk::BeamformingFilter::New(createConfig(
false, inputDim, mitk::BeamformingSettings::BeamformingAlgorithm::DAS));
210 void testBeamformingGPU_DAS()
213 unsigned int* inputDim =
new unsigned int[3];
214 inputDim[0] = ELEMENTS;
215 inputDim[1] = SAMPLES;
223 void testBeamformingCPU_sDMAS()
225 MITK_INFO <<
"Started sDMAS test on CPU";
226 unsigned int* inputDim =
new unsigned int[3];
227 inputDim[0] = ELEMENTS;
228 inputDim[1] = SAMPLES;
230 m_BeamformingFilter =
mitk::BeamformingFilter::New(createConfig(
false, inputDim, mitk::BeamformingSettings::BeamformingAlgorithm::sDMAS));
236 void testBeamformingGPU_sDMAS()
238 MITK_INFO <<
"Started sDMAS test on GPU";
239 unsigned int* inputDim =
new unsigned int[3];
240 inputDim[0] = ELEMENTS;
241 inputDim[1] = SAMPLES;
243 m_BeamformingFilter =
mitk::BeamformingFilter::New(createConfig(
true, inputDim, mitk::BeamformingSettings::BeamformingAlgorithm::sDMAS));
249 void testBeamformingCPU_DMAS()
252 unsigned int* inputDim =
new unsigned int[3];
253 inputDim[0] = ELEMENTS;
254 inputDim[1] = SAMPLES;
256 m_BeamformingFilter =
mitk::BeamformingFilter::New(createConfig(
false, inputDim, mitk::BeamformingSettings::BeamformingAlgorithm::DMAS));
262 void testBeamformingGPU_DMAS()
265 unsigned int* inputDim =
new unsigned int[3];
266 inputDim[0] = ELEMENTS;
267 inputDim[1] = SAMPLES;
269 m_BeamformingFilter =
mitk::BeamformingFilter::New(createConfig(
true, inputDim, mitk::BeamformingSettings::BeamformingAlgorithm::DMAS));
MITK_TEST_SUITE_REGISTRATION(mitkImageToItk)
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
ImageReadAccessor class to get locked read access for a particular image part.