20 #include <boost/algorithm/string.hpp> 33 if ((inputImage->GetDimension() != 4))
35 mitkThrow() <<
"mitk::CESTImageNormalizationFilter:GenerateData works only with 4D images, sorry.";
46 resultTimeGeometry->Expand(numberOfNonM0s);
48 for (
unsigned int index = 0; index < numberOfNonM0s; ++index)
50 resultTimeGeometry->SetTimeStepGeometry(originalTimeGeometry->GetGeometryCloneForTimeStep(
m_NonM0Indices.at(index)), index);
52 resultMitkImage->SetTimeGeometry(resultTimeGeometry);
54 resultMitkImage->SetPropertyList(this->
GetInput()->GetPropertyList()->
Clone());
57 resultMitkImage->GetPropertyList()->DeleteProperty(
"DICOM.0008.0018");
58 resultMitkImage->GetPropertyList()->DeleteProperty(
"DICOM.0020.000D");
59 resultMitkImage->GetPropertyList()->DeleteProperty(
"DICOM.0020.000E");
65 std::vector<double> result;
69 std::string offsets =
"";
70 std::vector<std::string> parts;
73 boost::algorithm::trim(offsets);
74 boost::split(parts, offsets, boost::is_any_of(
" "));
76 for (
auto part : parts)
78 std::istringstream iss(part);
79 iss.imbue(std::locale(
"C"));
91 template <
typename TPixel,
unsigned int VImageDimension>
94 typedef itk::Image<TPixel, VImageDimension>
ImageType;
100 std::vector<unsigned int> mZeroIndices;
101 std::stringstream offsetsWithoutM0;
102 offsetsWithoutM0.imbue(std::locale(
"C"));
104 for (
unsigned int index = 0; index < offsets.size(); ++index)
106 if ((offsets.at(index) < -299) || (offsets.at(index) > 299))
108 mZeroIndices.push_back(index);
112 offsetsWithoutM0 << offsets.at(index) <<
" ";
118 typename ImageType::RegionType targetEntireRegion = image->GetLargestPossibleRegion();
120 resultImage->SetRegions(targetEntireRegion);
121 resultImage->Allocate();
122 resultImage->FillBuffer(0);
124 unsigned int numberOfTimesteps = image->GetLargestPossibleRegion().GetSize(3);
126 typename ImageType::RegionType lowerMZeroRegion = image->GetLargestPossibleRegion();
127 lowerMZeroRegion.SetSize(3, 1);
128 typename ImageType::RegionType upperMZeroRegion = image->GetLargestPossibleRegion();
129 upperMZeroRegion.SetSize(3, 1);
130 typename ImageType::RegionType sourceRegion = image->GetLargestPossibleRegion();
131 sourceRegion.SetSize(3, 1);
133 targetRegion.SetSize(3, 1);
134 unsigned int targetTimestep = 0;
135 for (
unsigned int sourceTimestep = 0; sourceTimestep < numberOfTimesteps; ++sourceTimestep)
137 unsigned int lowerMZeroIndex = mZeroIndices[0];
138 unsigned int upperMZeroIndex = mZeroIndices[0];
139 for (
unsigned int loop = 0; loop < mZeroIndices.size(); ++loop)
141 if (mZeroIndices[loop] <= sourceTimestep)
143 lowerMZeroIndex = mZeroIndices[loop];
145 if (mZeroIndices[loop] > sourceTimestep)
147 upperMZeroIndex = mZeroIndices[loop];
151 bool isMZero = (lowerMZeroIndex == sourceTimestep);
154 if (lowerMZeroIndex == upperMZeroIndex)
160 weight = 1.0 - double(sourceTimestep - lowerMZeroIndex) / double(upperMZeroIndex - lowerMZeroIndex);
170 lowerMZeroRegion.SetIndex(3, lowerMZeroIndex);
171 upperMZeroRegion.SetIndex(3, upperMZeroIndex);
172 sourceRegion.SetIndex(3, sourceTimestep);
173 targetRegion.SetIndex(3, targetTimestep);
175 itk::ImageRegionConstIterator<ImageType> lowerMZeroIterator(image, lowerMZeroRegion);
176 itk::ImageRegionConstIterator<ImageType> upperMZeroIterator(image, upperMZeroRegion);
177 itk::ImageRegionConstIterator<ImageType> sourceIterator(image, sourceRegion);
178 itk::ImageRegionIterator<OutputImageType> targetIterator(resultImage.GetPointer(), targetRegion);
180 while (!sourceIterator.IsAtEnd())
182 double normalizationFactor = weight * lowerMZeroIterator.Get() + (1.0 - weight) * upperMZeroIterator.Get();
185 targetIterator.Set(0);
189 targetIterator.Set(
double(sourceIterator.Get()) / normalizationFactor);
192 ++lowerMZeroIterator;
193 ++upperMZeroIterator;
204 mitk::CastToMitkImage<OutputImageType>(resultImage, resultMitkImage);
214 itkDebugMacro(<<
"GenerateOutputInformation()");
221 for (
auto offset : offsets)
223 if (offset < -299 || offset > 299)
#define AccessFixedDimensionByItk(mitkImage, itkImageTypeFunction, dimension)
Access a mitk-image with known dimension by an itk-image.
itk::Image< unsigned char, 3 > ImageType
CESTImageNormalizationFilter()
standard constructor
void GenerateData() override
Method generating the output of this filter. Called in the updated process of the pipeline...
~CESTImageNormalizationFilter() override
standard destructor
const mitk::TimeGeometry * GetTimeGeometry() const
Return the TimeGeometry of the data as const pointer.
void NormalizeTimeSteps(const itk::Image< TPixel, VImageDimension > *image)
itk::ImageRegion< RegionDimension > RegionType
std::vector< unsigned int > m_NonM0Indices
non M0 indices
Image class for storing images.
mitk::Image OutputImageType
Some convenient typedefs.
std::string m_RealOffsets
Offsets without M0s.
mitk::Image::Pointer image
MITKCEST_EXPORT bool IsNotNormalizedCESTImage(const Image *cestImage)
mitk::PropertyList::Pointer GetPropertyList() const
Get the data's property list.
void GenerateOutputInformation() override
Method generating the output information of this filter (e.g. image dimension, image type...
InputImageType * GetInput(void)
MITKNEWMODULE_EXPORT bool Equal(mitk::ExampleDataStructure *leftHandSide, mitk::ExampleDataStructure *rightHandSide, mitk::ScalarType eps, bool verbose)
Returns true if the example data structures are considered equal.
std::vector< double > ExtractOffsets(const mitk::Image *image)
OutputType * GetOutput()
Get the output data of this image source object.
static const std::string m_OffsetsPropertyName
name of the property for the offsets, including normalization offsets