Statistiques
| Révision :

root / src / lsm_cells.cpp @ 21

Historique | Voir | Annoter | Télécharger (18,88 ko)

1 18 akiss
/*
2 18 akiss
Level-set Method to detect cell's contours
3 18 akiss
Parallel standard version
4 18 akiss

5 18 akiss
To compile :
6 18 akiss
 g++ -o lsm_cells_20160610.exe lsm_cells_20160610.cpp -O2 -L/usr/X11R6/lib -lm -lpthread -lX11 -fopenmp
7 18 akiss
 Need CImg.h and lsm_lib.h
8 18 akiss

9 18 akiss
To execute :
10 18 akiss
 ./lsm_cells.exe img img_wat img_contour erosion
11 18 akiss

12 18 akiss
 image in .inr or .inr.gz, save in .inr.gz
13 18 akiss
 img : grayscale image of cells (unsigned char)
14 18 akiss
 img_wat : watershed 16bits image (unsigned short) with background label 1 and cells labels >1
15 18 akiss
 img_contour : binary image with background=1, all cells=0 (unsigned char)
16 18 akiss
 erosion : amount of erosion for each cell in watershed image (int)
17 18 akiss
*/
18 18 akiss
19 18 akiss
#include <iostream>
20 18 akiss
#include <math.h>
21 18 akiss
#include <sstream>
22 18 akiss
#include <vector>
23 18 akiss
#include <fstream>
24 18 akiss
#include <omp.h>
25 18 akiss
26 18 akiss
#include "CImg.h"
27 18 akiss
#include "lsm_lib.h"
28 18 akiss
29 18 akiss
using namespace cimg_library;
30 18 akiss
using namespace std;
31 18 akiss
32 18 akiss
33 18 akiss
//Return list of cell label
34 18 akiss
//---------------------------------------------------------------------
35 18 akiss
vector<int> index(const CImg<unsigned short> & wat, int nbcells)
36 18 akiss
{
37 18 akiss
  vector<int> list;
38 18 akiss
  vector<bool> test(nbcells,false);
39 18 akiss
  cimg_forXYZ(wat,x,y,z)
40 18 akiss
    {
41 18 akiss
      int ind=wat(x,y,z);
42 18 akiss
      if((test[ind]==false)and(ind!=1)and(ind!=0))
43 18 akiss
        {
44 18 akiss
          list.push_back(ind);
45 18 akiss
          test[ind]=true;
46 18 akiss
        }
47 18 akiss
    }
48 18 akiss
  return list;
49 18 akiss
}
50 18 akiss
51 18 akiss
//Return crop psi image and it's min coordinates for one cell
52 18 akiss
//--------------------------------------------------------------------
53 18 akiss
CImg<float> box_cell(const CImg<unsigned short> & wat, int marge,int erosion, int c0,int indice, int &xmin, int &ymin, int &zmin)
54 18 akiss
{
55 18 akiss
  //search box (min and max coordinates with a marge)
56 18 akiss
  xmin=wat._width;
57 18 akiss
  ymin=wat._height;
58 18 akiss
  zmin=wat._depth;
59 18 akiss
  int xmax=0;
60 18 akiss
  int ymax=0;
61 18 akiss
  int zmax=0;
62 18 akiss
  cimg_forXYZ(wat,x,y,z)
63 18 akiss
    {
64 18 akiss
      if(wat(x,y,z)==indice)
65 18 akiss
        {
66 18 akiss
          if(x>xmax){xmax=x;}else if(x<xmin){xmin=x;}
67 18 akiss
          if(y>ymax){ymax=y;}else if(y<ymin){ymin=y;}
68 18 akiss
          if(z>zmax){zmax=z;}else if(z<zmin){zmin=z;}
69 18 akiss
        }
70 18 akiss
    }
71 18 akiss
  //marge and border conditions
72 18 akiss
  xmin=xmin-marge;
73 18 akiss
  if(xmin<0){xmin=0;}
74 18 akiss
  ymin=ymin-marge;
75 18 akiss
  if(ymin<0){ymin=0;}
76 18 akiss
  zmin=zmin-marge;
77 18 akiss
  if(zmin<0){zmin=0;}
78 18 akiss
  xmax=xmax+marge;
79 18 akiss
  if(xmax>=wat._width){xmax=wat._width-1;}
80 18 akiss
  ymax=ymax+marge;
81 18 akiss
  if(ymax>=wat._height){ymax=wat._height-1;}
82 18 akiss
  zmax=zmax+marge;
83 18 akiss
  if(zmax>=wat._depth){zmax=wat._depth-1;}
84 18 akiss
85 18 akiss
  //crop wat image to the size of box, make binary
86 18 akiss
  CImg<unsigned short>binary=wat.get_crop(xmin,ymin,zmin,0,xmax,ymax,zmax,0);
87 18 akiss
  cimg_forXYZ(binary,x,y,z)
88 18 akiss
    {
89 18 akiss
      if(binary(x,y,z)==indice){binary(x,y,z)=1;}
90 18 akiss
      else {binary(x,y,z)=0;}
91 18 akiss
    }
92 18 akiss
93 18 akiss
  //erode binary but not completely (vol stay >0)
94 18 akiss
  int vol=binary.sum();
95 18 akiss
  int nb_ero=0;
96 18 akiss
  while((vol>0)and(nb_ero<abs(erosion)))
97 18 akiss
  {
98 18 akiss
    CImg<unsigned char> binary_erode=binary.get_erode(3,3,3);
99 18 akiss
        if (erosion<0)
100 18 akiss
        {
101 18 akiss
                for(int i=0;i<3;i++)
102 18 akiss
                {
103 18 akiss
                binary=binary.get_dilate(2,2,2);
104 18 akiss
                }
105 18 akiss
                binary_erode=binary;
106 18 akiss
        }
107 18 akiss
      vol=binary_erode.sum();
108 18 akiss
      if(vol>0)
109 18 akiss
        {
110 18 akiss
          binary=binary_erode;
111 18 akiss
          nb_ero+=1;
112 18 akiss
        }
113 18 akiss
    }
114 18 akiss
115 18 akiss
  //initalize psi
116 18 akiss
  CImg<float>psi=binary;
117 18 akiss
  cimg_forXYZ(psi,x,y,z)
118 18 akiss
    {
119 18 akiss
      if(binary(x,y,z)==0){psi(x,y,z)=c0;}
120 18 akiss
      else {psi(x,y,z)=-c0;}
121 18 akiss
    }
122 18 akiss
  return psi;
123 18 akiss
}
124 18 akiss
125 18 akiss
126 18 akiss
//LSM segment : edge detection
127 18 akiss
//---------------------------------------------------------------------
128 18 akiss
CImg<float> lsm_segment2(CImg<float> psi,CImg<float> const & g,CImgList<float> const & gg,CImg<float> const & h, int lam, float mu,float alf, float beta, float epsilon, int dt, vector<int> min_list)
129 18 akiss
{
130 18 akiss
  int timestep_max=2000;
131 18 akiss
  int evolution_min=1;
132 18 akiss
  int evolution_max=-1;
133 18 akiss
  int it=0;
134 18 akiss
  int it_stop=0;
135 18 akiss
  bool contour_evolve=true;
136 18 akiss
  int backsegm=0;
137 18 akiss
  cimg_forXYZ(psi,x,y,z)
138 18 akiss
    {
139 18 akiss
      if(psi(x,y,z)>=0){backsegm+=1;}
140 18 akiss
    }
141 18 akiss
142 18 akiss
  while((it<timestep_max)and(contour_evolve==true)and(backsegm>30))
143 18 akiss
    {
144 18 akiss
      //evolution
145 18 akiss
      psi=evolution_AK2_contour_cells(psi,g,gg,h,lam,mu,alf,beta,epsilon,dt,min_list);
146 18 akiss
      //new segmentation
147 18 akiss
      int new_backsegm=0;
148 18 akiss
      cimg_forXYZ(psi,x,y,z)
149 18 akiss
        {
150 18 akiss
          if(psi(x,y,z)>=0){new_backsegm+=1;}
151 18 akiss
        }
152 18 akiss
153 18 akiss
      //Stop criteria
154 18 akiss
      int bg_evolution=abs(new_backsegm-backsegm);
155 18 akiss
      /*
156 18 akiss
      if((it>20)and(bg_evolution<evolution_min))
157 18 akiss
        {contour_evolve=false;}
158 18 akiss
        */
159 18 akiss
160 18 akiss
      //New stop criteria
161 18 akiss
      if((it>10) and (bg_evolution<=evolution_min) and (bg_evolution>=evolution_max))
162 18 akiss
        {
163 18 akiss
          it_stop+=1;
164 18 akiss
          if(it_stop>1)
165 18 akiss
            {contour_evolve=false;}
166 18 akiss
        }
167 18 akiss
      else
168 18 akiss
        {
169 18 akiss
          it_stop=0;
170 18 akiss
        }
171 18 akiss
172 18 akiss
173 18 akiss
174 18 akiss
175 18 akiss
      it+=1;
176 18 akiss
      backsegm=new_backsegm;
177 18 akiss
    }
178 18 akiss
179 18 akiss
  cimg_forXYZ(psi,x,y,z)
180 18 akiss
    {
181 18 akiss
      if(psi(x,y,z)>=0){psi(x,y,z)=4;}
182 18 akiss
      else{psi(x,y,z)=-4;}
183 18 akiss
    }
184 18 akiss
185 18 akiss
  return psi;
186 18 akiss
}
187 18 akiss
188 18 akiss
189 18 akiss
//Reconstruct full segmented image from cell's images
190 18 akiss
//---------------------------------------------------------------
191 18 akiss
CImg<unsigned short> reconstruct(const CImg<unsigned char> & background,const vector<CImg<float> > & psi_list, const vector< vector<int> > & min_list, int nbcells,const vector<int> & list)
192 18 akiss
{
193 18 akiss
  CImg<unsigned short> res=background;
194 18 akiss
  for(int i=0;i<nbcells;i++)
195 18 akiss
    {
196 18 akiss
      cimg_forXYZ(psi_list[i],xb,yb,zb)
197 18 akiss
        {
198 18 akiss
          int x=xb+min_list[i][0];
199 18 akiss
          int y=yb+min_list[i][1];
200 18 akiss
          int z=zb+min_list[i][2];
201 18 akiss
          if(psi_list[i](xb,yb,zb)>=0)
202 18 akiss
            {res(x,y,z)=list[i];}
203 18 akiss
        }
204 18 akiss
    }
205 18 akiss
  return res;
206 18 akiss
}
207 18 akiss
208 18 akiss
//Reconstruct segmented image from cell's images and treat overlap
209 18 akiss
//---------------------------------------------------------------
210 18 akiss
CImg<unsigned short> reconstruct_overlap(CImg<unsigned char> const &  background,const vector<CImg<float> > & psi_list, const vector< vector<int> > & min_list, int nbcells, CImg<unsigned char> &free, const vector<int> & list)
211 18 akiss
{
212 18 akiss
  CImg<unsigned short> res=background;
213 18 akiss
  free=background;
214 18 akiss
  for(int i=0;i<nbcells;i++)
215 18 akiss
    {
216 18 akiss
      cimg_forXYZ(psi_list[i],xb,yb,zb)
217 18 akiss
        {
218 18 akiss
          int x=xb+min_list[i][0];
219 18 akiss
          int y=yb+min_list[i][1];
220 18 akiss
          int z=zb+min_list[i][2];
221 18 akiss
          if(psi_list[i](xb,yb,zb)>=0)
222 18 akiss
            {
223 18 akiss
              res(x,y,z)=list[i];
224 18 akiss
              free(x,y,z)+=1;
225 18 akiss
            }
226 18 akiss
        }
227 18 akiss
    }
228 18 akiss
  cimg_forXYZ(free,x,y,z)
229 18 akiss
    {
230 18 akiss
      if(free(x,y,z)>1)
231 18 akiss
        {
232 18 akiss
          if(background(x,y,z)==1)
233 18 akiss
            {
234 18 akiss
              free(x,y,z)=1;
235 18 akiss
              res(x,y,z)=1;
236 18 akiss
            }
237 18 akiss
          else
238 18 akiss
            {
239 18 akiss
              free(x,y,z)=0;
240 18 akiss
              res(x,y,z)=0;
241 18 akiss
            }
242 18 akiss
        }
243 18 akiss
    }
244 18 akiss
  return res;
245 18 akiss
}
246 18 akiss
247 18 akiss
248 18 akiss
//-----------------------------------------------------------------------------------------------
249 18 akiss
//******************************************  MAIN **********************************************
250 18 akiss
//-----------------------------------------------------------------------------------------------
251 18 akiss
252 18 akiss
int main (int argc, char* argv[])
253 18 akiss
{
254 18 akiss
  double begin=omp_get_wtime();
255 18 akiss
256 18 akiss
  if(argc<5)
257 18 akiss
    {
258 18 akiss
    cout<<"!! wrong number of arguments ("<<argc<<")"<<endl;
259 18 akiss
    cout<<"how to execute : ./lsm_cells.exe img img_wat img_contour erosion [a b smooth lsm_type]"<<endl;
260 18 akiss
    cout<<"----------------- "<<endl;
261 18 akiss
        cout<<"img : grayscale image of cells, (.inr or .inr.gz)"<<endl;
262 18 akiss
        cout<<"img_wat : image of seeds, (.inr or .inr.gz)"<<endl;
263 18 akiss
        cout<<"img_contour : mask, where cells do not evolve, (.inr or .inr.gz)"<<endl;
264 18 akiss
        cout<<"              if 'None', then cells can evolve on the whole image"<<endl;
265 18 akiss
        cout<<"erosion : amount of erosion of seeds for initialisation (uint8) --> -2, 0, 2"<<endl;
266 18 akiss
        cout<<"              if 0, then no erosion or dilation"<<endl;
267 18 akiss
        cout<<"              if negative, then a dilation is performed"<<endl;
268 18 akiss
        cout<<"a : area term (float) --> 0 or 0.5 or 1 (the default is 0.5)"<<endl;
269 18 akiss
        cout<<"              if negative, the object retracts"<<endl;
270 18 akiss
        cout<<"              if positive, the object inflates"<<endl;
271 18 akiss
        cout<<"b : curvature term (float) --> 0 or 1 (the default is 0)"<<endl;
272 18 akiss
        cout<<"gamma : scale parameter (float>0) --> 0.5 or 1 (the default is 0)"<<endl;
273 18 akiss
        cout<<"smooth : gaussian blur to apply to the image (int) --> 0 or 1 (the default is 0)"<<endl;
274 18 akiss
    cout<<"lsm_type : image, gradient or hessien based evolution --> 'i', 'g' or 'h' (the default is g)"<<endl;
275 18 akiss
      return 0;
276 18 akiss
    }
277 18 akiss
278 18 akiss
  //----------------------------------------------read images and check the names
279 18 akiss
  //Original image
280 18 akiss
  CImg<char> description;
281 18 akiss
  float tailleVoxel[3] = {0}; // resolution initialisation
282 18 akiss
  //float tailleVoxel[3] = {0.195177,0.195177,0.195177};
283 18 akiss
284 18 akiss
  bool gzipped=false;
285 18 akiss
286 18 akiss
  string filename_img=argv[1];
287 18 akiss
  CImg<unsigned char> img_prev;
288 18 akiss
  if(filename_img.compare(filename_img.size()-4,4,".inr")==0)
289 18 akiss
    {
290 18 akiss
      img_prev.load(filename_img.c_str());
291 18 akiss
      img_prev.get_load_inr(filename_img.c_str(),tailleVoxel); // reads resolution
292 18 akiss
    }
293 18 akiss
  else if(filename_img.compare(filename_img.size()-7,7,".inr.gz")==0)
294 18 akiss
    {
295 18 akiss
          gzipped = true;
296 18 akiss
      string oldname = filename_img;
297 18 akiss
      filename_img.erase(filename_img.size()-3);
298 18 akiss
      string zip="gunzip -c "+oldname+" > "+filename_img;
299 18 akiss
      if(system(zip.c_str())); // decompress image file
300 18 akiss
      img_prev.load(filename_img.c_str());
301 18 akiss
      img_prev.get_load_inr(filename_img.c_str(),tailleVoxel); // reads resolution
302 18 akiss
      zip="rm "+filename_img;
303 18 akiss
      if(system(zip.c_str())); //removes decompressed image
304 18 akiss
    }
305 18 akiss
  else
306 18 akiss
    {cout<<"!! wrong file extension : "<<filename_img<<endl;
307 18 akiss
      return 0;}
308 18 akiss
  CImg<float> img=img_prev;
309 18 akiss
  img_prev.assign();
310 18 akiss
  cout<<"original image : "<<filename_img<<endl;
311 18 akiss
  cout<<"size : "<<img.size()<<endl;
312 18 akiss
  cout<<"size of original image : "<< img._width<<' '<< img._height <<' '<< img._depth<<' '<< endl;
313 18 akiss
314 18 akiss
  //Watershed
315 18 akiss
  string filename=argv[2];
316 18 akiss
  CImg<unsigned short> wat;
317 18 akiss
  if(filename.compare(filename.size()-4,4,".inr")==0)
318 18 akiss
    {
319 18 akiss
      wat.load(filename.c_str());
320 18 akiss
    }
321 18 akiss
  else if(filename.compare(filename.size()-7,7,".inr.gz")==0)
322 18 akiss
    {
323 18 akiss
      wat.load_gzip_external(filename.c_str());
324 18 akiss
      filename.erase(filename.size()-3);
325 18 akiss
    }
326 18 akiss
  else
327 18 akiss
    {cout<<"!! wrong file extension : "<<filename<<endl;
328 18 akiss
      return 0;}
329 18 akiss
  cout<<"watershed image : "<<filename<<endl;
330 18 akiss
cout<<"size : "<<wat.size()<<endl;
331 18 akiss
  cout<<"size of original image : "<< wat._width<<' '<< wat._height <<' '<< wat._depth<<' '<< endl;
332 18 akiss
333 18 akiss
  //Background
334 18 akiss
  string filename_bg=argv[3];
335 18 akiss
  CImg<unsigned char> background(img._width, img._height, img._depth,1,0);
336 18 akiss
   if(filename_bg.compare("None")==0)
337 18 akiss
    {
338 18 akiss
       cout<<"!! no background entered !!"<<endl;
339 18 akiss
    }
340 18 akiss
    else if(filename_bg.compare(filename_bg.size()-4,4,".inr")==0)
341 18 akiss
    {
342 18 akiss
      background.load(filename_bg.c_str());
343 18 akiss
    }
344 18 akiss
  else if(filename_bg.compare(filename_bg.size()-7,7,".inr.gz")==0)
345 18 akiss
    {
346 18 akiss
      background.load_gzip_external(filename_bg.c_str());
347 18 akiss
      filename_bg.erase(filename_bg.size()-3);
348 18 akiss
    }
349 18 akiss
  else
350 18 akiss
    {cout<<"!! wrong file extension : "<<filename_bg<<endl;
351 18 akiss
      return 0;}
352 18 akiss
  cout<<"background image : "<<filename_bg<<endl;
353 18 akiss
354 18 akiss
  if((wat.size()!=img.size())or(background.size()!=img.size()))
355 18 akiss
    {
356 18 akiss
      cout<<"!! images are not the same size"<<endl;
357 18 akiss
      return 0;
358 18 akiss
    }
359 18 akiss
  else cout<<"size : "<<img.size()<<endl;
360 18 akiss
361 18 akiss
362 18 akiss
  //---------------------------------------------------------------Parameters
363 18 akiss
  //model parameters
364 18 akiss
  //int alfabis=100;
365 18 akiss
  //float betabis=0;
366 18 akiss
367 18 akiss
  int c0=-4;
368 18 akiss
  int erosion=atoi(argv[4]);
369 18 akiss
  int marge=10; //10
370 18 akiss
371 18 akiss
  int lam=10;
372 18 akiss
  float alf=0.5;//1
373 18 akiss
  float beta=0;
374 18 akiss
  float gamma=1;
375 18 akiss
  float smooth=0;
376 18 akiss
  string lsm_type="g";
377 18 akiss
378 18 akiss
  string ar=argv[4];
379 18 akiss
  string insert="_cellLSM-d"+ar;
380 18 akiss
  if(argc>5)
381 18 akiss
    {
382 18 akiss
    alf=atof(argv[5]);
383 18 akiss
    ar=argv[5];
384 18 akiss
    insert=insert+"-a"+ar;
385 18 akiss
    }
386 18 akiss
  if(argc>6)
387 18 akiss
    {
388 18 akiss
    beta=atof(argv[6]);
389 18 akiss
    ar=argv[6];
390 18 akiss
    insert+="-b"+ar;
391 18 akiss
    }
392 18 akiss
  if(argc>7)
393 18 akiss
    {
394 18 akiss
    gamma=atof(argv[7]);
395 18 akiss
    ar=argv[7];
396 18 akiss
    insert+="-g"+ar;
397 18 akiss
        }
398 18 akiss
  if(argc>8)
399 18 akiss
    {
400 18 akiss
    smooth=atof(argv[8]);
401 18 akiss
    ar=argv[8];
402 18 akiss
    insert+="-s"+ar;
403 18 akiss
        }
404 18 akiss
  if(argc>9)
405 18 akiss
    {
406 18 akiss
        lsm_type=argv[9];
407 18 akiss
        ar=argv[9];
408 18 akiss
        insert+="-"+ar;
409 18 akiss
        }
410 18 akiss
411 18 akiss
412 18 akiss
413 18 akiss
  //numerical parameters
414 18 akiss
  float epsilon=0.5;
415 18 akiss
  int dt=1;   //it was 50, changed into 1 the 2015/10/16
416 18 akiss
  float mu=0.1/dt;
417 18 akiss
  int timestep_max=10000; // it was 1000, changed into 10000 the 2015/10/16
418 18 akiss
419 18 akiss
420 18 akiss
  //------------------------------------Names and directories
421 18 akiss
  //new name with arguments
422 18 akiss
  //string ar=argv[4];
423 18 akiss
  //string insert="_cellLSM-d"+ar;
424 18 akiss
  filename.insert(filename.size()-4,insert);
425 18 akiss
426 18 akiss
  //create directories and update names
427 18 akiss
  size_t test=filename.rfind("/");
428 18 akiss
  if(test!=filename.npos)
429 18 akiss
    {filename.erase(0,test+1);}
430 18 akiss
  string outputdir=filename;
431 18 akiss
  outputdir.erase(filename.size()-4);
432 18 akiss
  string mkdir="mkdir -p "+outputdir;
433 18 akiss
  int syst=system(mkdir.c_str());
434 18 akiss
  mkdir="mkdir -p "+outputdir+"/evolution";
435 18 akiss
  syst=system(mkdir.c_str());
436 18 akiss
437 18 akiss
  string filename_cut=outputdir+"/evolution/"+filename;
438 18 akiss
  filename_cut.erase(filename_cut.size()-4);
439 18 akiss
  filename=outputdir+"/"+filename;
440 18 akiss
  string wat_eroded_name=filename;
441 18 akiss
  wat_eroded_name.insert(filename.size()-4,"_eroded");
442 18 akiss
  string edge_detection_name=filename;
443 18 akiss
  edge_detection_name.insert(filename.size()-4,"_evoEdge");
444 18 akiss
  string edge_evolve_name=filename;
445 18 akiss
  edge_evolve_name.insert(filename.size()-4,"_final");
446 18 akiss
447 18 akiss
  //txt files
448 18 akiss
  ofstream file;
449 18 akiss
  string txt_name=filename_cut+".txt";
450 18 akiss
  file.open(txt_name.c_str());
451 18 akiss
  file<<argv[0]<<endl;
452 18 akiss
  time_t t;
453 18 akiss
  struct tm * timeinfo;
454 18 akiss
  time(&t);
455 18 akiss
  timeinfo=localtime(&t);
456 18 akiss
  file<<asctime(timeinfo);
457 18 akiss
  file<<"image : "<<argv[1]<<endl;
458 18 akiss
  file<<"watershed : "<<argv[2]<<endl;
459 18 akiss
  file<<"background : "<<argv[3]<<endl;
460 18 akiss
  file<<"_________________________________"<<endl;
461 18 akiss
  file<<"Parameters"<<endl;
462 18 akiss
  file<<"lsm_type : "<<lsm_type<<endl;
463 18 akiss
  file<<"lambda : "<<lam<<endl;
464 18 akiss
  file<<"alpha : "<<alf<<endl;
465 18 akiss
  file<<"beta : "<<beta<<endl;
466 18 akiss
  file<<"gamma :"<<gamma<<endl;
467 18 akiss
  //file<<"alphabis : "<<alfabis<<endl;
468 18 akiss
  //file<<"betabis : "<<betabis<<endl;
469 18 akiss
  file<<"erosion : "<<erosion<<endl;
470 18 akiss
  file<<"marge : "<<marge<<endl;
471 18 akiss
  file<<"epsilon : "<<epsilon <<endl;
472 18 akiss
  file<<"mu : "<<mu <<endl;
473 18 akiss
  file<<"dt : "<<dt <<endl;
474 18 akiss
  file<<"timestep_max : "<<timestep_max <<endl;
475 18 akiss
476 18 akiss
  //-----------------------------------------Image Pre-processing
477 18 akiss
  //define cut
478 18 akiss
  int cut=img._depth/2;
479 18 akiss
  cut = 82;
480 18 akiss
  cout <<"cut z= "<<cut<<endl;
481 18 akiss
  file <<"\ncut z= "<<cut<<endl;
482 18 akiss
  CImg<float> imgCut=img.get_crop(0,0,cut,0,img._width,img._height,cut,0);
483 18 akiss
  imgCut.save((filename_cut+".png").c_str());
484 18 akiss
485 18 akiss
  //smooth image
486 18 akiss
  file<<"smooth : "<<smooth<<endl;
487 18 akiss
  if (smooth>0)
488 18 akiss
  {
489 18 akiss
  img.blur(smooth);
490 18 akiss
  }
491 18 akiss
492 18 akiss
  //-------------------------------------Initialization with erosion
493 18 akiss
  //compute fixed terms
494 18 akiss
  CImg<float> g;
495 18 akiss
  if(lsm_type.compare("g")==0)
496 18 akiss
    {
497 18 akiss
  g=edge_indicator1(img, gamma);
498 18 akiss
    }
499 18 akiss
  else if (lsm_type.compare("h")==0)
500 18 akiss
   {
501 18 akiss
  g=edge_indicator2s(img, gamma);
502 18 akiss
   }
503 18 akiss
  else if (lsm_type.compare("i")==0)
504 18 akiss
   {
505 18 akiss
  g=edge_indicator3(img, gamma);
506 18 akiss
   }
507 18 akiss
  else
508 18 akiss
  cout<<"Wrong lsm type given :'"<<lsm_type<<"'('g' for gradient-based, 'h' for Hessien-based) "<<endl;
509 18 akiss
510 18 akiss
  CImgList<float> gg=gradient(g);
511 18 akiss
  CImg<float> h=g;
512 18 akiss
  img.assign();
513 18 akiss
514 18 akiss
  // save edge indicator
515 18 akiss
  string edge_indicator_name = "edge_indicator.inr";
516 18 akiss
  g.save_inr(edge_indicator_name.c_str(),tailleVoxel);
517 18 akiss
  string zip="gzip -f "+edge_indicator_name;
518 18 akiss
  syst=system(zip.c_str());
519 18 akiss
520 18 akiss
  //g.crop(0,0,cut,0,g._width,g._height,cut,0);
521 18 akiss
  //g.normalize(0,255).save((filename_cut+"_edge_indicator.png").c_str());
522 18 akiss
  // warning !!! once normalised, one cannot do computations with it
523 18 akiss
524 18 akiss
  CImg<float> gout=g;
525 18 akiss
  gout.crop(0,0,cut,0,g._width,g._height,cut,0);
526 18 akiss
  gout.normalize(0,255).save((filename_cut+"_edge_indicator.png").c_str());
527 18 akiss
  gout.assign();
528 18 akiss
529 18 akiss
  //initialize psi for every cell
530 18 akiss
  int maxcells=wat.max()+1; //indice maximum
531 18 akiss
  vector<int> list=index(wat,maxcells);
532 18 akiss
  int nbcells=list.size();
533 18 akiss
  cout<<"number of cells : "<<nbcells<<endl;
534 18 akiss
  file<<"number of cells : "<<nbcells<<endl;
535 18 akiss
  vector<CImg<float> > psi_list(nbcells);
536 18 akiss
  vector<vector<int> > min_list(nbcells,vector<int>(3,0));
537 18 akiss
  vector<vector<int> > max_list(nbcells,vector<int>(3,0));
538 18 akiss
539 18 akiss
#pragma omp parallel shared(wat,marge,erosion,c0,psi_list,min_list,list)
540 18 akiss
  {
541 18 akiss
  int xmin=0;
542 18 akiss
  int ymin=0;
543 18 akiss
  int zmin=0;
544 18 akiss
#pragma omp for schedule(dynamic)
545 18 akiss
  for(int i=0;i<nbcells;i++)
546 18 akiss
    {
547 18 akiss
      int ind=list[i];
548 18 akiss
      psi_list[i]=box_cell(wat,marge,erosion,c0,ind,xmin,ymin,zmin);
549 18 akiss
      min_list[i][0]=xmin;
550 18 akiss
      min_list[i][1]=ymin;
551 18 akiss
      min_list[i][2]=zmin;
552 18 akiss
      cout <<"cell "<<ind<<endl;
553 18 akiss
    }
554 18 akiss
  }
555 18 akiss
  wat.assign();
556 18 akiss
557 18 akiss
  //reconstruct image of eroded cell
558 18 akiss
  CImg<unsigned short> wat_eroded=reconstruct(background,psi_list,min_list,nbcells,list);
559 18 akiss
  wat_eroded.save_inr(wat_eroded_name.c_str(),tailleVoxel);
560 18 akiss
  zip="gzip -f "+wat_eroded_name;
561 18 akiss
  syst=system(zip.c_str());
562 18 akiss
  wat_eroded.crop(0,0,cut,0,wat_eroded._width,wat_eroded._height,cut,0);
563 18 akiss
  wat_eroded.normalize(0,255).save((filename_cut+"_eroded.png").c_str());
564 18 akiss
  wat_eroded.assign();
565 18 akiss
566 18 akiss
  //Segmented inital = background segmentation
567 18 akiss
  CImg<unsigned char> segmented=background;
568 18 akiss
569 18 akiss
  double end1=omp_get_wtime();
570 18 akiss
  double time1=double(end1-begin);
571 18 akiss
  cout<<"initialization with erosion : "<<time1<<endl;
572 18 akiss
  file<<"\ninitialization with erosion : "<<time1<<endl;
573 18 akiss
  cout<<"coucou : "<<endl;
574 18 akiss
  //---------------------------------------------------------Edge detection
575 18 akiss
  //evolve each cell one by one, attract to maximal gradient
576 18 akiss
#pragma omp parallel shared(psi_list,min_list,g,gg,h,lam,mu,alf,beta,epsilon,dt,list)
577 18 akiss
  {
578 18 akiss
#pragma omp for schedule(dynamic)
579 18 akiss
  for(int i=0;i<nbcells;i++)
580 18 akiss
    {
581 18 akiss
      psi_list[i]=lsm_segment2(psi_list[i],g,gg,h,lam,mu,alf,beta,epsilon,dt,min_list[i]);
582 18 akiss
      cout <<"cell evolution "<<list[i]<<endl;
583 18 akiss
    }
584 18 akiss
  }
585 18 akiss
586 18 akiss
  //reconstruct image of edge detection, overlap=not segmented
587 18 akiss
  CImg<unsigned char>free=background;
588 18 akiss
  CImg<unsigned short> edge=reconstruct_overlap(background,psi_list,min_list,nbcells,free,list);
589 18 akiss
  edge.save_inr(edge_detection_name.c_str(),tailleVoxel);
590 18 akiss
  zip="gzip -f "+edge_detection_name;
591 18 akiss
  syst=system(zip.c_str());
592 18 akiss
  edge.crop(0,0,cut,0,edge._width,edge._height,cut,0);
593 18 akiss
  edge.normalize(0,255).save((filename_cut+"_evoEdge.png").c_str());
594 18 akiss
595 18 akiss
596 18 akiss
597 18 akiss
  double end2=omp_get_wtime();
598 18 akiss
  double time2=double(end2-begin);
599 18 akiss
  cout<<"edge detection : "<<time2<<endl;
600 18 akiss
  file<<"edge detection : "<<time2<<endl;
601 18 akiss
602 18 akiss
603 18 akiss
/*
604 18 akiss
  //--------------------------------------------------------Edge evolution
605 18 akiss
  //evolve every cell to fill the gaps
606 18 akiss
  lam=0;
607 18 akiss
  alf=alfabis;
608 18 akiss
  beta=betabis;
609 18 akiss
  bool contour_evolve=true;
610 18 akiss
  float backsegm=free.sum();
611 18 akiss
  int it=0;
612 18 akiss
  int it_stop=0;
613 18 akiss

614 18 akiss
  while((it<timestep_max)and(contour_evolve==true))
615 18 akiss
    {
616 18 akiss
      //each cell evolve one time step
617 18 akiss
#pragma omp parallel shared(psi_list,min_list,g,gg,h,lam,mu,alf,beta,epsilon,dt,free)
618 18 akiss
      {
619 18 akiss
#pragma omp for schedule(dynamic)
620 18 akiss
        for(int i=0;i<nbcells;i++)
621 18 akiss
          {
622 18 akiss
          psi_list[i]=evolution_AK2_contour_interact(psi_list[i],g,gg,h,lam,mu,alf,beta,epsilon,dt,free,min_list[i]);
623 18 akiss
          }
624 18 akiss
      }
625 18 akiss

626 18 akiss
      //reconstruct image of edge detection, overlap=not segmented
627 18 akiss
      edge=reconstruct_overlap(background,psi_list,min_list,nbcells,free,list);
628 18 akiss

629 18 akiss
      //bg evolution
630 18 akiss
      float newsegm=free.sum();
631 18 akiss
      float bg_evolution=newsegm-backsegm;
632 18 akiss
      backsegm=newsegm;
633 18 akiss

634 18 akiss
      //stop criteria
635 18 akiss
      //double stop_criteria=size-newsegm;
636 18 akiss
      if((it>40)and(abs(bg_evolution)<1))
637 18 akiss
        {
638 18 akiss
            contour_evolve=false;
639 18 akiss
        }
640 18 akiss

641 18 akiss
      //save
642 18 akiss
      if(((it%100==0)and(it!=0))or(contour_evolve==false)or(it==timestep_max-1))
643 18 akiss
        {
644 18 akiss
          edge.save_inr(edge_evolve_name.c_str(),tailleVoxel);
645 18 akiss
          zip="gzip -f "+edge_evolve_name;
646 18 akiss
          syst=system(zip.c_str());
647 18 akiss
          CImg<unsigned short> edgeCrop=edge.get_crop(0,0,cut,0,edge._width,edge._height,cut,0);
648 18 akiss
          edgeCrop.normalize(0,255).save((filename_cut+"_final.png").c_str());
649 18 akiss
        }
650 18 akiss

651 18 akiss
      cout<<"it "<<it<<" evo "<<bg_evolution<<endl;
652 18 akiss
      it+=1;
653 18 akiss

654 18 akiss
    }
655 18 akiss
*/
656 18 akiss
657 18 akiss
  double end=omp_get_wtime();
658 18 akiss
  double time=double(end-begin);
659 18 akiss
  cout<<"total time : "<<time<<" (~"<<time/60<<" mn  ~"<<time/60/60<<" h)"<<endl;
660 18 akiss
  cout<<"initialization with erosion : "<<time1<<endl;
661 18 akiss
  cout<<"edge detection : "<<time2<<endl;
662 18 akiss
  file<<"total time : "<<time<<" (~"<<time/60<<" mn  ~"<<time/60/60<<" h)"<<endl;
663 18 akiss
  file<<"initialization with erosion : "<<time1<<endl;
664 18 akiss
  file<<"edge detection : "<<time2<<endl;
665 18 akiss
  file.close();
666 18 akiss
667 18 akiss
  return 0;
668 18 akiss
}