Xmipp  v3.23.11-Nereus
image_vectorize.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  *
3  * Authors: Carlos Oscar S. Sorzano (coss@cnb.csic.es)
4  *
5  * Unidad de Bioinformatica of Centro Nacional de Biotecnologia , CSIC
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
20  * 02111-1307 USA
21  *
22  * All comments concerning this program package may be sent to the
23  * e-mail address 'xmipp@cnb.csic.es'
24  ***************************************************************************/
25 
26 #include <core/xmipp_program.h>
27 #include <data/mask.h>
29 
31 {
32 public:
36  bool apply_mask;
37  void defineParams()
38  {
39  addUsageLine("Convert an image/volume to data and viceversa.");
40  addUsageLine("Data is the file format used by KerDenSOM and other classification programs");
41  addParamsLine(" -i <file> : If Image->Vector: Input Single image/volume/stack or selfile");
42  addParamsLine(" : If Vector->Image: Input Vector metadata");
43  addParamsLine(" -o <file> : If Image->Vector: Output vector metadata");
44  addParamsLine(" : If Vector->Image: Output stack");
45  mask.defineParams(this,INT_MASK,nullptr,"Extract pixel values from a mask area.");
46  addExampleLine("Produce vectors from images or volumes",false);
47  addExampleLine("xmipp_image_vectorize -i projections.sel -o vectors.xmd");
48  addExampleLine("Produce images from vectors",false);
49  addExampleLine("xmipp_image_vectorize -i vectors.xmd -o images.stk");
50  addExampleLine("Produce vectors from images or volumes with a mask",false);
51  addExampleLine("xmipp_image_vectorize -i projections.sel -o vectors.xmd --mask circular -16");
52  addExampleLine("Produce images from vectors that were defined using a mask",false);
53  addExampleLine("xmipp_image_vectorize -i vectors.xmd -o images.stk --mask circular -16");
54  }
55 
56  void readParams()
57  {
58  fnIn = getParam("-i");
59  fnOut = getParam("-o");
61  if ((apply_mask = checkParam("--mask")))
62  mask.readParams(this);
63  }
64 
65  void show()
66  {
67  if (verbose==0)
68  return;
69  std::cout
70  << "Input: " << fnIn << std::endl
71  << "Output: " << fnOut << std::endl
72  ;
73  }
74 
75 
76  void run()
77  {
78  StringVector blockList;
79  getBlocksInMetaDataFile(fnIn, blockList);
80  bool headerFound=false;
81  for (size_t i=0; i<blockList.size(); i++)
82  if (blockList[i]=="vectorHeader")
83  {
84  headerFound=true;
85  break;
86  }
87  if (!headerFound)
88  {
89  // Image -> Vector
90  MetaDataVec SF(fnIn);
91  MetaDataVec vectorContent, vectorHeader;
92  vectorHeader.setColumnFormat(false);
93  Image<double> img;
94  bool first=true;
95  size_t order=0;
96  FileName fnImg;
97  float *buffer=nullptr;
98  FileName fnOutRaw=formatString("%s.vec",fnOut.withoutExtension().c_str());
99  std::ofstream fhOutRaw(fnOutRaw.c_str(),std::ios::binary);
100  if (!fhOutRaw)
101  REPORT_ERROR(ERR_IO_NOWRITE,fnOutRaw);
102  size_t vectorSize;
103 
104  for (auto& row : SF)
105  {
106  img.readApplyGeo(SF, row.id());
107 
108  // Create header
109  if (first)
110  {
111  if (apply_mask)
112  {
113  mask.generate_mask(ZSIZE(img()),YSIZE(img()),XSIZE(img()));
114  // Make sure that the mask is between 0 and 1
115  MultidimArray<int> &imask=mask.get_binary_mask();
117  A2D_ELEM(imask,i,j)=(A2D_ELEM(imask,i,j)!=0)?1:0;
118  vectorSize=(int)imask.sum();
119  }
120  else
121  vectorSize=MULTIDIM_SIZE(img());
122  size_t outId=vectorHeader.addObject();
123  vectorHeader.setValue(MDL_XSIZE,XSIZE(img()),outId);
124  vectorHeader.setValue(MDL_YSIZE,YSIZE(img()),outId);
125  vectorHeader.setValue(MDL_ZSIZE,ZSIZE(img()),outId);
126  vectorHeader.setValue(MDL_COUNT,SF.size(),outId);
127  vectorHeader.setValue(MDL_CLASSIFICATION_DATA_SIZE,vectorSize,outId);
128  vectorHeader.write(formatString("vectorHeader@%s",fnOut.c_str()));
129  buffer=new float[vectorSize];
130  first=false;
131  }
132 
133  // Save this image in the output metadata
134  row.setValue(MDL_ORDER, order++);
135  vectorContent.addRow(dynamic_cast<const MDRowVec&>(row));
136 
137  // Save raw values
138  const MultidimArray<double> &mimg=img();
139  const MultidimArray<int> &mmask=mask.get_binary_mask();
140  int ii=0;
141  if (apply_mask)
142  {
144  if (DIRECT_MULTIDIM_ELEM(mmask,n))
145  buffer[ii++]=(float)DIRECT_MULTIDIM_ELEM(mimg,n);
146  }
147  else
148  {
150  buffer[ii++]=(float)DIRECT_MULTIDIM_ELEM(mimg,n);
151  }
152  fhOutRaw.write((char*)buffer,vectorSize*sizeof(float));
153  }
154  fhOutRaw.close();
155  vectorContent.write(formatString("vectorContent@%s",fnOut.c_str()),MD_APPEND);
156  delete []buffer;
157  }
158  else
159  {
160  // Vector -> Image
161  fnOut.deleteFile();
162 
163  MetaDataVec vectorHeader(formatString("vectorHeader@%s",fnIn.c_str()));
164  MetaDataVec vectorContent(formatString("vectorContent@%s",fnIn.c_str()));
165 
166  // Read header
167  size_t headerId=vectorHeader.firstRowId();
168  size_t Xdim, Ydim, Zdim, vectorSize, imgNo;
169  vectorHeader.getValue(MDL_XSIZE,Xdim,headerId);
170  vectorHeader.getValue(MDL_YSIZE,Ydim,headerId);
171  vectorHeader.getValue(MDL_ZSIZE,Zdim,headerId);
172  vectorHeader.getValue(MDL_COUNT,imgNo,headerId);
173  vectorHeader.getValue(MDL_CLASSIFICATION_DATA_SIZE,vectorSize,headerId);
174  if (apply_mask)
175  mask.generate_mask(Zdim,Ydim,Xdim);
176  const MultidimArray<int> &mmask=mask.get_binary_mask();
177 
178  // Process all images
179  Image<double> img;
180  img().resizeNoCopy(Zdim,Ydim,Xdim);
181  const MultidimArray<double> &mimg=img();
182  FileName fnImg, fnIdx;
183  auto *buffer=new float[vectorSize];
184  FileName fnInRaw=formatString("%s.vec",fnIn.withoutExtension().c_str());
185  std::ifstream fhInRaw(fnInRaw.c_str(),std::ios::binary);
186  if (!fhInRaw)
187  REPORT_ERROR(ERR_IO_NOTEXIST,fnInRaw);
188  size_t order;
189  size_t idx=1;
190 
191  for (size_t objId : vectorContent.ids())
192  {
193  vectorContent.getValue(MDL_IMAGE, fnImg, objId);
194  vectorContent.getValue(MDL_ORDER, order, objId);
195 
196  // Read raw values
197  fhInRaw.seekg(order*vectorSize*sizeof(float));
198  fhInRaw.read((char*)buffer,vectorSize*sizeof(float));
199  if (!fhInRaw)
201  formatString("Could not read image %lu from %s",
202  order,fnInRaw.c_str()));
203  int ii=0;
204  if (apply_mask)
205  {
207  if (DIRECT_MULTIDIM_ELEM(mmask,n))
208  DIRECT_MULTIDIM_ELEM(mimg,n)=buffer[ii++];
209  }
210  else
211  {
213  DIRECT_MULTIDIM_ELEM(mimg,n)=buffer[ii++];
214  }
215 
216  // Write image
217  fnIdx.compose(idx++,fnOut);
218  img.write(fnIdx);
219  }
220  fhInRaw.close();
221  delete []buffer;
222  }
223  }
224 };
Z size (int)
#define YSIZE(v)
#define A2D_ELEM(v, i, j)
#define REPORT_ERROR(nerr, ErrormMsg)
Definition: xmipp_error.h:211
#define MULTIDIM_SIZE(v)
Definition: mask.h:360
HBITMAP buffer
Definition: svm-toy.cpp:37
Couldn&#39;t write to file.
Definition: xmipp_error.h:140
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)
int allowed_data_types
Definition: mask.h:495
void compose(const String &str, const size_t no, const String &ext="")
void write(const FileName &outFile, WriteModeMetaData mode=MD_OVERWRITE) const
virtual IdIteratorProxy< false > ids()
void getBlocksInMetaDataFile(const FileName &inFile, StringVector &blockList)
std::vector< String > StringVector
Definition: xmipp_strings.h:35
int readApplyGeo(const FileName &name, const MDRow &row, const ApplyGeoParams &params=DefaultApplyGeoParams)
#define i
size_t addRow(const MDRow &row) override
#define FOR_ALL_ELEMENTS_IN_ARRAY2D(m)
Y size (int)
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
glob_log first
Number of elements of a type (int) [this is a genereic type do not use to transfer information to ano...
const char * getParam(const char *param, int arg=0)
bool setValue(const MDObject &mdValueIn, size_t id)
size_t addObject() override
size_t firstRowId() const override
Size of data vectors for classification (int)
#define XSIZE(v)
#define FOR_ALL_DIRECT_ELEMENTS_IN_MULTIDIMARRAY(v)
#define ZSIZE(v)
#define DIRECT_MULTIDIM_ELEM(v, n)
void addExampleLine(const char *example, bool verbatim=true)
File or directory does not exist.
Definition: xmipp_error.h:136
Couldn&#39;t read from file.
Definition: xmipp_error.h:139
void readParams(XmippProgram *program)
Definition: mask.cpp:1284
int verbose
Verbosity level.
#define j
void deleteFile() const
bool getValue(MDObject &mdValueOut, size_t id) const override
virtual void setColumnFormat(bool column)
void generate_mask(bool apply_geo=false)
Definition: mask.cpp:1577
X size (int)
FileName withoutExtension() const
#define INT_MASK
Definition: mask.h:385
String formatString(const char *format,...)
bool checkParam(const char *param)
void addUsageLine(const char *line, bool verbatim=false)
const MultidimArray< int > & get_binary_mask() const
Definition: mask.h:707
int * n
Name of an image (std::string)
double sum() const
void addParamsLine(const String &line)