88
99#include < animaReadWriteFunctions.h>
1010
11+ /* *
12+ * @brief Converts an input image (either vectorial or not) into a mask
13+ * The output mask will be 0 in the voxels where the input image is 0 (or a null vector) and 1 elsewhere
14+ */
1115int main (int argc, char **argv)
1216{
1317 TCLAP::CmdLine cmd (" INRIA / IRISA - VisAGeS/Empenn Team" , ' ' ,ANIMA_VERSION);
1418
19+ // Define arguments
1520 TCLAP::ValueArg<std::string> inArg (" i" ," inputfile" ," input image" ,true ," " ," input image" ,cmd);
1621 TCLAP::ValueArg<std::string> outArg (" o" ," outputfile" ," output mask" ,true ," " ," output mask" ,cmd);
1722
23+ // Try to parse
1824 try
1925 {
2026 cmd.parse (argc,argv);
@@ -25,84 +31,113 @@ int main(int argc, char **argv)
2531 return (1 );
2632 }
2733
28- typedef itk::Image <unsigned int ,3 > ImageType;
34+ // Define types
35+ typedef itk::Image <double ,3 > ImageType;
2936 typedef itk::Image <double ,4 > Image4DType;
3037 typedef itk::VectorImage <double ,3 > VectorImageType;
3138
39+ // Read input image
3240 itk::ImageIOBase::Pointer imageIO = itk::ImageIOFactory::CreateImageIO (inArg.getValue ().c_str (),
3341 itk::IOFileModeEnum::ReadMode);
3442
3543 imageIO->SetFileName (inArg.getValue ());
3644 imageIO->ReadImageInformation ();
3745
46+ // Initialize the output image (which is a mask) and allocate memory
47+ ImageType::Pointer outImage = ImageType::New ();
48+
49+ // Determine if the input image is a vector image (each voxel value is a vector) or not
3850 bool vectorImage = (imageIO->GetNumberOfComponents () > 1 );
3951
4052 if (vectorImage)
4153 {
42- // Vectorial case
54+ // Case of a vector image
55+
56+ // Read input image and store in the correct format
4357 VectorImageType::Pointer image = anima::readImage <VectorImageType> (inArg.getValue ());
4458
45- ImageType::Pointer outImage = ImageType::New ();
59+ // Set the output image with the same properties as the input image
4660 outImage->Initialize ();
47- // outImage->SetNumberOfComponentsPerPixel(image->GetNumberOfComponentsPerPixel());
4861 outImage->SetDirection (image->GetDirection ());
4962 outImage->SetSpacing (image->GetSpacing ());
5063 outImage->SetOrigin (image->GetOrigin ());
5164
65+ // Allocate the correct size for output image. region (image->GetLargestPossibleRegion()) is the whole image
5266 VectorImageType::RegionType region = image->GetLargestPossibleRegion ();
5367 outImage->SetRegions (region);
5468 outImage->Allocate ();
5569
70+ // Create a vector with as many components as there are for each voxel, and with each component equal to 0
5671 VectorImageType::PixelType zeroVec (image->GetNumberOfComponentsPerPixel ());
5772 zeroVec.Fill (0 );
5873
74+ // Create iterators on input and output images
5975 itk::ImageRegionIterator <VectorImageType> inItr (image,region);
6076 itk::ImageRegionIterator <ImageType> outItr (outImage,outImage->GetLargestPossibleRegion ());
6177
78+ // Main algorithm
6279 while (!outItr.IsAtEnd ())
6380 {
6481 if (inItr.Get () == zeroVec)
82+ {
83+ // The voxel in the input image is a constant vector equal to 0, so this voxel in the output mask will be 0.
6584 outItr.Set (0 );
85+ }
6686 else
87+ {
88+ // The voxel in the input image is not a constant vector equal to 0, so this voxel in the output mask will be 1.
6789 outItr.Set (1 );
90+ }
6891
92+ // Move to following voxel
6993 ++inItr;
7094 ++outItr;
7195 }
72-
73- anima::writeImage <ImageType> (outArg.getValue (),outImage);
74-
75- return EXIT_SUCCESS;
7696 }
97+ else
98+ {
99+ // Case of a non-vector image
100+
101+ // Read input image and store in the correct format
102+ ImageType::Pointer image = anima::readImage <ImageType> (inArg.getValue ());
77103
78- ImageType::Pointer image = anima::readImage <ImageType> (inArg.getValue ());
79-
80- ImageType::Pointer outImage = ImageType::New ();
81- outImage->Initialize ();
82- outImage->SetDirection (image->GetDirection ());
83- outImage->SetSpacing (image->GetSpacing ());
84- outImage->SetOrigin (image->GetOrigin ());
104+ // Set the output image with the same properties as the input image
105+ outImage->Initialize ();
106+ outImage->SetDirection (image->GetDirection ());
107+ outImage->SetSpacing (image->GetSpacing ());
108+ outImage->SetOrigin (image->GetOrigin ());
85109
86- ImageType::RegionType largestRegion = image->GetLargestPossibleRegion ();
87- outImage->SetRegions (largestRegion);
88- outImage->Allocate ();
89- outImage->FillBuffer (0.0 );
110+ // Allocate the correct size for output image. largestRegion (image->GetLargestPossibleRegion()) is the whole image
111+ ImageType::RegionType largestRegion = image->GetLargestPossibleRegion ();
112+ outImage->SetRegions (largestRegion);
113+ outImage->Allocate ();
114+ outImage->FillBuffer (0.0 );
90115
91- itk::ImageRegionIterator <ImageType> inItr (image,image->GetLargestPossibleRegion ());
92- itk::ImageRegionIterator <ImageType> outItr (outImage,outImage->GetLargestPossibleRegion ());
116+ // Create iterators on input and output images
117+ itk::ImageRegionIterator <ImageType> inItr (image,image->GetLargestPossibleRegion ());
118+ itk::ImageRegionIterator <ImageType> outItr (outImage,outImage->GetLargestPossibleRegion ());
93119
94- while (!outItr.IsAtEnd ())
95- {
96- if (inItr.Get () == 0.0 )
97- outItr.Set (0 );
98- else
99- outItr.Set (1 );
120+ // Main algorithm
121+ while (!outItr.IsAtEnd ())
122+ {
123+ if (inItr.Get () == 0.0 )
124+ {
125+ // The voxel in the input image is 0, so this voxel in the output mask will be 0.
126+ outItr.Set (0 );
127+ }
128+ else
129+ {
130+ // The voxel in the input image is not 0, so this voxel in the output mask will be 1.
131+ outItr.Set (1 );
132+ }
100133
101- ++inItr;
102- ++outItr;
134+ // Move to following voxel
135+ ++inItr;
136+ ++outItr;
137+ }
103138 }
104139
140+ // Write output image and exit
105141 anima::writeImage <ImageType> (outArg.getValue (),outImage);
106-
107142 return EXIT_SUCCESS;
108143}
0 commit comments