Xmipp  v3.23.11-Nereus
image_resize.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  * Authors: Joaquin Oton (joton@cnb.csic.es)
3  * J.M. De la Rosa (jmdelarosa@cnb.csic.es)
4  *
5  *
6  * Unidad de Bioinformatica of Centro Nacional de Biotecnologia , CSIC
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
21  * 02111-1307 USA
22  *
23  * All comments concerning this program package may be sent to the
24  * e-mail address 'xmipp@cnb.csic.es'
25  ***************************************************************************/
26 #include "image_resize.h"
27 #include "core/transformations.h"
28 #include "core/xmipp_fftw.h"
29 
31 {}
32 
34 {}
35 
37 {
39  save_metadata_stack = true;
40  keep_input_columns = true;
41  allow_apply_geo = true;
42  temporaryOutput = false;
44  //usage
45  addUsageLine("Resize image or volume dimensions.");
46  addUsageLine("+You can select different ways to resize your image/volumes.");
47  //keywords
48  addKeywords("transform, dimension, pyramid, fourier, scale");
49  //examples
50  addExampleLine("Resize a group of images to half size", false);
51  addExampleLine("xmipp_image_resize -i images.xmd --factor 0.5 --oroot halvedOriginal");
52  addExampleLine("For pyramid resizing(increase volume size 4 times):", false);
53  addExampleLine("xmipp_image_resize -i input/bacteriorhodopsin.vol --pyramid 2 -o bdr_x4.vol");
54  addExampleLine("Resize from 128 to 64 using Fourier", false);
55  addExampleLine("xmipp_image_resize -i images.xmd --fourier 64 --oroot halvedFourierDim");
56  //params
57  addParamsLine("--factor <n=0.5> : Resize a factor of dimensions, 0.5 halves and 2 doubles (uses splines or linear interpolation).");
58  addParamsLine(" alias -n;");
59  addParamsLine("or --dim <x> <y=x> <z=x> : New x,y and z dimensions (uses splines / linear interpolation or nearest neighbour method).");
60  addParamsLine(" alias -d;");
61  addParamsLine("or --fourier <x> <y=x> <z=x> <thr=1> : Use padding/windowing in Fourier Space to resize. thr=number of threads");
62  addParamsLine(" alias -f;");
63  addParamsLine("or --pyramid <levels=1> : Use positive value to expand and negative to reduce");
64  addParamsLine(" alias -p;");
65  addParamsLine(" [--interp <interpolation_type=spline>] : Interpolation type to be used. ");
66  addParamsLine(" where <interpolation_type>");
67  addParamsLine(" spline : Use spline interpolation");
68  addParamsLine(" linear : Use bilinear/trilinear interpolation");
69  addParamsLine(" nearest : Use nearest neighbour to set new value");
70 }
71 
73 {
75  String degree = getParam("--interp");
76 
77  if (degree == "spline")
79  else if (degree == "linear")
81  else if (degree == "nearest")
83 
85 }
86 
87 
89 {
90  double factor=1.0;
91  double oxdim = xdimOut;
92  auto oydim = (double)ydimOut;
93  auto ozdim = (double)zdimOut;
94 
95  //If zdimOut greater than 1, is a volume and should apply transform
96  dim = (isVol = (zdimOut > 1)) ? 3 : 2;
97 
100 
101  if (fn_out.empty() && oroot.empty())
102  {
103  fn_out=fn_in+"_tmp";
105  temporaryOutput=true;
107  }
108 
109  if (checkParam("--factor") || checkParam("--dim"))
110  {
111  //Calculate scale factor from images sizes and given dimensions
112  //this approach assumes that all images have equal size
113  if (checkParam("--dim"))
114  {
115  xdimOut = getIntParam("--dim", 0);
116  ydimOut = STR_EQUAL(getParam("--dim", 1), "x") ? xdimOut : getIntParam("--dim", 1);
117  XX(resizeFactor) = (double)xdimOut / oxdim;
118  YY(resizeFactor) = (double)ydimOut / oydim;
119  }
120  else
121  {
122  factor = getDoubleParam("--factor");
123  if (factor <= 0)
124  REPORT_ERROR(ERR_VALUE_INCORRECT,"Resize factor must be a positive number");
125  xdimOut = (int) (xdimOut * factor);
126  ydimOut = (int) (ydimOut * factor);
127  resizeFactor.initConstant(factor);
128  }
129 
130  //if scale factor is large splines s not the way to go, print a warning
131  if( fabs(1.0-XX(resizeFactor)) > 0.1 )
132  {
133  reportWarning("Do not apply large scale factor using B-splines "
134  "choose fourier option.");
135  }
136 
137  if (isVol)
138  {
139  if (checkParam("--dim"))
140  {
141  zdimOut = STR_EQUAL(getParam("--dim", 2), "x")
142  ? xdimOut : getIntParam("--dim", 2);
143  ZZ(resizeFactor) = (double)zdimOut / ozdim;
144  }
145  else
146  zdimOut = (int) (zdimOut * factor);
147  }
149  }
150  else if (checkParam("--fourier"))
151  {
152  // if (isVol)
153  // REPORT_ERROR(ERR_PARAM_INCORRECT, "The 'fourier' scaling type is only valid for images");
154  auto oxdim2 = xdimOut;
155  auto oydim2 = ydimOut;
156  auto ozdim2 = zdimOut;
158 
159  xdimOut = getIntParam("--fourier", 0);
160  ydimOut = STR_EQUAL(getParam("--fourier", 1), "x") ? xdimOut : getIntParam("--fourier", 1);
161  if (isVol)
162  zdimOut = STR_EQUAL(getParam("--fourier", 2), "x") ? xdimOut : getIntParam("--fourier", 2);
163  else
164  zdimOut=1;
165  fourier_threads = getIntParam("--fourier", 3);
166  XX(resizeFactor) = (double)xdimOut / oxdim2;
167  YY(resizeFactor) = (double)ydimOut / oydim2;
168  if (isVol)
169  ZZ(resizeFactor) = (double)zdimOut / ozdim2;
170  //Do not think this is true
171  // if (oxdim < xdimOut || oydim < ydimOut)
172  // REPORT_ERROR(ERR_PARAM_INCORRECT, "The 'fourier' scaling type can only be used for reducing size");
173  }
174  else if (checkParam("--pyramid"))
175  {
177  pyramid_level = getIntParam("--pyramid", 0);
178  factor = (double)(pow(2.0, pyramid_level));
179  xdimOut = (size_t)(xdimOut*factor);
180  ydimOut = (size_t)(ydimOut*factor);
181  if (isVol)
182  zdimOut = (size_t)(zdimOut*factor);
183  if (pyramid_level < 0)
184  {
185  pyramid_level *= -1; //change sign, negative means reduce operation
187  }
188  resizeFactor.initConstant(factor);
189  }
190 }
191 
192 #define SCALE_SHIFT(shiftLabel, resizeFactor) if (rowIn.containsLabel(shiftLabel)) {\
193  rowIn.getValue(shiftLabel, aux); aux *= (resizeFactor); rowOut.setValue(shiftLabel, aux); }
194 
195 void ProgImageResize::processImage(const FileName &fnImg, const FileName &fnImgOut, const MDRow &rowIn, MDRow &rowOut)
196 {
197  double aux;
198  if (apply_geo)
199  {
202  if (isVol)
204  }
205  else
206  rowOut.resetGeo(false);
207 
208  img.read(fnImg);
209  img().setXmippOrigin();
211 
212  switch (scale_type)
213  {
214  case RESIZE_FACTOR:
215  //selfScaleToSize(splineDegree, img(), xdimOut, ydimOut, zdimOut);
217  break;
220  //selfPyramidExpand(splineDegree, img(), pyramid_level);
221  break;
224  //selfPyramidReduce(splineDegree, img(), pyramid_level);
225  break;
226  case RESIZE_FOURIER:
228  img.write(fnImgOut);
229  return;
230  case RESIZE_NONE:
231  break;
232  }
233  imgOut.write(fnImgOut);
234 }
235 
237 {
238  if (temporaryOutput)
239  std::rename(fn_out.c_str(),fn_in.c_str());
240 }
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)
double getDoubleParam(const char *param, int arg=0)
void reportWarning(const String &what)
#define REPORT_ERROR(nerr, ErrormMsg)
Definition: xmipp_error.h:211
void processImage(const FileName &fnImg, const FileName &fnImgOut, const MDRow &rowIn, MDRow &rowOut)
void pyramidReduce(int SplineDegree, MultidimArrayGeneric &V2, const MultidimArrayGeneric &V1, int levels)
FileName addExtension(const String &ext) const
Shift for the image in the X axis (double)
ScaleType scale_type
Definition: image_resize.h:48
ImageGeneric imgOut
Definition: image_resize.h:59
DataType getDatatype() const
void addKeywords(const char *keywords)
String getExtension() const
FileName fn_in
Filenames of input and output Metadata.
const char * getParam(const char *param, int arg=0)
#define XX(v)
Definition: matrix1d.h:85
void addExampleLine(const char *example, bool verbatim=true)
void selfScaleToSizeFourier(int Zdim, int Ydim, int Xdim, MultidimArray< double > &mda, int nThreads)
Definition: xmipp_fftw.cpp:723
void pyramidExpand(int SplineDegree, MultidimArrayGeneric &V2, const MultidimArrayGeneric &V1, int levels)
virtual void resetGeo(bool addLabels=true)
#define STR_EQUAL(str1, str2)
Definition: xmipp_strings.h:42
void scaleToSize(int SplineDegree, MultidimArrayGeneric &V2, const MultidimArrayGeneric &V1, int Xdim, int Ydim, int Zdim)
#define YY(v)
Definition: matrix1d.h:93
void setDatatype(DataType _datatype)
bool save_metadata_stack
Save the associated output metadata when output file is a stack.
std::string String
Definition: xmipp_strings.h:34
Matrix1D< double > resizeFactor
Definition: image_resize.h:57
Shift for the image in the Z axis (double)
ImageGeneric img
Definition: image_resize.h:58
void resizeNoCopy(int Xdim)
Definition: matrix1d.h:458
bool keep_input_columns
Keep input metadata columns.
bool checkParam(const char *param)
bool each_image_produces_an_output
Indicate that an output is produced for each image in the input.
Shift for the image in the Y axis (double)
void addUsageLine(const char *line, bool verbatim=false)
int getIntParam(const char *param, int arg=0)
int read(const FileName &name, DataMode datamode=DATA, size_t select_img=ALL_IMAGES, bool mapData=false)
Incorrect value received.
Definition: xmipp_error.h:195
void initConstant(T val)
Definition: matrix1d.cpp:83
#define ZZ(v)
Definition: matrix1d.h:101
#define SCALE_SHIFT(shiftLabel, resizeFactor)
void addParamsLine(const String &line)