Statistiques
| Révision :

root / src / lsm_cells.cpp @ 27

Historique | Voir | Annoter | Télécharger (17,17 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 24 akiss
 g++ -o lsm_cells lsm_cells.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 24 akiss
 ./lsm_cells 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 27 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 27 akiss
  CImg<float> psi_old=psi;
138 18 akiss
  cimg_forXYZ(psi,x,y,z)
139 18 akiss
    {
140 18 akiss
      if(psi(x,y,z)>=0){backsegm+=1;}
141 18 akiss
    }
142 18 akiss
143 18 akiss
  while((it<timestep_max)and(contour_evolve==true)and(backsegm>30))
144 18 akiss
    {
145 27 akiss
      psi_old=psi;
146 18 akiss
      //evolution
147 18 akiss
      psi=evolution_AK2_contour_cells(psi,g,gg,h,lam,mu,alf,beta,epsilon,dt,min_list);
148 18 akiss
      //new segmentation
149 18 akiss
      int new_backsegm=0;
150 18 akiss
      cimg_forXYZ(psi,x,y,z)
151 18 akiss
        {
152 18 akiss
          if(psi(x,y,z)>=0){new_backsegm+=1;}
153 18 akiss
        }
154 27 akiss
155 18 akiss
      //Stop criteria
156 27 akiss
      // * if the cell would disappear, we stop
157 27 akiss
      if(new_backsegm==0)
158 27 akiss
                        {psi=psi_old;
159 27 akiss
                     contour_evolve=false;}
160 27 akiss
161 18 akiss
      int bg_evolution=abs(new_backsegm-backsegm);
162 18 akiss
163 27 akiss
      // * if the evolution is less then evolution_min 3 consecutive times
164 27 akiss
      //if((it>10) and (bg_evolution<=evolution_min) and (bg_evolution>=evolution_max))
165 27 akiss
      if((it>10) and (bg_evolution<=evolution_min) )
166 18 akiss
        {
167 18 akiss
          it_stop+=1;
168 27 akiss
          if(it_stop>3)
169 27 akiss
            {contour_evolve=false;
170 27 akiss
                cout<<"stopit "<<endl;}
171 18 akiss
        }
172 18 akiss
      else
173 18 akiss
        {
174 18 akiss
          it_stop=0;
175 18 akiss
        }
176 18 akiss
177 18 akiss
178 18 akiss
      it+=1;
179 27 akiss
      backsegm=new_backsegm;
180 27 akiss
      //cout<<"backsegm= "<<backsegm<<endl;
181 18 akiss
    }
182 18 akiss
183 27 akiss
//  cimg_forXYZ(psi,x,y,z)
184 27 akiss
//    {
185 27 akiss
//      if(psi(x,y,z)>=0){psi(x,y,z)=4;}
186 27 akiss
//      else{psi(x,y,z)=-4;}
187 27 akiss
//    }
188 18 akiss
189 18 akiss
  return psi;
190 18 akiss
}
191 18 akiss
192 18 akiss
193 18 akiss
//Reconstruct full segmented image from cell's images
194 18 akiss
//---------------------------------------------------------------
195 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)
196 18 akiss
{
197 18 akiss
  CImg<unsigned short> res=background;
198 18 akiss
  for(int i=0;i<nbcells;i++)
199 18 akiss
    {
200 18 akiss
      cimg_forXYZ(psi_list[i],xb,yb,zb)
201 18 akiss
        {
202 18 akiss
          int x=xb+min_list[i][0];
203 18 akiss
          int y=yb+min_list[i][1];
204 18 akiss
          int z=zb+min_list[i][2];
205 18 akiss
          if(psi_list[i](xb,yb,zb)>=0)
206 18 akiss
            {res(x,y,z)=list[i];}
207 18 akiss
        }
208 18 akiss
    }
209 18 akiss
  return res;
210 18 akiss
}
211 18 akiss
212 18 akiss
//Reconstruct segmented image from cell's images and treat overlap
213 18 akiss
//---------------------------------------------------------------
214 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)
215 18 akiss
{
216 18 akiss
  CImg<unsigned short> res=background;
217 18 akiss
  free=background;
218 18 akiss
  for(int i=0;i<nbcells;i++)
219 18 akiss
    {
220 18 akiss
      cimg_forXYZ(psi_list[i],xb,yb,zb)
221 18 akiss
        {
222 18 akiss
          int x=xb+min_list[i][0];
223 18 akiss
          int y=yb+min_list[i][1];
224 18 akiss
          int z=zb+min_list[i][2];
225 18 akiss
          if(psi_list[i](xb,yb,zb)>=0)
226 18 akiss
            {
227 18 akiss
              res(x,y,z)=list[i];
228 18 akiss
              free(x,y,z)+=1;
229 18 akiss
            }
230 18 akiss
        }
231 18 akiss
    }
232 18 akiss
  cimg_forXYZ(free,x,y,z)
233 18 akiss
    {
234 18 akiss
      if(free(x,y,z)>1)
235 18 akiss
        {
236 18 akiss
          if(background(x,y,z)==1)
237 18 akiss
            {
238 18 akiss
              free(x,y,z)=1;
239 18 akiss
              res(x,y,z)=1;
240 18 akiss
            }
241 18 akiss
          else
242 18 akiss
            {
243 18 akiss
              free(x,y,z)=0;
244 18 akiss
              res(x,y,z)=0;
245 18 akiss
            }
246 18 akiss
        }
247 18 akiss
    }
248 18 akiss
  return res;
249 18 akiss
}
250 18 akiss
251 18 akiss
252 18 akiss
//-----------------------------------------------------------------------------------------------
253 18 akiss
//******************************************  MAIN **********************************************
254 18 akiss
//-----------------------------------------------------------------------------------------------
255 18 akiss
256 18 akiss
int main (int argc, char* argv[])
257 18 akiss
{
258 18 akiss
  double begin=omp_get_wtime();
259 18 akiss
260 18 akiss
  if(argc<5)
261 18 akiss
    {
262 18 akiss
    cout<<"!! wrong number of arguments ("<<argc<<")"<<endl;
263 24 akiss
    cout<<"Usage : lsm_cells img img_wat img_contour erosion [a b smooth lsm_type]"<<endl;
264 18 akiss
    cout<<"----------------- "<<endl;
265 18 akiss
        cout<<"img : grayscale image of cells, (.inr or .inr.gz)"<<endl;
266 18 akiss
        cout<<"img_wat : image of seeds, (.inr or .inr.gz)"<<endl;
267 18 akiss
        cout<<"img_contour : mask, where cells do not evolve, (.inr or .inr.gz)"<<endl;
268 18 akiss
        cout<<"              if 'None', then cells can evolve on the whole image"<<endl;
269 18 akiss
        cout<<"erosion : amount of erosion of seeds for initialisation (uint8) --> -2, 0, 2"<<endl;
270 18 akiss
        cout<<"              if 0, then no erosion or dilation"<<endl;
271 18 akiss
        cout<<"              if negative, then a dilation is performed"<<endl;
272 18 akiss
        cout<<"a : area term (float) --> 0 or 0.5 or 1 (the default is 0.5)"<<endl;
273 18 akiss
        cout<<"              if negative, the object retracts"<<endl;
274 18 akiss
        cout<<"              if positive, the object inflates"<<endl;
275 18 akiss
        cout<<"b : curvature term (float) --> 0 or 1 (the default is 0)"<<endl;
276 24 akiss
        cout<<"gamma : scale parameter (float>0) --> 0.5 or 1 (the default is 1)"<<endl;
277 18 akiss
        cout<<"smooth : gaussian blur to apply to the image (int) --> 0 or 1 (the default is 0)"<<endl;
278 18 akiss
    cout<<"lsm_type : image, gradient or hessien based evolution --> 'i', 'g' or 'h' (the default is g)"<<endl;
279 18 akiss
      return 0;
280 18 akiss
    }
281 18 akiss
282 18 akiss
  //----------------------------------------------read images and check the names
283 18 akiss
  //Original image
284 18 akiss
  CImg<char> description;
285 18 akiss
  float tailleVoxel[3] = {0}; // resolution initialisation
286 18 akiss
  //float tailleVoxel[3] = {0.195177,0.195177,0.195177};
287 18 akiss
288 18 akiss
  bool gzipped=false;
289 18 akiss
290 18 akiss
  string filename_img=argv[1];
291 18 akiss
  CImg<unsigned char> img_prev;
292 18 akiss
  if(filename_img.compare(filename_img.size()-4,4,".inr")==0)
293 18 akiss
    {
294 18 akiss
      img_prev.load(filename_img.c_str());
295 18 akiss
      img_prev.get_load_inr(filename_img.c_str(),tailleVoxel); // reads resolution
296 18 akiss
    }
297 18 akiss
  else if(filename_img.compare(filename_img.size()-7,7,".inr.gz")==0)
298 18 akiss
    {
299 18 akiss
          gzipped = true;
300 18 akiss
      string oldname = filename_img;
301 18 akiss
      filename_img.erase(filename_img.size()-3);
302 18 akiss
      string zip="gunzip -c "+oldname+" > "+filename_img;
303 18 akiss
      if(system(zip.c_str())); // decompress image file
304 18 akiss
      img_prev.load(filename_img.c_str());
305 18 akiss
      img_prev.get_load_inr(filename_img.c_str(),tailleVoxel); // reads resolution
306 18 akiss
      zip="rm "+filename_img;
307 18 akiss
      if(system(zip.c_str())); //removes decompressed image
308 18 akiss
    }
309 18 akiss
  else
310 18 akiss
    {cout<<"!! wrong file extension : "<<filename_img<<endl;
311 18 akiss
      return 0;}
312 18 akiss
  CImg<float> img=img_prev;
313 18 akiss
  img_prev.assign();
314 18 akiss
  cout<<"original image : "<<filename_img<<endl;
315 18 akiss
  cout<<"size : "<<img.size()<<endl;
316 18 akiss
  cout<<"size of original image : "<< img._width<<' '<< img._height <<' '<< img._depth<<' '<< endl;
317 18 akiss
318 18 akiss
  //Watershed
319 18 akiss
  string filename=argv[2];
320 18 akiss
  CImg<unsigned short> wat;
321 18 akiss
  if(filename.compare(filename.size()-4,4,".inr")==0)
322 18 akiss
    {
323 18 akiss
      wat.load(filename.c_str());
324 18 akiss
    }
325 18 akiss
  else if(filename.compare(filename.size()-7,7,".inr.gz")==0)
326 18 akiss
    {
327 18 akiss
      wat.load_gzip_external(filename.c_str());
328 18 akiss
      filename.erase(filename.size()-3);
329 18 akiss
    }
330 18 akiss
  else
331 18 akiss
    {cout<<"!! wrong file extension : "<<filename<<endl;
332 18 akiss
      return 0;}
333 18 akiss
  cout<<"watershed image : "<<filename<<endl;
334 18 akiss
cout<<"size : "<<wat.size()<<endl;
335 18 akiss
  cout<<"size of original image : "<< wat._width<<' '<< wat._height <<' '<< wat._depth<<' '<< endl;
336 18 akiss
337 18 akiss
  //Background
338 18 akiss
  string filename_bg=argv[3];
339 18 akiss
  CImg<unsigned char> background(img._width, img._height, img._depth,1,0);
340 18 akiss
   if(filename_bg.compare("None")==0)
341 18 akiss
    {
342 18 akiss
       cout<<"!! no background entered !!"<<endl;
343 18 akiss
    }
344 18 akiss
    else if(filename_bg.compare(filename_bg.size()-4,4,".inr")==0)
345 18 akiss
    {
346 18 akiss
      background.load(filename_bg.c_str());
347 18 akiss
    }
348 18 akiss
  else if(filename_bg.compare(filename_bg.size()-7,7,".inr.gz")==0)
349 18 akiss
    {
350 18 akiss
      background.load_gzip_external(filename_bg.c_str());
351 18 akiss
      filename_bg.erase(filename_bg.size()-3);
352 18 akiss
    }
353 18 akiss
  else
354 18 akiss
    {cout<<"!! wrong file extension : "<<filename_bg<<endl;
355 18 akiss
      return 0;}
356 18 akiss
  cout<<"background image : "<<filename_bg<<endl;
357 18 akiss
358 18 akiss
  if((wat.size()!=img.size())or(background.size()!=img.size()))
359 18 akiss
    {
360 18 akiss
      cout<<"!! images are not the same size"<<endl;
361 18 akiss
      return 0;
362 18 akiss
    }
363 18 akiss
  else cout<<"size : "<<img.size()<<endl;
364 18 akiss
365 18 akiss
366 18 akiss
  //---------------------------------------------------------------Parameters
367 18 akiss
  //model parameters
368 18 akiss
369 18 akiss
  int c0=-4;
370 18 akiss
  int erosion=atoi(argv[4]);
371 18 akiss
  int marge=10; //10
372 18 akiss
373 18 akiss
  int lam=10;
374 18 akiss
  float alf=0.5;//1
375 18 akiss
  float beta=0;
376 18 akiss
  float gamma=1;
377 18 akiss
  float smooth=0;
378 18 akiss
  string lsm_type="g";
379 18 akiss
380 18 akiss
  string ar=argv[4];
381 18 akiss
  string insert="_cellLSM-d"+ar;
382 18 akiss
  if(argc>5)
383 18 akiss
    {
384 18 akiss
    alf=atof(argv[5]);
385 18 akiss
    ar=argv[5];
386 18 akiss
    insert=insert+"-a"+ar;
387 18 akiss
    }
388 18 akiss
  if(argc>6)
389 18 akiss
    {
390 18 akiss
    beta=atof(argv[6]);
391 18 akiss
    ar=argv[6];
392 18 akiss
    insert+="-b"+ar;
393 18 akiss
    }
394 18 akiss
  if(argc>7)
395 18 akiss
    {
396 18 akiss
    gamma=atof(argv[7]);
397 18 akiss
    ar=argv[7];
398 18 akiss
    insert+="-g"+ar;
399 18 akiss
        }
400 18 akiss
  if(argc>8)
401 18 akiss
    {
402 18 akiss
    smooth=atof(argv[8]);
403 18 akiss
    ar=argv[8];
404 18 akiss
    insert+="-s"+ar;
405 18 akiss
        }
406 18 akiss
  if(argc>9)
407 18 akiss
    {
408 18 akiss
        lsm_type=argv[9];
409 18 akiss
        ar=argv[9];
410 18 akiss
        insert+="-"+ar;
411 18 akiss
        }
412 18 akiss
413 18 akiss
414 18 akiss
415 18 akiss
  //numerical parameters
416 18 akiss
  float epsilon=0.5;
417 18 akiss
  int dt=1;   //it was 50, changed into 1 the 2015/10/16
418 18 akiss
  float mu=0.1/dt;
419 18 akiss
  int timestep_max=10000; // it was 1000, changed into 10000 the 2015/10/16
420 18 akiss
421 18 akiss
422 18 akiss
  //------------------------------------Names and directories
423 18 akiss
  //new name with arguments
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 24 akiss
514 18 akiss
515 18 akiss
  CImg<float> gout=g;
516 18 akiss
  gout.crop(0,0,cut,0,g._width,g._height,cut,0);
517 18 akiss
  gout.normalize(0,255).save((filename_cut+"_edge_indicator.png").c_str());
518 18 akiss
  gout.assign();
519 18 akiss
520 18 akiss
  //initialize psi for every cell
521 18 akiss
  int maxcells=wat.max()+1; //indice maximum
522 18 akiss
  vector<int> list=index(wat,maxcells);
523 18 akiss
  int nbcells=list.size();
524 18 akiss
  cout<<"number of cells : "<<nbcells<<endl;
525 18 akiss
  file<<"number of cells : "<<nbcells<<endl;
526 18 akiss
  vector<CImg<float> > psi_list(nbcells);
527 18 akiss
  vector<vector<int> > min_list(nbcells,vector<int>(3,0));
528 18 akiss
  vector<vector<int> > max_list(nbcells,vector<int>(3,0));
529 18 akiss
530 18 akiss
#pragma omp parallel shared(wat,marge,erosion,c0,psi_list,min_list,list)
531 18 akiss
  {
532 18 akiss
  int xmin=0;
533 18 akiss
  int ymin=0;
534 18 akiss
  int zmin=0;
535 18 akiss
#pragma omp for schedule(dynamic)
536 18 akiss
  for(int i=0;i<nbcells;i++)
537 18 akiss
    {
538 18 akiss
      int ind=list[i];
539 18 akiss
      psi_list[i]=box_cell(wat,marge,erosion,c0,ind,xmin,ymin,zmin);
540 18 akiss
      min_list[i][0]=xmin;
541 18 akiss
      min_list[i][1]=ymin;
542 18 akiss
      min_list[i][2]=zmin;
543 18 akiss
      cout <<"cell "<<ind<<endl;
544 18 akiss
    }
545 18 akiss
  }
546 18 akiss
  wat.assign();
547 18 akiss
548 18 akiss
  //reconstruct image of eroded cell
549 18 akiss
  CImg<unsigned short> wat_eroded=reconstruct(background,psi_list,min_list,nbcells,list);
550 18 akiss
  wat_eroded.save_inr(wat_eroded_name.c_str(),tailleVoxel);
551 24 akiss
  string zip="gzip -f "+wat_eroded_name;
552 18 akiss
  syst=system(zip.c_str());
553 18 akiss
  wat_eroded.crop(0,0,cut,0,wat_eroded._width,wat_eroded._height,cut,0);
554 18 akiss
  wat_eroded.normalize(0,255).save((filename_cut+"_eroded.png").c_str());
555 18 akiss
  wat_eroded.assign();
556 18 akiss
557 18 akiss
  //Segmented inital = background segmentation
558 18 akiss
  CImg<unsigned char> segmented=background;
559 18 akiss
560 18 akiss
  double end1=omp_get_wtime();
561 18 akiss
  double time1=double(end1-begin);
562 18 akiss
  cout<<"initialization with erosion : "<<time1<<endl;
563 18 akiss
  file<<"\ninitialization with erosion : "<<time1<<endl;
564 27 akiss
  cout<<"Evolving cells..... "<<endl;
565 18 akiss
  //---------------------------------------------------------Edge detection
566 18 akiss
  //evolve each cell one by one, attract to maximal gradient
567 18 akiss
#pragma omp parallel shared(psi_list,min_list,g,gg,h,lam,mu,alf,beta,epsilon,dt,list)
568 18 akiss
  {
569 18 akiss
#pragma omp for schedule(dynamic)
570 18 akiss
  for(int i=0;i<nbcells;i++)
571 18 akiss
    {
572 18 akiss
      psi_list[i]=lsm_segment2(psi_list[i],g,gg,h,lam,mu,alf,beta,epsilon,dt,min_list[i]);
573 18 akiss
      cout <<"cell evolution "<<list[i]<<endl;
574 18 akiss
    }
575 18 akiss
  }
576 18 akiss
577 18 akiss
  //reconstruct image of edge detection, overlap=not segmented
578 18 akiss
  CImg<unsigned char>free=background;
579 18 akiss
  CImg<unsigned short> edge=reconstruct_overlap(background,psi_list,min_list,nbcells,free,list);
580 18 akiss
  edge.save_inr(edge_detection_name.c_str(),tailleVoxel);
581 18 akiss
  zip="gzip -f "+edge_detection_name;
582 18 akiss
  syst=system(zip.c_str());
583 18 akiss
  edge.crop(0,0,cut,0,edge._width,edge._height,cut,0);
584 18 akiss
  edge.normalize(0,255).save((filename_cut+"_evoEdge.png").c_str());
585 18 akiss
586 18 akiss
587 18 akiss
588 18 akiss
  double end2=omp_get_wtime();
589 18 akiss
  double time2=double(end2-begin);
590 18 akiss
  cout<<"edge detection : "<<time2<<endl;
591 18 akiss
  file<<"edge detection : "<<time2<<endl;
592 18 akiss
593 18 akiss
594 18 akiss
  double end=omp_get_wtime();
595 18 akiss
  double time=double(end-begin);
596 18 akiss
  cout<<"total time : "<<time<<" (~"<<time/60<<" mn  ~"<<time/60/60<<" h)"<<endl;
597 18 akiss
  cout<<"initialization with erosion : "<<time1<<endl;
598 18 akiss
  cout<<"edge detection : "<<time2<<endl;
599 18 akiss
  file<<"total time : "<<time<<" (~"<<time/60<<" mn  ~"<<time/60/60<<" h)"<<endl;
600 18 akiss
  file<<"initialization with erosion : "<<time1<<endl;
601 18 akiss
  file<<"edge detection : "<<time2<<endl;
602 18 akiss
  file.close();
603 18 akiss
604 18 akiss
  return 0;
605 18 akiss
}