1 #include <itkGrayscaleErodeImageFilter.h> 2 #include <itkGrayscaleDilateImageFilter.h> 3 #include <itkGrayscaleMorphologicalClosingImageFilter.h> 4 #include <itkGrayscaleMorphologicalOpeningImageFilter.h> 5 #include <itkBinaryBallStructuringElement.h> 7 #include <tclap/CmdLine.h> 9 int main(
int argc,
char **argv)
11 TCLAP::CmdLine cmd(
"INRIA / IRISA - VisAGeS/Empenn Team",
' ',ANIMA_VERSION);
13 TCLAP::ValueArg<std::string> inArg(
"i",
"inputfile",
"Input image",
true,
"",
"input image",cmd);
14 TCLAP::ValueArg<std::string> outArg(
"o",
"outputfile",
"Output image",
true,
"",
"output image",cmd);
15 TCLAP::ValueArg<unsigned int> nbpArg(
"p",
"nbcores",
"Number of cores to run on (default: all cores)",
false,itk::MultiThreaderBase::GetGlobalDefaultNumberOfThreads(),
"Number of cores",cmd);
17 TCLAP::ValueArg<std::string> actArg(
"a",
"action",
"Action to perform ([clos], open, dil, er)",
false,
"clos",
"Action to perform",cmd);
18 TCLAP::ValueArg<double> radiusArg(
"r",
"radius",
"Radius of morphological operation (in mm by default, see -R)",
false,1,
"morphological radius",cmd);
19 TCLAP::SwitchArg radiusVoxelArg(
"R",
"r-in-voxel",
"Use the radius in voxels",cmd);
25 catch (TCLAP::ArgException& e)
27 std::cerr <<
"Error: " << e.error() <<
"for argument " << e.argId() << std::endl;
31 typedef itk::Image <double,3> ImageType;
33 typedef itk::BinaryBallStructuringElement <unsigned short, 3> BallElementType;
34 typedef itk::GrayscaleErodeImageFilter <ImageType,ImageType,BallElementType> ErodeFilterType;
35 typedef itk::GrayscaleDilateImageFilter <ImageType,ImageType,BallElementType> DilateFilterType;
36 typedef itk::GrayscaleMorphologicalClosingImageFilter <ImageType,ImageType,BallElementType> ClosingFilterType;
37 typedef itk::GrayscaleMorphologicalOpeningImageFilter <ImageType, ImageType, BallElementType> OpeningFilterType;
39 ImageType::Pointer inputImage = anima::readImage <ImageType> (inArg.getValue());
41 ImageType::Pointer resPointer;
42 BallElementType tmpBall;
44 unsigned int radiusInVoxel0 = radiusArg.getValue();
45 unsigned int radiusInVoxel1 = radiusArg.getValue();
46 unsigned int radiusInVoxel2 = radiusArg.getValue();
48 if (!radiusVoxelArg.isSet())
51 ImageType::SpacingType spacing = inputImage->GetSpacing();
52 ImageType::SpacingValueType spacing0 = spacing[0];
53 ImageType::SpacingValueType spacing1 = spacing[1];
54 ImageType::SpacingValueType spacing2 = spacing[2];
56 double radiusInVoxelD0 = radiusArg.getValue() / spacing0;
57 double radiusInVoxelD1 = radiusArg.getValue() / spacing1;
58 double radiusInVoxelD2 = radiusArg.getValue() / spacing2;
60 double radiusInVoxelD0_round = std::round(radiusInVoxelD0);
61 double radiusInVoxelD1_round = std::round(radiusInVoxelD1);
62 double radiusInVoxelD2_round = std::round(radiusInVoxelD2);
64 radiusInVoxel0 =
static_cast<unsigned int>(radiusInVoxelD0_round);
65 radiusInVoxel1 =
static_cast<unsigned int>(radiusInVoxelD1_round);
66 radiusInVoxel2 =
static_cast<unsigned int>(radiusInVoxelD2_round);
68 std::cout <<
"Image spacing: " << spacing0 <<
"*" << spacing1 <<
"*" << spacing2 << std::endl;
69 std::cout <<
"Radius: " << radiusArg.getValue() <<
" mm3 --> " <<
"process on " << radiusInVoxel0 <<
"*" << radiusInVoxel1 <<
"*" << radiusInVoxel2 <<
" voxel(s)" << std::endl;
71 double diff0 = std::abs(radiusInVoxelD0-radiusInVoxelD0_round);
72 double diff1 = std::abs(radiusInVoxelD1-radiusInVoxelD1_round);
73 double diff2 = std::abs(radiusInVoxelD2-radiusInVoxelD2_round);
77 std::cout <<
"-- Warning: operation is not complete, on dimension 0 process is performed on " << (double)(radiusInVoxel0)*spacing0 <<
" mm3 (" << radiusInVoxel0 <<
" voxel(s)) " 78 <<
"instead of " << radiusArg.getValue() <<
" mm3 (" << radiusInVoxelD0 <<
" voxel(s))" << std::endl;
83 std::cout <<
"-- Warning: operation is not complete, on dimension 1 process is performed on " << (double)(radiusInVoxel1)*spacing1 <<
" mm3 (" << radiusInVoxel1 <<
" voxel(s)) " 84 <<
"instead of " << radiusArg.getValue() <<
" mm3 (" << radiusInVoxelD1 <<
" voxel(s))" << std::endl;
89 std::cout <<
"-- Warning: operation is not complete, on dimension 2 process is performed on " << (double)(radiusInVoxel2)*spacing2 <<
" mm3 (" << radiusInVoxel2 <<
" voxel(s)) " 90 <<
"instead of " << radiusArg.getValue() <<
" mm3 (" << radiusInVoxelD2 <<
" voxel(s))" << std::endl;
94 BallElementType::SizeType ballSize;
95 ballSize[0] = radiusInVoxel0;
96 ballSize[1] = radiusInVoxel1;
97 ballSize[2] = radiusInVoxel2;
98 tmpBall.SetRadius(ballSize);
99 tmpBall.CreateStructuringElement();
101 if (actArg.getValue() ==
"er")
103 std::cout <<
"Performing erosion with radius " << radiusArg.getValue() <<
"..." << std::endl;
105 ErodeFilterType::Pointer mainFilter = ErodeFilterType::New();
106 mainFilter->SetInput(inputImage);
107 mainFilter->SetNumberOfWorkUnits(nbpArg.getValue());
108 mainFilter->SetKernel(tmpBall);
110 mainFilter->Update();
112 resPointer = mainFilter->GetOutput();
114 else if (actArg.getValue() ==
"dil")
116 std::cout <<
"Performing dilation with radius " << radiusArg.getValue() <<
"..." << std::endl;
118 DilateFilterType::Pointer mainFilter = DilateFilterType::New();
119 mainFilter->SetInput(inputImage);
120 mainFilter->SetNumberOfWorkUnits(nbpArg.getValue());
121 mainFilter->SetKernel(tmpBall);
123 mainFilter->Update();
125 resPointer = mainFilter->GetOutput();
127 else if (actArg.getValue() ==
"open")
129 std::cout <<
"Performing opening with radius " << radiusArg.getValue() <<
"..." << std::endl;
131 OpeningFilterType::Pointer mainFilter = OpeningFilterType::New();
132 mainFilter->SetInput(inputImage);
133 mainFilter->SetNumberOfWorkUnits(nbpArg.getValue());
134 mainFilter->SetKernel(tmpBall);
136 mainFilter->Update();
138 resPointer = mainFilter->GetOutput();
142 std::cout <<
"Performing closing with radius " << radiusArg.getValue() <<
"..." << std::endl;
144 ClosingFilterType::Pointer mainFilter = ClosingFilterType::New();
145 mainFilter->SetInput(inputImage);
146 mainFilter->SetNumberOfWorkUnits(nbpArg.getValue());
147 mainFilter->SetKernel(tmpBall);
149 mainFilter->Update();
151 resPointer = mainFilter->GetOutput();
154 anima::writeImage <ImageType> (outArg.getValue(),resPointer);
int main(int argc, char **argv)