17 #include "itksys/SystemTools.hxx" 18 #include "itkImageRegionConstIteratorWithIndex.h" 19 #include "itkCastImageFilter.h" 20 #include "itkExtractImageFilter.h" 57 struct DumpIndexCompare
65 else if (lhs[0] > rhs[0])
74 else if (lhs[1] > rhs[1])
79 return lhs[2] < rhs[2];
91 parser.
setDescription(
"MiniApp that allows to dump the pixel values of all passed files into a csv. The region of dumping can defined by a mask. All images (and mask) must have the same geometrie.");
107 "where to save the csv.",
116 "captions",
"c",
mitkCommandLineParser::StringList,
"Captions of image columns",
"If provided the pixel columns of the csv will be named according to the passed values instead of using the image pathes. Number of images and names must be equal.",
us::Any(),
false);
124 if (parsedArgs.size() == 0)
132 if (parsedArgs.count(
"mask"))
139 if (parsedArgs.count(
"captions"))
147 template <
typename TPixel,
unsigned int VImageDimension >
149 const itk::Image< TPixel, VImageDimension > *
image)
157 template <
typename TPixel,
unsigned int VImageDimension >
159 const itk::Image< TPixel, VImageDimension > *
image,
160 InternalImageType::Pointer& internalImage)
162 typedef itk::Image< TPixel, VImageDimension >
ImageType;
167 typename ImageType::SpacingType imageSpacing = image->GetSpacing();
168 typename ImageType::PointType zeroPoint; zeroPoint.Fill(0.0);
169 if ((zeroPoint + imageSpacing).SquaredEuclideanDistanceTo((zeroPoint +
relevantSpacing)) >
172 mitkThrow() <<
"Images need to have same spacing! (Image spacing: " << imageSpacing
177 typename ImageType::DirectionType imageDirection = image->GetDirection();
178 for (
unsigned int i = 0; i < imageDirection.RowDimensions; ++i)
180 for (
unsigned int j = 0; j < imageDirection.ColumnDimensions; ++j)
183 if (fabs(differenceDirection) > 1e-6)
186 mitkThrow() <<
"Images need to have same direction! (Image direction: " 187 << imageDirection <<
"; relevant direction: " << relevantDirection <<
")";
193 typename ImageType::PointType imageOrigin = image->GetOrigin();
194 if (imageOrigin.SquaredEuclideanDistanceTo(
relevantOrigin) > 1e-6)
197 mitkThrow() <<
"Image need to have same spacing! (Image spacing: " 198 << imageSpacing <<
"; relevant spacing: " <<
relevantOrigin <<
")";
201 typename ImageType::RegionType imageRegion = image->GetLargestPossibleRegion();
205 mitkThrow() <<
"Images need to have same region! (Image region: " 210 typedef itk::ExtractImageFilter<ImageType, ImageType> ExtractFilterType;
211 typename ExtractFilterType::Pointer extractFilter = ExtractFilterType::New();
212 typedef itk::CastImageFilter<ImageType, InternalImageType> CastFilterType;
213 typename CastFilterType::Pointer castFilter = CastFilterType::New();
215 extractFilter->SetInput(image);
217 castFilter->SetInput(extractFilter->GetOutput());
218 castFilter->Update();
219 internalImage = castFilter->GetOutput();
222 template <
typename TPixel,
unsigned int VImageDimension >
224 const itk::Image< TPixel, VImageDimension > *
image)
226 typedef itk::Image< TPixel, VImageDimension >
ImageType;
228 itk::ImageRegionConstIteratorWithIndex<ImageType> it(image,
relevantRegion);
232 while (!it.IsAtEnd())
234 if (mask.IsNull() || it.Get() > 0)
238 const auto index = it.GetIndex();
242 double value = imagePos.second->GetPixel(index);
243 values.push_back(value);
256 InternalImageType::Pointer internalImage;
258 for (
unsigned int i = 0; i < image->
GetTimeSteps(); ++i)
261 imageTimeSelector->SetInput(image);
262 imageTimeSelector->SetTimeNr(i);
263 imageTimeSelector->UpdateLargestPossibleRegion();
272 std::stringstream stream;
273 stream <<
"[" << i <<
"]";
274 map.insert(std::make_pair(stream.str(), internalImage));
282 if (mask.IsNotNull() && mask->GetTimeSteps() > 1)
285 "Pixel Dumper: Selected mask has multiple timesteps. Only use first timestep to mask the pixel dumping." << std::endl;
288 maskTimeSelector->SetInput(mask);
289 maskTimeSelector->SetTimeNr(0);
290 maskTimeSelector->UpdateLargestPossibleRegion();
291 mask = maskTimeSelector->GetOutput();
296 if (mask.IsNotNull())
305 catch (
const std::exception& e)
307 std::cerr <<
"Error extracting image geometry. Error text: " << e.what();
312 for (
unsigned int index = 0; index <
images.size(); ++index)
318 if (conversionMap.size() == 1)
322 else if (conversionMap.size() > 1)
324 for (
auto& pos : conversionMap)
326 std::stringstream namestream;
327 namestream <<
captions[index] <<
" " << pos.first;
328 internalImages.insert(std::make_pair(namestream.str(), pos.second));
332 catch (
const std::exception& e)
334 std::stringstream errorStr;
335 errorStr <<
"Inconsistent image \"" <<
captions[index] <<
"\" will be excluded from the collection. Error: " << e.what();
336 std::cerr << errorStr.str() << std::endl;
341 if (mask.IsNotNull())
354 std::ofstream resultfile;
356 resultfile <<
"x,y,z";
359 resultfile <<
"," << aImage.first;
362 resultfile << std::endl;
366 resultfile << dumpPos.first[0] <<
"," << dumpPos.first[1] <<
"," << dumpPos.first[2];
368 for(
auto d : dumpPos.second)
370 resultfile <<
"," << d;
373 resultfile << std::endl;
377 int main(
int argc,
char* argv[])
381 const std::map<std::string, us::Any>& parsedArgs = parser.
parseArguments(argc, argv);
391 if (parsedArgs.count(
"help") || parsedArgs.count(
"h"))
399 std::cerr <<
"Cannot dump images. Number of given captions does not equal number of given images.";
406 std::cout <<
"Load images:" << std::endl;
409 std::cout <<
"Input: " << path << std::endl;
410 auto image = mitk::IOUtil::Load<mitk::Image>(path, &readerFilterFunctor);
417 mask = mitk::IOUtil::Load<mitk::Image>(
maskFileName, &readerFilterFunctor);
418 std::cout <<
"Mask: " << maskFileName << std::endl;
422 std::cout <<
"Mask: none" << std::endl;
428 std::cout <<
"Processing finished." << std::endl;
432 catch (
const itk::ExceptionObject& e)
437 catch (
const std::exception& e)
444 MITK_ERROR <<
"Unexpected error encountered.";
Option callback functor with a preference list/ black list option selection strategy.
void DoMaskedCollecting(const itk::Image< TPixel, VImageDimension > *image)
std::map< DumpIndexType, DumpedValuesType, DumpIndexCompare > DumpPixelMapType
std::map< std::string, InternalImageType::Pointer > InternalImageMapType
#define AccessFixedDimensionByItk(mitkImage, itkImageTypeFunction, dimension)
Access a mitk-image with known dimension by an itk-image.
itk::Image< unsigned char, 3 > ImageType
void setContributor(std::string contributor)
ValueType * any_cast(Any *operand)
mitkCommandLineParser::StringContainerType captions
void addArgument(const std::string &longarg, const std::string &shortarg, Type type, const std::string &argLabel, const std::string &argHelp=std::string(), const us::Any &defaultValue=us::Any(), bool optional=true, bool ignoreRest=false, bool deprecated=false, mitkCommandLineParser::Channel channel=mitkCommandLineParser::Channel::None)
InternalImageType::PointType relevantOrigin
std::map< std::string, us::Any > parseArguments(const StringContainerType &arguments, bool *ok=nullptr)
mitk::Image::Pointer mask
InternalImageType::SpacingType relevantSpacing
void DoInternalImageConversion(const itk::Image< TPixel, VImageDimension > *image, InternalImageType::Pointer &internalImage)
itk::ImageRegion< 3 > relevantRegion
InternalImageType::DirectionType relevantDirection
void setupParser(mitkCommandLineParser &parser)
InternalImageMapType internalImages
void ExtractRelevantInformation(const itk::Image< TPixel, VImageDimension > *image)
DumpPixelMapType dumpedPixels
Image class for storing images.
std::string helpText() const
itk::Index< 3 > DumpIndexType
void setCategory(std::string category)
mitk::Image::Pointer image
MITKMATCHPOINTREGISTRATION_EXPORT ResultImageType::Pointer map(const InputImageType *input, const RegistrationType *registration, bool throwOnOutOfInputAreaError=false, const double &paddingValue=0, const ResultImageGeometryType *resultGeometry=nullptr, bool throwOnMappingError=true, const double &errorValue=0, mitk::ImageMappingInterpolator::Type interpolatorType=mitk::ImageMappingInterpolator::Linear)
void setArgumentPrefix(const std::string &longPrefix, const std::string &shortPrefix)
#define AccessFixedDimensionByItk_1(mitkImage, itkImageTypeFunction, dimension, arg1)
mitkCommandLineParser::StringContainerType inFilenames
std::vector< mitk::ScalarType > DumpedValuesType
std::vector< std::string > StringContainerType
unsigned int GetTimeSteps() const
Get the number of time steps from the TimeGeometry As the base data has not a data vector given by it...
InternalImageMapType ConvertImageTimeSteps(mitk::Image *image)
void setTitle(std::string title)
itk::Image< mitk::ScalarType, 3 > InternalImageType
bool configureApplicationSettings(std::map< std::string, us::Any > parsedArgs)
std::vector< mitk::Image::Pointer > ImageVectorType
void setDescription(std::string description)
int main(int argc, char *argv[])
void beginGroup(const std::string &description)