28 #include "itkImageDuplicator.h"
29 #include "itkPermuteAxesImageFilter.h"
30 #include "itkTileImageFilter.h"
31 #include <itkExtractImageFilter.h>
32 #include <itkImageFileWriter.h>
33 #include <itkRGBPixel.h>
34 #include <itkResampleImageFilter.h>
35 #include <itkVTKImageImport.h>
37 #include <itkDirectory.h>
38 #include <itksys/SystemTools.hxx>
40 #include <vtkCellArray.h>
41 #include <vtkFreeTypeStringToImage.h>
42 #include <vtkImageData.h>
43 #include <vtkTextProperty.h>
44 #include <vtkUnicodeString.h>
49 #include "itkRescaleIntensityImageFilter.h"
57 typedef itk::Image<itk::RGBPixel<PixelType>, 2>
RGB2DImage;
61 typedef std::vector<mitk::Image::Pointer>
ImageList;
69 if (dir->Load(folder.c_str()))
71 int n = dir->GetNumberOfFiles();
72 for (
int r = 0; r < n; r++)
74 std::string
filename = dir->GetFile(r);
75 if (filename ==
"." || filename ==
"..")
78 if (!itksys::SystemTools::FileExists(filename.c_str()))
81 if (postfix.compare(filename.substr(filename.length() - postfix.length())) == 0)
82 fileList.push_back(filename);
85 std::sort(fileList.begin(), fileList.end());
89 class mitkProgressionVisualization
92 mitkProgressionVisualization() {}
101 unsigned int *dim = grayImage->GetDimensions();
102 rgbImage->Initialize(mitk::MakePixelType<PixelType, RGBPixelType, 3>(), 3, dim);
103 rgbImage->SetGeometry(grayImage->GetGeometry());
110 typedef itk::RescaleIntensityImageFilter<itk::Image<InputPixelType, 3>, itk::Image<PixelType, 3>> RescaleFilterType;
112 rescaleFilter->SetInput(itkGrayImage);
113 rescaleFilter->SetOutputMinimum(0);
114 rescaleFilter->SetOutputMaximum(255 * 255);
115 rescaleFilter->Update();
121 for (idx[2] = 0; (
unsigned int)idx[2] < dim[2]; idx[2]++)
123 for (idx[1] = 0; (
unsigned int)idx[1] < dim[1]; idx[1]++)
125 for (idx[0] = 0; (
unsigned int)idx[0] < dim[0]; idx[0]++)
127 value.Fill(rescaleFilter->GetOutput()->GetPixel(idx));
128 writeAcc.SetPixelByIndex(idx, value);
140 float color[3] = {1, 1, 1};
142 prop->SetColor(color[0], color[1], color[2]);
143 prop->SetFontSize(40);
144 prop->SetOpacity(opacity);
145 textImage->AllocateScalars(VTK_UNSIGNED_SHORT, 3);
146 freetype->RenderString(prop, vtkUnicodeString::from_utf8(text.c_str()), 72, textImage);
147 textImage->Modified();
149 int *extent = textImage->GetExtent();
153 RGB2DImage::IndexType start;
155 RGB2DImage::SizeType size;
160 RGB2DImage::RegionType region(start, size);
161 itkImage->SetRegions(region);
162 itkImage->Allocate();
163 RGB2DImage::IndexType idx;
165 for (
unsigned int y = 0; y < size[1]; y++)
167 for (
unsigned int x = 0; x < size[0]; x++)
172 values[0] = pixel[1];
173 values[1] = pixel[1];
174 values[2] = pixel[1];
179 itkImage->SetPixel(idx, values);
183 typedef itk::PermuteAxesImageFilter<RGB2DImage> PermuteAxesImageFilterType;
185 itk::FixedArray<unsigned int, 2> order;
190 permuteAxesFilter->SetInput(itkImage);
191 permuteAxesFilter->SetOrder(order);
192 permuteAxesFilter->Update();
195 itkResultImage->SetRegions(region);
196 itkResultImage->Allocate();
198 itkResultImage->Graft(permuteAxesFilter->GetOutput());
200 return itkResultImage;
215 unsigned int *dim = rgbImage->GetDimensions();
221 itk::RGBPixel<PixelType> value;
222 unsigned short overlayVal = 0;
224 for (idx[2] = 0; (
unsigned int)idx[2] < dim[2]; idx[2]++)
226 for (idx[1] = 0; (
unsigned int)idx[1] < dim[1]; idx[1]++)
228 for (idx[0] = 0; (
unsigned int)idx[0] < dim[0]; idx[0]++)
230 overlayVal = 255 * itkOverlayImage->GetPixel(idx);
231 value = writeAcc.GetPixelByIndex(idx);
232 value[0] =
std::min((
int)(value[0] + overlayVal * color[0]), 254 * 255);
233 value[1] =
std::min((
int)(value[1] + overlayVal * color[1]), 254 * 255);
234 value[2] =
std::min((
int)(value[2] + overlayVal * color[2]), 254 * 255);
235 writeAcc.SetPixelByIndex(idx, value);
241 itk::Image<itk::RGBPixel<PixelType>, 2>
::Pointer ExtractSlice(
245 typedef itk::Image<RGBPixelType, 2> OutputImageType;
248 dim[0] = itkImage->GetLargestPossibleRegion().GetSize()[0];
249 dim[1] = itkImage->GetLargestPossibleRegion().GetSize()[1];
250 dim[2] = itkImage->GetLargestPossibleRegion().GetSize()[2];
253 itk::Size<3> desiredSize;
256 desiredStart.Fill(0);
257 desiredStart[2] = sliceNo;
259 desiredSize[0] = dim[0];
260 desiredSize[1] = dim[1];
263 itk::ImageRegion<3> desiredRegion(desiredStart, desiredSize);
268 extractSlice->SetInput(itkImage);
269 extractSlice->SetExtractionRegion(desiredRegion);
270 extractSlice->SetDirectionCollapseToIdentity();
271 extractSlice->Update();
273 return extractSlice->GetOutput();
277 static std::string
GetName(std::string fileName, std::string suffix =
"_T2.nrrd")
279 fileName = itksys::SystemTools::GetFilenameName(fileName);
280 return fileName.substr(0, fileName.length() - suffix.length() - 11);
283 static std::string
GetDate(std::string fileName, std::string suffix =
"_T2.nrrd")
285 fileName = itksys::SystemTools::GetFilenameName(fileName);
286 fileName = fileName.substr(fileName.length() - suffix.length() - 10, 10);
293 for (
unsigned int i = 0; i < files.size(); ++i)
300 int main(
int argc,
char *argv[])
306 parser.
setTitle(
"Tumor Progression Mapping");
309 parser.
setDescription(
"Convert a set of co-registered and resampled follow-up images into a 2D png overview (and "
310 "optionally in a 4D NRRD Volume).\nNaming convecntion of files is "
311 "IDENTIFIER_YYYY-MM-DD_MODALITY.nrrd");
327 map<string, us::Any> parsedArgs = parser.
parseArguments(argc, argv);
329 if (parsedArgs.size() == 0)
333 if (parsedArgs.count(
"help") || parsedArgs.count(
"h"))
339 std::string outputFile;
340 std::string inputFolder;
342 if (parsedArgs.count(
"input") || parsedArgs.count(
"i"))
344 inputFolder =
us::any_cast<
string>(parsedArgs[
"input"]) +
"/";
347 if (parsedArgs.count(
"output") || parsedArgs.count(
"o"))
349 outputFile =
us::any_cast<
string>(parsedArgs[
"output"]);
356 if (parsedArgs.count(
"skip") || parsedArgs.count(
"k"))
361 if (parsedArgs.count(
"interval") || parsedArgs.count(
"n"))
366 if (parsedArgs.count(
"opacity") || parsedArgs.count(
"c"))
374 std::string refPattern;
375 std::string segPattern;
377 if (parsedArgs.count(
"morphology") || parsedArgs.count(
"m"))
379 refPattern =
us::any_cast<std::string>(parsedArgs[
"morphology"]);
384 if (parsedArgs.count(
"segmentation") || parsedArgs.count(
"s"))
386 segPattern =
us::any_cast<std::string>(parsedArgs[
"segmentation"]);
390 if (parsedArgs.count(
"blanked") || parsedArgs.count(
"b"))
395 typedef itk::Image<RGBPixelType, 2> OutputImageType;
398 mitkProgressionVisualization progressVis;
405 if (segFiles.size() > 0 && blank ==
false)
413 color[0] = 200 * opacity;
419 itk::FixedArray<unsigned int, 2> layout;
420 unsigned int noOfTimeSteps = morphImages.size();
421 layout[0] = noOfTimeSteps;
423 tileFilter->SetLayout(layout);
427 std::string fileName = morphFiles.at(0);
431 std::string volumeFile;
433 if (parsedArgs.count(
"4dVolume") || parsedArgs.count(
"v"))
435 volumeFile =
us::any_cast<
string>(parsedArgs[
"4dVolume"]);
436 if (volumeFile !=
"")
438 unsigned int *dims =
new unsigned int[4];
442 dims[3] = morphImages.size();
444 merged4D->Initialize(referenceImg->
GetPixelType(), 4, dims);
445 merged4D->GetTimeGeometry()->Expand(noOfTimeSteps);
450 unsigned int sliceMaxAxial = dim[2];
456 for (
unsigned int i = 0; i < noOfTimeSteps; i++)
458 MITK_INFO <<
"File : " << i <<
" of /" << noOfTimeSteps;
459 int currentSliceNo = 0;
462 fileName = morphFiles.at(i);
463 morphImage = morphImages.at(i);
466 if (volumeFile !=
"")
473 merged4D->SetVolume(readAc.
GetData(), i);
477 rgbImage = progressVis.ConvertToRGBImage(morphImage);
481 color[0] = 200 * opacity;
485 segmentationImage = segImages.at(i);
486 if (segmentationImage != NULL)
489 progressVis.AddColouredOverlay(rgbImage, segmentationImage, color);
495 MITK_INFO <<
"Skipping retro view in first time step";
501 color[1] = 200 * opacity;
505 MITK_INFO <<
"-- Add Overlay of next Step";
506 progressVis.AddColouredOverlay(rgbImage, nextSeg, color);
512 for (
int slice = sliceMaxAxial - skip - 1; slice > skip; slice -= interval)
518 typedef itk::ImageDuplicator<InputImageType> DuplicatorType;
520 duplicator->SetInputImage(itkImage);
521 duplicator->Update();
522 itkImage2 = duplicator->GetOutput();
525 extractedSlice->Graft(progressVis.ExtractSlice(itkImage2, slice));
526 tileFilter->SetInput(((currentSliceNo + 1) * (noOfTimeSteps) + i), extractedSlice);
528 tileFilter->SetInput(i, progressVis.TextAsImage(
GetDate(fileName)));
535 tileFilter->Update();
538 typedef itk::ImageFileWriter<OutputImageType> WriterType;
540 writer->SetInput(tileFilter->GetOutput());
541 std::string patientName;
543 patientName =
GetName(fileName);
546 writer->SetFileName(outputFile);
548 writer->SetFileName(outputFile);
551 if (volumeFile !=
"")
const Point3D GetOrigin() const
Get the origin, e.g. the upper-left corner of the plane.
Gives locked and index-based write access for a particular image part. The class provides several set...
static void Save(const mitk::BaseData *data, const std::string &path)
Save a mitk::BaseData instance.
itk::SmartPointer< Self > Pointer
Gives locked and index-based read access for a particular image part. The class provides several set-...
static std::string GetName(std::string fileName, std::string suffix="_T2.nrrd")
void setContributor(std::string contributor)
std::vector< mitk::Image::Pointer > ImageList
int main(int argc, char *argv[])
ValueType * any_cast(Any *operand)
const mitk::Vector3D GetSpacing() const
Get the spacing (size of a pixel).
std::vector< std::string > FileList
std::map< std::string, us::Any > parseArguments(const StringContainerType &arguments, bool *ok=nullptr)
static std::string GetDate(std::string fileName, std::string suffix="_T2.nrrd")
unsigned int * GetDimensions() const
Get the sizes of all dimensions as an integer-array.
itk::Image< double, 3 > InputImageType
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)
static const std::string filename
Image class for storing images.
static ImageList LoadPreprocessedFiles(FileList files)
const mitk::PixelType GetPixelType(int n=0) const
Returns the PixelType of channel n.
void setCategory(std::string category)
const TPixel * GetData() const
Gives const access to the data.
static FileList CreateFileList(std::string folder, std::string postfix)
Create list of all files in provided folder ending with same postfix.
itk::RGBPixel< float > Color
Color Standard RGB color typedef (float)
void setArgumentPrefix(const std::string &longPrefix, const std::string &shortPrefix)
itk::Image< itk::RGBPixel< PixelType >, 2 > RGB2DImage
void MITKCORE_EXPORT CastToItkImage(const mitk::Image *mitkImage, itk::SmartPointer< ItkOutputImageType > &itkOutputImage)
Cast an mitk::Image to an itk::Image with a specific type.
itk::RGBPixel< PixelType > RGBPixelType
std::string helpText() const
void setTitle(std::string title)
mitk::BaseGeometry * GetGeometry(int t=0) const
Return the geometry, which is a TimeGeometry, of the data as non-const pointer.
void setDescription(std::string description)
static mitk::Image::Pointer LoadImage(const std::string &path)
LoadImage Convenience method to load an arbitrary mitkImage.
section MAP_FRAME_Mapper_Settings Mapper settings For the mapping of corrected images
mitk::AffineTransform3D * GetIndexToWorldTransform()
Get the transformation used to convert from index to world coordinates.
static itkEventMacro(BoundingShapeInteractionEvent, itk::AnyEvent) class MITKBOUNDINGSHAPE_EXPORT BoundingShapeInteractor Pointer New()
Basic interaction methods for mitk::GeometryData.