Xmipp  v3.23.11-Nereus
transform_morphology.cpp
Go to the documentation of this file.
1 
2 /***************************************************************************
3  *
4  * Authors: Carlos Oscar S. Sorzano (coss@cnb.csic.es)
5  * Pedro A. de Alarcon (pedro@cnb.csic.es)
6  *
7  * Unidad de Bioinformatica of Centro Nacional de Biotecnologia , CSIC
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
22  * 02111-1307 USA
23  *
24  * All comments concerning this program package may be sent to the
25  * e-mail address 'xmipp@cnb.csic.es'
26  ***************************************************************************/
27 
29 #include "core/xmipp_image.h"
30 #include "data/morphology.h"
31 #include "data/filters.h"
32 
34 {
35 public:
36 #define DILATION 1
37 #define EROSION 2
38 #define OPENING 3
39 #define CLOSING 4
40 #define SHARPENING 5
41 #define KEEPBIGGEST 6
42 #define REMOVESMALL 7
43 
45  int operation;
46  int size;
47  int count;
48  int neig2D, neig3D;
49  double width;
50  double strength;
51  int smallSize;
52 public:
53  void defineParams()
54  {
56  addUsageLine("Apply morphological operations to binary or gray images/volumes.");
57  addUsageLine("+You may learn about morphological operations in general from");
58  addUsageLine("[[http://en.wikipedia.org/wiki/Mathematical_morphology][here]].");
59  addUsageLine("");
61  addParamsLine("--binaryOperation <op>: Morphological operation on binary images");
62  addParamsLine(" where <op>");
63  addParamsLine(" dilation : Dilate white region");
64  addParamsLine(" erosion : Erode white region");
65  addParamsLine(" closing : Dilation+Erosion, removes black spots");
66  addParamsLine(" opening : Erosion+Dilation, removes white spots");
67  addParamsLine(" keepBiggest : Keep biggest component");
68  addParamsLine(" removeSmall <size=10> : Remove components whose size is smaller than this size");
69  addParamsLine("or --grayOperation <op>: Morphological operation on gray images");
70  addParamsLine(" where <op>");
71  addParamsLine(" sharpening <w=1> <s=0.5>: Sharpening with width (suggested 1 or 2)");
72  addParamsLine(" : and strength (suggested 0.1-1.0).");
73  addParamsLine(" : Only valid for volumes, not images.");
74  addParamsLine(" :++ Implemented according to JGM Schavemaker, MJT Reinders, JJ Gerbrands,");
75  addParamsLine(" :++ E Backer. Image sharpening by morphological filtering. Pattern Recognition");
76  addParamsLine(" :++ 33: 997-1012 (2000)");
77  addParamsLine("[--neigh2D+ <n=Neigh8>] : Neighbourhood in 2D.");
78  addParamsLine(" where <n>");
79  addParamsLine(" Neigh4");
80  addParamsLine(" Neigh8");
81  addParamsLine(" requires --binaryOperation;");
82  addParamsLine("[--neigh3D+ <n=Neigh18>] : Neighbourhood in 3D.");
83  addParamsLine(" where <n>");
84  addParamsLine(" Neigh6");
85  addParamsLine(" Neigh18");
86  addParamsLine(" Neigh26");
87  addParamsLine(" requires --binaryOperation;");
88  addParamsLine("[--size <s=1>]: Size of the Strutural element.");
89  addParamsLine(" requires --binaryOperation;");
90  addParamsLine("[--count+ <c=0>]: Minimum required neighbors with distinct value.");
91  addParamsLine(" requires --binaryOperation;");
92  addExampleLine("xmipp_transform_morphology -i binaryVolume.vol --binaryOperation dilation");
93  }
94 
95  void readParams()
96  {
98  binaryOperation=checkParam("--binaryOperation");
99  if (binaryOperation)
100  {
101  String strOperation=getParam("--binaryOperation");
102  if (strOperation=="dilation")
103  operation = DILATION;
104  else if (strOperation=="erosion")
105  operation = EROSION;
106  else if (strOperation=="closing")
107  operation = CLOSING;
108  else if (strOperation=="opening")
109  operation = OPENING;
110  else if (strOperation=="keepBiggest")
111  operation = KEEPBIGGEST;
112  else if (strOperation=="removeSmall")
113  {
114  operation = REMOVESMALL;
115  smallSize = getIntParam("--binaryOperation",1);
116  }
117 
118  size = getIntParam("--size");
119  String neighbourhood=getParam("--neigh2D");
120  if (neighbourhood=="Neigh8")
121  neig2D = 8;
122  else
123  neig2D = 4;
124  neighbourhood=getParam("--neigh3D");
125  if (neighbourhood=="Neigh6")
126  neig3D = 6;
127  else if (neighbourhood=="Neigh18")
128  neig3D = 18;
129  else
130  neig3D = 26;
131  count = getIntParam("--count");
132  }
133  else if (checkParam("--grayOperation"))
134  {
135  String strOperation=getParam("--grayOperation");
136  if (strOperation=="sharpening")
137  {
138  operation = SHARPENING;
139  width=getDoubleParam("--grayOperation",1);
140  strength=getDoubleParam("--grayOperation",2);
141  }
142  }
143  }
144 
145  void show()
146  {
147  std::cout << "Performing a ";
148  switch (operation)
149  {
150  case DILATION :
151  std::cout << "Dilation\n";
152  break;
153  case EROSION :
154  std::cout << "Erosion\n";
155  break;
156  case OPENING :
157  std::cout << "Opening\n";
158  break;
159  case CLOSING :
160  std::cout << "Closing\n";
161  break;
162  case SHARPENING :
163  std::cout << "Sharpening\n"
164  << "Width = " << width << std::endl
165  << "Strength = " << strength << std::endl;
166  case KEEPBIGGEST :
167  std::cout << "Keeping biggest component\n";
168  break;
169  case REMOVESMALL :
170  std::cout << "Removing small objects\n"
171  << "Small size < " << smallSize << std::endl;
172  break;
173  }
174  if (binaryOperation)
175  std::cout << "Size=" << size << std::endl
176  << "Neighbourhood2D=" << neig2D << std::endl
177  << "Neighbourhood3D=" << neig3D << std::endl
178  << "Count=" << count << std::endl;
179  }
180  void processImage(const FileName &fnImg, const FileName &fnImgOut, const MDRow &rowIn, MDRow &rowOut)
181  {
182  Image<double> img, imgOut;
183  img.readApplyGeo(fnImg, rowIn);
184  imgOut().resizeNoCopy(img());
185 
186  if (binaryOperation)
187  std::cout << "Initially the image has " << img().sum()
188  << " pixels set to 1\n";
189  bool isVolume=ZSIZE(img())>1;
190  switch (operation)
191  {
192  case DILATION:
193  if (isVolume)
194  dilate3D(img(), imgOut(), neig3D, count, size);
195  else
196  dilate2D(img(), imgOut(), neig2D, count, size);
197  break;
198  case EROSION:
199  if (isVolume)
200  erode3D(img(), imgOut(), neig3D, count, size);
201  else
202  erode2D(img(), imgOut(), neig2D, count, size);
203  break;
204  case OPENING:
205  if (isVolume)
206  opening3D(img(), imgOut(), neig3D, count, size);
207  else
208  opening2D(img(), imgOut(), neig2D, count, size);
209  break;
210  case CLOSING:
211  if (isVolume)
212  closing3D(img(), imgOut(), neig3D, count, size);
213  else
214  closing2D(img(), imgOut(), neig2D, count, size);
215  break;
216  case SHARPENING:
217  if (isVolume)
218  sharpening(img(), width, strength, imgOut());
219  else
220  REPORT_ERROR(ERR_NOT_IMPLEMENTED,"Sharpening has not been implemented for images");
221  break;
222  case KEEPBIGGEST:
223  if (isVolume)
224  keepBiggestComponent(img(),0,neig3D);
225  else
226  keepBiggestComponent(img(),0,neig2D);
227  imgOut()=img();
228  break;
229  case REMOVESMALL:
230  if (isVolume)
231  removeSmallComponents(img(),smallSize,neig3D);
232  else
233  removeSmallComponents(img(),smallSize,neig2D);
234  imgOut()=img();
235  break;
236  }
237 
238  if (binaryOperation)
239  std::cout << "Finally the image has " << imgOut().sum() << " pixels set to 1\n";
240  imgOut.write(fnImgOut);
241  }
242 };
void erode3D(const MultidimArray< double > &in, MultidimArray< double > &out, int neig, int count, int size)
Definition: morphology.cpp:407
Case or algorithm not implemented yet.
Definition: xmipp_error.h:177
double getDoubleParam(const char *param, int arg=0)
#define REPORT_ERROR(nerr, ErrormMsg)
Definition: xmipp_error.h:211
#define CLOSING
void write(const FileName &name="", size_t select_img=ALL_IMAGES, bool isStack=false, int mode=WRITE_OVERWRITE, CastWriteMode castMode=CW_CAST, int _swapWrite=0)
#define EROSION
#define REMOVESMALL
#define DILATION
int readApplyGeo(const FileName &name, const MDRow &row, const ApplyGeoParams &params=DefaultApplyGeoParams)
#define KEEPBIGGEST
void opening2D(const MultidimArray< double > &in, MultidimArray< double > &out, int neig, int count, int size)
Definition: morphology.cpp:148
void opening3D(const MultidimArray< double > &in, MultidimArray< double > &out, int neig, int count, int size)
Definition: morphology.cpp:440
void closing3D(const MultidimArray< double > &in, MultidimArray< double > &out, int neig, int count, int size)
Definition: morphology.cpp:422
#define OPENING
const char * getParam(const char *param, int arg=0)
void erode2D(const MultidimArray< double > &in, MultidimArray< double > &out, int neig, int count, int size)
Definition: morphology.cpp:116
void processImage(const FileName &fnImg, const FileName &fnImgOut, const MDRow &rowIn, MDRow &rowOut)
void removeSmallComponents(MultidimArray< double > &I, int size, int neighbourhood)
Definition: filters.cpp:689
void closing2D(const MultidimArray< double > &in, MultidimArray< double > &out, int neig, int count, int size)
Definition: morphology.cpp:130
#define ZSIZE(v)
void addExampleLine(const char *example, bool verbatim=true)
void dilate3D(const MultidimArray< double > &in, MultidimArray< double > &out, int neig, int count, int size)
Definition: morphology.cpp:394
void sharpening(const MultidimArray< double > &in, double width, double strength, MultidimArray< double > &out)
Definition: morphology.cpp:522
void keepBiggestComponent(MultidimArray< double > &I, double percentage, int neighbourhood)
Definition: filters.cpp:713
std::string String
Definition: xmipp_strings.h:34
bool checkParam(const char *param)
bool each_image_produces_an_output
Indicate that an output is produced for each image in the input.
void addUsageLine(const char *line, bool verbatim=false)
void dilate2D(const MultidimArray< double > &in, MultidimArray< double > &out, int neig, int count, int size)
Definition: morphology.cpp:103
#define SHARPENING
int getIntParam(const char *param, int arg=0)
void addParamsLine(const String &line)