YaDICs  V04.14.a
Yet another Digital Image Correlation software: platform dedicated to 2/3D Fluid and Solid kinematics field measurements.
 All Classes Files Functions Variables Pages
Cimage.h
Go to the documentation of this file.
1 /**********************************************************************
2  * Copyright (C) 2012, The YaDICs Project Developers.
3  * See the COPYRIGHT file at the top-level directory of this distribution ./COPYRIGHT.
4  * See ./COPYING file for copying and redistribution conditions.
5  *
6  * This file is part of YaDICs.
7  * YaDICs 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 3 of the License, or
10  * (at your option) any later version.
11  *
12  * YaDICs 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 YaDICs. If not, see <http://www.gnu.org/licenses/>.
19  *
20  * Information about how to use the software are provided at http://yadic.univ-lille1.fr/
21  **********************************************************************/
22 
23 
24 #ifndef CIMAGE
25 #define CIMAGE
26 
37 //-----------------------------CIMG_NETCDF-------------------------------
38 #define cimg_plugin "plugins/add_fileformat.h"
39 #define cimg_use_netcdf
40 
41 #ifdef cimg_use_netcdf
42  #include "../NetCDF.Tool/struct_parameter_NetCDF.h"
43 // #define cimg_plugin1 "plugins/netcdf_file_format4CImg1.h"
44 // #define cimglist_plugin1 "plugins/netcdf_file_format4CImgList1.h"
45  #define cimg_plugin2 "plugins/netcdf_file_format4CImg2.h"
46  #define cimglist_plugin2 "plugins/netcdf_file_format4CImgList2.h"
47  #include "../CImg.Tool/CImg_NetCDF.h"
48 #endif
49 
50 #include "textcolor.h"
51 //-----------------------------CIMG_NETCDF-------------------------------
52 
53 
56 template<typename Timg>
57 class Cimage
58 {
59 
60  public:
61 
62  std::string class_name;
63  std::string m_name, m_type;
64 
65  CImgList<Timg> m_img, m_curImg;// img_ref and img_def as well as a shared or resized version
66  CImg<char> m_mask, m_curMask;// store mask as well as a shared or resized version
67  CImg<char> m_list;// store image path list
68 
69  std::vector<float> m_pix;// pixel ratio
70  std::string m_maskName, m_dirPath; // paths
71  int m_dim_sample, m_dim_image, m_dim;//number of image to correlate (classically 2), list size (n), image dimension (2 or 3)
72 
73  int m_storeImg, m_storeDef, m_storeRes, m_storeField, m_storeStr, m_storeActiv, m_display, m_mode;//store data & how to treat image sequence
74  float m_Rpxmm;
75  std::string m_oFormat;
76 
77  float m_res;
78 
79  bool m_verbose;
80  const char* m_paramPath;
81 
82 
83  Cimage()
84  {// constructor
85 
86  class_name = "Image : mother";
87 
88  }
89 
90  virtual void init(CParameterNetCDF &fp)
91  {// image list parameters
92 
93  //dependent or separate mode
94  std::string attribute_name = "mode";
95  int error = fp.loadAttribute(attribute_name,m_mode);
96  if (this->m_verbose){printf("\t\t separate list mode -> %i\n", m_mode);}
97 
98  float var(0);
99  std::string m_variable = "output";
100 
101  //load output variable
102  fp.loadVar(var,&m_variable);
103 
104 
105  //output format
106  attribute_name = "format";
107  error = fp.loadAttribute(attribute_name,m_oFormat);
108  if (this->m_verbose){printf("\t\t output file format -> %s\n", m_oFormat.c_str());}
109 
110  //display mode
111  attribute_name = "display_mode";
112  error = fp.loadAttribute(attribute_name,m_display);
113  if (this->m_verbose){printf("\t\t display mode -> %i\n", m_display);}
114 
115  //save input data in netcdf
116  attribute_name = "store_img";
117  error = fp.loadAttribute(attribute_name,m_storeImg);
118  if (this->m_verbose){printf("\t\t input data storage -> %i\n", m_storeImg);}
119 
120  //save corrected deformed image in netcdf
121  attribute_name = "store_def";
122  error = fp.loadAttribute(attribute_name,m_storeDef);
123  if (this->m_verbose){printf("\t\t deformed image storage -> %i\n", m_storeDef);}
124 
125  //save corrected deformed image in netcdf
126  attribute_name = "store_field";
127  error = fp.loadAttribute(attribute_name,m_storeField);
128  if (this->m_verbose){printf("\t\t field storage -> %i\n", m_storeField);}
129 
130  //save image residue in netcdf
131  attribute_name = "store_res";
132  error = fp.loadAttribute(attribute_name,m_storeRes);
133  if (this->m_verbose){printf("\t\t image residue storage -> %i\n", m_storeRes);}
134 
135  m_storeActiv = 0;
136 
137  if (m_storeRes or m_storeField or m_storeDef){m_storeActiv = 1;}
138 
139  //save image residue in netcdf
140  attribute_name = "store_strain";
141  error = fp.loadAttribute(attribute_name,m_storeStr);
142  if (this->m_verbose){printf("\t\t strain field storage -> %i\n", m_storeStr);}
143 
144  //ratio pix mm
145  m_Rpxmm = 1;
146  attribute_name = "ratio_pxmm";
147  error = fp.loadAttribute(attribute_name,m_Rpxmm);
148  if (this->m_verbose){std::cout<<"\t\t ratio pix/mm -> "<<m_Rpxmm<<"\n";}
149 
150  }
151 
152  void exec(int argc, char *argv[], const int &sample = 0)
153  {// exec
154 
155  load_images(m_list, m_dirPath, sample);
156  if (m_maskName != ""){load_mask(m_maskName, m_dirPath);}
157 
158  }
159 
160 
161  virtual void load_paths(CParameterNetCDF &fp) = 0;
162 
163  virtual void load_images(CImg<char> &list, std::string &dir, const int &sample) = 0;
164 
165  void load_mask(std::string &name, std::string &dir)
166  {// load mask from path
167 
168  m_mask.load((dir + name).c_str());// load mask from path
169  m_mask.channel(0);// enforce to use no color images
170  m_mask.abs();
171  m_mask.threshold(1);// enforce to use no color images
172  m_mask.round(1,0);
173 
174  if (this->m_verbose){printf("\t mask : %s\n",(dir + name).c_str());}
175 
176  }
177 
178  void resize(const int &filter)
179  {// resize init images to provides m_curImg if piramidal filter is active
180 
183  m_pix.clear();
184  m_curImg.clear();
185  m_curMask.clear();
186 
187  if (filter != 0)
188  {
189 
190  int suElem = std::pow(2,filter);
191  std::vector<int> X;
192 
193  for (int i=0; i<3; i++)
194  {
195  if (dim(i)>1){X.push_back(dim(i)/suElem);}else{X.push_back(1);}
196  m_pix.push_back(((float)dim(i)/(float)X[i])*m_Rpxmm);
197  }
198 
199  m_curImg.assign(m_img.size(), X[0], X[1], X[2], 1, 0);
200  if (!m_mask.is_empty()){m_curMask.assign(X[0], X[1], X[2], 1, 1);}
201 /*
202  cimglist_for(m_img, list)
203  {// resizing with linear interpolation
204  m_curImg[list] = m_img[list].get_resize(m_curImg[list],3);
205  }
206  if (!m_mask.is_empty()){m_curMask = m_mask.get_resize(m_curMask,3);}
207  */
208 // #pragma omp parallel if (num_dims()==3)
209  #pragma omp parallel
210  {
211 
212  int X(0), Y(0), Z(0);
213 
214  std::vector<double> buff0;
215  double buff1(0), counter(0);
216 
217  #pragma omp for schedule(runtime)
218  for (int pix=0; pix<m_curImg[0].size(); pix++)
219  {
220 
221  m_curImg[0].contains(m_curImg[0][pix],X,Y,Z);
222 
223  buff0.assign(m_img.size(),0);
224  buff1 = 0;
225  counter = 0;
226 
227  for (int x=0; x<suElem; x++)
228  {
229  for (int y=0; y<suElem; y++)
230  {
231  for (int z=0; z<=(suElem-1)*(num_dims()-2); z++)
232  {
233 
234  if (m_img[0].contains(m_img(0,X*suElem+x, Y*suElem+y, Z*suElem+z,0)))
235  {
236 
237  counter++;
238 
239  cimglist_for(m_img, list)
240  {// resizing with linear interpolation
241  buff0[list] += m_img(list, X*suElem+x, Y*suElem+y, Z*suElem+z);
242  }
243 
244  if (!m_mask.is_empty())
245  {buff1 += m_mask(X*suElem+x, Y*suElem+y, Z*suElem+z);}
246 
247  }//contains
248  }//for z
249  }//for y
250  }//for x
251 
252  cimglist_for(m_curImg, list){m_curImg[list][pix] = buff0[list]/counter;}
253  if (!m_mask.is_empty()){m_curMask[pix] = buff1/counter;}
254 
255  }//for super pixels
256 
257  }//parallele
258 
259  }
260  else
261  {
262 
265  m_curImg = m_img.get_shared();
266  if (!m_mask.is_empty()){m_curMask = m_mask.get_shared();}
267 
268  for (int i=0; i<3; i++)
269  {
270  if (dim(i)>1){m_pix.push_back(m_Rpxmm);}else{m_pix.push_back(1);}
271  }
272 
273  }
274 
275 
276 // m_img.print();
277 // m_curImg.print();
278 // if (!m_mask.is_empty()){
279 // m_mask.print();
280 // m_curMask.print();}
281 
282 
283  //reference residue between both images
284  m_res = 0;
285  for (int p=0; p<m_curImg[0].size(); p++)
286  {m_res += std::pow((double)m_curImg[0][p]-(double)m_curImg[1][p],2);}
287  m_res = std::sqrt(m_res);
288 
289  std::cout<<"\nreference residue at current scale : "<<m_res<<" in GL\n";
290 
291  }
292 
293 
294  template<typename T>
295  void save_netcdf(CImgList<T> &img, std::string name = "images", const int &sample = 0) const
296  {// allow to stored any input CImgList<T>
297 
298  std::string path;
299  std::ostringstream sample_index;
300 
302  int n = std::floor(log10(img.size()) + 1);
303 
304  img.dim_names.clear();
305  if (img[0].width() != 1 ){img.dim_names.push_back( "dimX" );}
306  if (img[0].height() != 1 ){img.dim_names.push_back( "dimY" );}
307  if (img[0].depth() != 1 ){img.dim_names.push_back( "dimZ" );}
308  if (img[0].spectrum() != 1 ){img.dim_names.push_back( "dimC" );}
309 
310  img.var_names.clear();
311  img.unit_names.clear();
312  cimglist_for(img,L)
313  {
314 
315  sample_index.width(n);
316  sample_index.fill('0');
317  sample_index << L;
318 
319  path = "Var_" + sample_index.str();
320 
321  img.var_names.push_back( path );
322  img.unit_names.push_back( "none" );
323 
324  sample_index.str("");
325 
326  }
327 
328  std::string output_name = name + ".nc";
329 
330  save_unlimited(img, output_name, sample);
331 
332  }
333 
334  template<typename T>
335  void save_netcdf(CImg<T> &img, std::string name = "images", const int sample = 0) const
336  {// allow to stored any input CImg<T>
337 
338  img.dim_names.clear();
339  if (img.width() != 1 ){img.dim_names.push_back( "dimX" );}
340  if (img.height() != 1 ){img.dim_names.push_back( "dimY" );}
341  if (img.depth() != 1 ){img.dim_names.push_back( "dimZ" );}
342  if (img.spectrum() != 1 ){img.dim_names.push_back( "dimC" );}
343 
344  img.var_name = "Var";
345  img.unit_name = "none";
346 
347  std::string output_name = name + ".nc";
348 
349  save_unlimited(img, output_name, sample);
350 
351  }
352 
353  template<typename T>
354  void save_unlimited(CImgList<T> &imgOut, std::string &fileOut, const int &i) const
355  {// add data along unlimited dimension depending on the sample number
356 
361  //save first
362  #ifdef cimg_plugin1
363  imgOut.save(fileOut.c_str());
364  #else //cimg_plugin2
365  if (imgOut[0].depth() == 1){// enforce z dimension
366  imgOut.dim_names.push_back( "dummy_0" );}
367  if (imgOut[0].spectrum() == 1){// enforce c dimension
368  imgOut.dim_names.push_back( "dummy_1" );}
369  imgOut.dim_time="dimS";// enfore dim_time
370  if(i==0)
371  {//save first
372  imgOut.pNc_file=NULL;//should be in CImg constructors
373  imgOut.NetCDF_init();
374  imgOut.save(fileOut.c_str());
375  imgOut.is_NetCDF_open=true;//should be in CImg::save_netcdf (but "const": save_netcdf(const char *filename) const)
376  }//save first
377  else
378  {//save next
379  imgOut.save(fileOut.c_str());
380  }//save next
381  #endif //cimg_plugin2
382 
383  }
384 
385  template<typename T>
386  void save_unlimited(CImg<T> &imgOut, std::string &fileOut, const int &i) const
387  {// add data along unlimited dimension depending on the sample number
388 
393  //save first
394  #ifdef cimg_plugin1
395  imgOut.save(fileOut.c_str());
396  #else //cimg_plugin2
397  if (imgOut.depth() == 1){// enforce z dimension
398  imgOut.dim_names.push_back( "dummy_0" );}
399  if (imgOut.spectrum() == 1){// enforce c dimension
400  imgOut.dim_names.push_back( "dummy_1" );}
401  imgOut.dim_time="dimS";// enfore dim_time
402  if(i==0)
403  {//save first
404  imgOut.pNc_file=NULL;//should be in CImg constructors
405  imgOut.NetCDF_init();
406  imgOut.save(fileOut.c_str());
407  imgOut.is_NetCDF_open=true;//should be in CImg::save_netcdf (but "const": save_netcdf(const char *filename) const)
408  }//save first
409  else
410  {//save next
411  imgOut.save(fileOut.c_str());
412  }//save next
413  #endif //cimg_plugin2
414 
415  }
416 
417 
418 
419  int num_var() const
420  {// "num_var" provides the number of image to correlate
421 
422  return m_curImg.size();
423 
424  }
425 
426  int cur_dim(const int &i) const
427  {// provides spatial dimensions "X,Y,Z" and color channel dimension "C" of images to correlate
428 
429  switch(i)
430  {
431  case 0: return m_curImg[0].width(); break;
432  case 1: return m_curImg[0].height(); break;
433  case 2: return m_curImg[0].depth(); break;
434  case 3: return m_curImg[0].spectrum(); break;
435  default:
436  {
437  std::cerr<<class_name<<"::"<<__func__<<": error: id="<<i<<" is unknown as CImg dimensions\n"<<std::flush;
438  return 0;
439  }
440  }
441  }
442 
443  int dim(const int &i) const
444  {// provides spatial dimensions "X,Y,Z" and color channel dimension "C" of images to correlate
445 
446  switch(i)
447  {
448  case 0: return m_img[0].width(); break;
449  case 1: return m_img[0].height(); break;
450  case 2: return m_img[0].depth(); break;
451  case 3: return m_img[0].spectrum(); break;
452  default:
453  {
454  std::cerr<<class_name<<"::"<<__func__<<": error: id="<<i<<" is unknown as CImg dimensions\n"<<std::flush;
455  return 0;
456  }
457  }
458  }
459 
460  int num_dims() const
461  {// "num_dims" provides the number of active image dimensions
462 
463  return m_dim;
464 
465  }
466 
467  int num_samples() const
468  {// "num_samples" provides the number image within image list
469 
470  return m_dim_sample;
471 
472  }
473 
474 };
475 
476 #endif
void save_netcdf(CImgList< T > &img, std::string name="images", const int &sample=0) const
Definition: Cimage.h:295
void save_unlimited(CImgList< T > &imgOut, std::string &fileOut, const int &i) const
Definition: Cimage.h:354
void resize(const int &filter)
Definition: Cimage.h:178
void save_unlimited(CImg< T > &imgOut, std::string &fileOut, const int &i) const
Definition: Cimage.h:386
Definition: Cimage.h:57