16 #include <itkImageIOBase.h> 19 #include <itkImageIOBase.h> 25 m_OutputData(nullptr),
29 MITK_INFO <<
"Instantiating BeamformingFilter...";
30 this->SetNumberOfIndexedInputs(1);
31 this->SetNumberOfRequiredInputs(1);
34 #if defined(PHOTOACOUSTICS_USE_GPU) 40 MITK_INFO <<
"Instantiating BeamformingFilter...[Done]";
50 MITK_INFO <<
"Destructed BeamformingFilter";
55 Superclass::GenerateInputRequestedRegion();
76 spacing[0] =
m_Conf->GetHorizontalExtent() /
m_Conf->GetReconstructionLines() * 1000;
77 float desiredYSpacing =
m_Conf->GetReconstructionDepth() * 1000 /
m_Conf->GetSamplesPerLine();
78 float maxYSpacing =
m_Conf->GetSpeedOfSound() *
m_Conf->GetTimeSpacing() * input->GetDimension(1) /
m_Conf->GetSamplesPerLine() * 1000;
79 spacing[1] = desiredYSpacing < maxYSpacing ? desiredYSpacing : maxYSpacing;
82 unsigned int dim[] = {
m_Conf->GetReconstructionLines(),
m_Conf->GetSamplesPerLine(), input->GetDimension(2)};
83 output->Initialize(mitk::MakeScalarPixelType<float>(), 3, dim);
84 output->GetGeometry()->SetSpacing(spacing);
85 output->GetGeometry()->Modified();
86 output->SetPropertyList(input->GetPropertyList()->Clone());
94 if (!(input->GetPixelType().GetTypeAsString() ==
"scalar (float)" || input->GetPixelType().GetTypeAsString() ==
" (float)"))
96 MITK_ERROR <<
"Pixel type of input needs to be float for this filter to work.";
97 mitkThrow() <<
"Pixel type of input needs to be float for this filter to work.";
103 if (!output->IsInitialized())
106 auto begin = std::chrono::high_resolution_clock::now();
110 int progInterval = output->GetDimension(2) / 20 > 1 ? output->GetDimension(2) / 20 : 1;
113 float inputDim[2] = { (float)input->GetDimension(0), (float)input->GetDimension(1) };
114 float outputDim[2] = { (float)output->GetDimension(0), (float)output->GetDimension(1) };
116 for (
unsigned int i = 0; i < output->GetDimension(2); ++i)
124 for (
int l = 0; l < outputDim[0]; ++l)
126 for (
int s = 0; s < outputDim[1]; ++s)
132 std::thread *threads =
new std::thread[(short)outputDim[0]];
135 if (
m_Conf->GetAlgorithm() == BeamformingSettings::BeamformingAlgorithm::DAS)
143 else if (
m_Conf->GetAlgorithm() == BeamformingSettings::BeamformingAlgorithm::DMAS)
151 else if (
m_Conf->GetAlgorithm() == BeamformingSettings::BeamformingAlgorithm::sDMAS)
162 threads[
line].join();
167 if (i % progInterval == 0)
168 m_ProgressHandle((
int)((i + 1) / (
float)output->GetDimension(2) * 100),
"performing reconstruction");
172 m_InputData =
nullptr;
175 #if defined(PHOTOACOUSTICS_USE_GPU) || DOXYGEN 181 if (!(input->GetPixelType().GetTypeAsString() ==
"scalar (float)" || input->GetPixelType().GetTypeAsString() ==
" (float)"))
183 MITK_ERROR <<
"Pixel type is not float, abort";
184 mitkThrow() <<
"Pixel type is not float, abort";
189 unsigned int batchSize =
m_Conf->GetGPUBatchSize();
190 unsigned int batches = (
unsigned int)((
float)input->GetDimension(2) / batchSize) + (input->GetDimension(2) % batchSize > 0);
192 unsigned int batchDim[] = { input->GetDimension(0), input->GetDimension(1), batchSize };
193 unsigned int batchDimLast[] = { input->GetDimension(0), input->GetDimension(1), input->GetDimension(2) % batchSize };
196 if((
unsigned long)batchSize *
197 ((
unsigned long)(batchDim[0] * batchDim[1]) * 4 +
198 (
unsigned long)(
m_Conf->GetReconstructionLines() *
m_Conf->GetSamplesPerLine()) * 4)
200 (
unsigned long)(
m_Conf->GetReconstructionLines() / 2 *
m_Conf->GetSamplesPerLine()) * 2 -
201 (
unsigned long)(
m_Conf->GetReconstructionLines() *
m_Conf->GetSamplesPerLine()) * 3 * 2 -
204 MITK_ERROR <<
"device memory too small for GPU beamforming; try decreasing the batch size";
210 for (
unsigned int i = 0; i < batches; ++i)
212 m_ProgressHandle(100.f * (
float)i / (
float)batches,
"performing reconstruction");
215 unsigned int num_Slices = 1;
216 if (i == batches - 1 && (input->GetDimension(2) % batchSize > 0))
218 inputBatch->Initialize(mitk::MakeScalarPixelType<float>(), 3, batchDimLast);
219 num_Slices = batchDimLast[2];
223 inputBatch->Initialize(mitk::MakeScalarPixelType<float>(), 3, batchDim);
224 num_Slices = batchDim[2];
227 inputBatch->SetSpacing(input->GetGeometry()->GetSpacing());
229 inputBatch->SetImportVolume(&(((
float*)copy.
GetData())[input->GetDimension(0) * input->GetDimension(1) * batchSize * i]));
237 for (
unsigned int slice = 0; slice < num_Slices; ++slice)
239 output->SetImportSlice(
240 &(((
float*)out)[
m_Conf->GetReconstructionLines() *
m_Conf->GetSamplesPerLine() * slice]),
241 batchSize * i + slice, 0, 0, mitk::Image::ImportMemoryManagementType::CopyMemory);
248 std::string errorMessage =
"Caught unexpected exception ";
249 errorMessage.append(e.what());
252 float* dummyData =
new float[
m_Conf->GetReconstructionLines() *
m_Conf->GetSamplesPerLine() *
m_Conf->GetInputDim()[2]];
253 output->SetImportVolume(dummyData, 0, 0, mitk::Image::ImportMemoryManagementType::CopyMemory);
259 auto end = std::chrono::high_resolution_clock::now();
260 MITK_INFO <<
"Beamforming of " << output->GetDimension(2) <<
" Images completed in " << ((float)std::chrono::duration_cast<std::chrono::nanoseconds>(end - begin).count()) / 1000000 <<
"ms" << std::endl;
void SetRequestedRegionToLargestPossibleRegion() override
An object of this class represents an exception of MITK. Please don't instantiate exceptions manually...
Image class for storing images.
InputImageType * GetInput(void)
virtual bool IsInitialized() const
Check whether the data has been initialized, i.e., at least the Geometry and other header data has be...
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.