Xmipp  v3.23.11-Nereus
image_statistics.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  *
3  * Authors: Carlos Oscar coss@cnb.csic.es (1999)
4  * and modified by Sjors Scheres
5  * " " " Joaquin Oton
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 
28 #include <cstdio>
29 #include <core/xmipp_program.h>
31 #include <core/metadata_vec.h>
32 #include <data/mask.h>
33 
34 /* PROGRAM ----------------------------------------------------------------- */
36 {
37 protected:
43 
45  int short_format; // True if a short line is to be shown
46  int save_mask; // True if the masks must be saved
47  int repair; // True if headers are initialized
48  bool show_angles; // True if angles are to be shown in stats
49  bool save_image_stats; // True if average and std images must be computed
50  bool apply_mask; // True if a mask must be applied
51 
55 
56 
58 
59  void defineParams()
60  {
62  allow_apply_geo = true;
63  allow_time_bar = false;
64  addUsageLine("Display statistics of 2D/3Dimages. A mask can be applied. Average Images may be computed");
65  addUsageLine("All images must have same size");
67  addParamsLine("[-o <metadata>] : Save the statistics in this metadata file.");
68  addParamsLine("[--short_format] : Do not show labels for statistics.");
69  addParamsLine("[--show_angles] : Also show angles in the image header.");
70  addParamsLine("[--save_mask <maskFileName>] : Save 2D and 3D masks.");
71  addParamsLine("[--save_image_stats <stats_root=\"\">]: Save average and standard deviation images");
72  addUsageLine (" Mask is ignored for this operation");
73  mask.defineParams(this,INT_MASK,nullptr,"Statistics restricted to the mask area.");
74  addUsageLine ("NOTE: Geometry will NOT be applied to volumes even if apply_geo flag is on");
75  addKeywords("statistics average mean std");
76  }
77 
78  void readParams()
79  {
81  short_format = checkParam("--short_format");
82 
83  if ((save_mask = checkParam("--save_mask")))
84  maskFileName = getParam("--save_mask");
85 
86  if ((save_image_stats = checkParam("--save_image_stats")))
87  statsRoot = getParam("--save_image_stats");
88 
89  show_angles = checkParam("--show_angles");
90  fn_out = (checkParam("-o"))? getParam("-o"): "";
91 
93 
94  if ((apply_mask = checkParam("--mask")))
95  mask.readParams(this);
96  }
97 
98  void show()
99  {
100  std::cout << " Statistics of " << fn_in << std::endl;
101  }
102 
103  void preProcess()
104  {
105  DF_stats.setComment((std::string)"Statistics of " + fn_in);
106  // Get maximum filename size ---------------------------------------------
107  max_length = getInputMd()->getMaxStringLength(image_label);
108 
109  // Process each file -----------------------------------------------------
110  mean_min_val = 0, mean_max_val = 0, mean_avg = 0, mean_stddev = 0;
111 
112  if (verbose > 0)
113  {
114  if (short_format)
115  {
116  std::cout << "Format: Name ZxYxX min max avg stddev ";
117  if (show_angles)
118  std::cout << " <rot tilt psi>";
119  std::cout << '>' << std::endl;
120  }
121  }
122 
123  // get xdim, ydim,zdim
124  //getImageSize(mdIn, xDim, yDim, zDim, nDim, image_label);
125  averageArray.resize(ndimOut, zdimOut, ydimOut, xdimOut);
126  stdArray.resize(ndimOut,zdimOut,ydimOut,xdimOut);
127  averageArray.setXmippOrigin();
128  stdArray.setXmippOrigin();
129 
130  // Generate mask if necessary
131  if (apply_mask)
132  mask.generate_mask(zdimOut, ydimOut, xdimOut);
133 
134  }
135 
136  void processImage(const FileName &fnImg, const FileName &fnImgOut, const MDRow &rowIn, MDRow &rowOut)
137  {
138  if (apply_geo)
139  image.readApplyGeo(fnImg, rowIn);
140  else
141  image.read(fnImg, DATA, ALL_IMAGES, true);
142 
143  image().setXmippOrigin();
144 
145  double rot = 0, tilt = 0, psi = 0;
146  if (show_angles)
147  image.getEulerAngles(rot,tilt,psi);
148 
149  if (apply_mask)
150  {
151  computeStats_within_binary_mask(mask.get_binary_mask(), image(), min_val, max_val,
152  avg, stddev);
153  }
154  else
155  image().computeStats(avg, stddev, min_val, max_val);
156 
157  if(save_image_stats)
158  {
159  //copy image from imageGeneric
160  image().getImage( dummyArray );
161  averageArray += dummyArray;
162  stdArray += dummyArray * dummyArray;
163  }
164 
165  // Show information
166  if (verbose > 0)
167  {
168  std::cout << stringToString(fnImg, max_length + 1);
169  if (zdimOut > 1)
170  formatString("%4dx%4dx%4d ", zdimOut, ydimOut, xdimOut);
171  else
172  formatString("%4dx%4d", ydimOut, xdimOut);
173 
174  if (!short_format)
175  {
176  std::cout << formatString("min=%10f max=%10f avg=%10f stddev=%10f",
177  min_val, max_val, avg, stddev);
178 
179  if (show_angles)
180  std::cout << formatString("rot=%10f tilt=%10f psi=%10f", rot, tilt, psi);
181  }
182  else
183  std::cout << formatString("%10f %10f %10f %10f", min_val, max_val, avg, stddev);
184  }
185  size_t id;
186  id = DF_stats.addObject();
187  DF_stats.setRow(rowIn,id);
188  DF_stats.setValue(MDL_MIN,min_val,id);
189  DF_stats.setValue(MDL_MAX,max_val,id);
190  DF_stats.setValue(MDL_AVG,avg,id);
191  DF_stats.setValue(MDL_STDDEV,stddev,id);
192 
193  // Total statistics
194  mean_min_val += min_val;
195  mean_max_val += max_val;
196  mean_avg += avg;
197  mean_stddev += stddev;
198 
199  // Finish information .................................................
200  if (verbose > 0)
201  std::cout << std::endl;
202  }
203 
204  void postProcess()
205  {
206 
207  if (mdInSize > 1)
208  {
209  mean_min_val /= mdInSize;
210  mean_max_val /= mdInSize;
211  mean_avg /= mdInSize;
212  mean_stddev /= mdInSize;
213 
214  if (verbose)
215  {
216  // Show total statistics ------------------------------------------------
217  std::cout << "==================================================\n";
218  std::cout << "Total number of images/volumes: " << mdInSize << std::endl;
219  std::cout << stringToString(" ", max_length + 13);
220  if (!short_format)
221  std::cout << formatString("min=%10f max=%10f avg=%10f stddev=%10f",
222  mean_min_val, mean_max_val, mean_avg, mean_stddev);
223  else
224  std::cout << formatString("%10f %10f %10f %10f", mean_min_val, mean_max_val, mean_avg, mean_stddev);
225  std::cout << std::endl;
226  }
227 
228  if (save_image_stats)
229  {
230  averageArray /= mdInSize;
231  if (mdInSize > 1)
232  {
233  stdArray= stdArray / mdInSize - averageArray * averageArray;
234  stdArray *= mdInSize / (mdInSize - 1);
235  //Do this as an image since it is not define for arrays
236  FOR_ALL_DIRECT_ELEMENTS_IN_MULTIDIMARRAY(stdArray)
237  DIRECT_MULTIDIM_ELEM(stdArray,n) = sqrt(fabs(DIRECT_MULTIDIM_ELEM(stdArray,n)));
238  }
239  else
240  stdArray.initZeros();
241  }
242  }
243 
244  // Save masks -----------------------------------------------------------
245  if (save_mask)
246  mask.write_mask(maskFileName);
247  // Save statistics ------------------------------------------------------
248  if (fn_out != "")
249  DF_stats.write(fn_out,MD_APPEND);
250 
251  //save average and std images
252  if(save_image_stats)
253  {
254  Image<double> dummyImage;
255  dummyImage() = averageArray;
256  dummyImage.write(statsRoot + "average.xmp");
257  dummyImage() = stdArray;
258  dummyImage.write(statsRoot + "stddev.xmp");
259  }
260  }
261 };// end of class ProgStatistics
Definition: mask.h:360
int allowed_data_types
Definition: mask.h:495
virtual void setComment(const String &newComment="No comment")
static void defineParams(XmippProgram *program, int allowed_data_types=ALL_KINDS, const char *prefix=nullptr, const char *comment=nullptr, bool moreOptions=false)
Definition: mask.cpp:1203
void addKeywords(const char *keywords)
MultidimArray< double > dummyArray
MultidimArray< double > averageArray
ImageGeneric image
FileName fn_in
Filenames of input and output Metadata.
const char * getParam(const char *param, int arg=0)
void readParams(XmippProgram *program)
Definition: mask.cpp:1284
int verbose
Verbosity level.
virtual int getMaxStringLength(const MDLabel thisLabel) const =0
MetaDataVec DF_stats
MDLabel image_label
MDLabel to be used to read/write images, usually will be MDL_IMAGE.
bool allow_time_bar
Show process time bar.
MultidimArray< double > stdArray
#define INT_MASK
Definition: mask.h:385
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 addParamsLine(const String &line)