Statistiques
| Révision :

root / src / lsm_cells.cpp @ 30

Historique | Voir | Annoter | Télécharger (16,08 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) )
165 18 akiss
        {
166 18 akiss
          it_stop+=1;
167 27 akiss
          if(it_stop>3)
168 28 akiss
            {contour_evolve=false;}
169 18 akiss
        }
170 18 akiss
      else
171 18 akiss
        {
172 18 akiss
          it_stop=0;
173 18 akiss
        }
174 18 akiss
175 18 akiss
176 18 akiss
      it+=1;
177 27 akiss
      backsegm=new_backsegm;
178 18 akiss
    }
179 18 akiss
  return psi;
180 18 akiss
}
181 18 akiss
182 18 akiss
183 18 akiss
//Reconstruct full segmented image from cell's images
184 18 akiss
//---------------------------------------------------------------
185 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)
186 18 akiss
{
187 18 akiss
  CImg<unsigned short> res=background;
188 18 akiss
  for(int i=0;i<nbcells;i++)
189 18 akiss
    {
190 18 akiss
      cimg_forXYZ(psi_list[i],xb,yb,zb)
191 18 akiss
        {
192 18 akiss
          int x=xb+min_list[i][0];
193 18 akiss
          int y=yb+min_list[i][1];
194 18 akiss
          int z=zb+min_list[i][2];
195 18 akiss
          if(psi_list[i](xb,yb,zb)>=0)
196 18 akiss
            {res(x,y,z)=list[i];}
197 18 akiss
        }
198 18 akiss
    }
199 18 akiss
  return res;
200 18 akiss
}
201 18 akiss
202 18 akiss
//Reconstruct segmented image from cell's images and treat overlap
203 18 akiss
//---------------------------------------------------------------
204 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)
205 18 akiss
{
206 18 akiss
  CImg<unsigned short> res=background;
207 18 akiss
  free=background;
208 18 akiss
  for(int i=0;i<nbcells;i++)
209 18 akiss
    {
210 18 akiss
      cimg_forXYZ(psi_list[i],xb,yb,zb)
211 18 akiss
        {
212 18 akiss
          int x=xb+min_list[i][0];
213 18 akiss
          int y=yb+min_list[i][1];
214 18 akiss
          int z=zb+min_list[i][2];
215 18 akiss
          if(psi_list[i](xb,yb,zb)>=0)
216 18 akiss
            {
217 18 akiss
              res(x,y,z)=list[i];
218 18 akiss
              free(x,y,z)+=1;
219 18 akiss
            }
220 18 akiss
        }
221 18 akiss
    }
222 18 akiss
  cimg_forXYZ(free,x,y,z)
223 18 akiss
    {
224 18 akiss
      if(free(x,y,z)>1)
225 18 akiss
        {
226 18 akiss
          if(background(x,y,z)==1)
227 18 akiss
            {
228 18 akiss
              free(x,y,z)=1;
229 18 akiss
              res(x,y,z)=1;
230 18 akiss
            }
231 18 akiss
          else
232 18 akiss
            {
233 18 akiss
              free(x,y,z)=0;
234 18 akiss
              res(x,y,z)=0;
235 18 akiss
            }
236 18 akiss
        }
237 18 akiss
    }
238 18 akiss
  return res;
239 18 akiss
}
240 18 akiss
241 18 akiss
242 18 akiss
//-----------------------------------------------------------------------------------------------
243 18 akiss
//******************************************  MAIN **********************************************
244 18 akiss
//-----------------------------------------------------------------------------------------------
245 18 akiss
246 18 akiss
int main (int argc, char* argv[])
247 18 akiss
{
248 18 akiss
  double begin=omp_get_wtime();
249 18 akiss
250 18 akiss
  if(argc<5)
251 18 akiss
    {
252 18 akiss
    cout<<"!! wrong number of arguments ("<<argc<<")"<<endl;
253 24 akiss
    cout<<"Usage : lsm_cells img img_wat img_contour erosion [a b smooth lsm_type]"<<endl;
254 18 akiss
    cout<<"----------------- "<<endl;
255 18 akiss
        cout<<"img : grayscale image of cells, (.inr or .inr.gz)"<<endl;
256 18 akiss
        cout<<"img_wat : image of seeds, (.inr or .inr.gz)"<<endl;
257 18 akiss
        cout<<"img_contour : mask, where cells do not evolve, (.inr or .inr.gz)"<<endl;
258 18 akiss
        cout<<"              if 'None', then cells can evolve on the whole image"<<endl;
259 18 akiss
        cout<<"erosion : amount of erosion of seeds for initialisation (uint8) --> -2, 0, 2"<<endl;
260 18 akiss
        cout<<"              if 0, then no erosion or dilation"<<endl;
261 18 akiss
        cout<<"              if negative, then a dilation is performed"<<endl;
262 18 akiss
        cout<<"a : area term (float) --> 0 or 0.5 or 1 (the default is 0.5)"<<endl;
263 18 akiss
        cout<<"              if negative, the object retracts"<<endl;
264 18 akiss
        cout<<"              if positive, the object inflates"<<endl;
265 18 akiss
        cout<<"b : curvature term (float) --> 0 or 1 (the default is 0)"<<endl;
266 24 akiss
        cout<<"gamma : scale parameter (float>0) --> 0.5 or 1 (the default is 1)"<<endl;
267 18 akiss
        cout<<"smooth : gaussian blur to apply to the image (int) --> 0 or 1 (the default is 0)"<<endl;
268 18 akiss
    cout<<"lsm_type : image, gradient or hessien based evolution --> 'i', 'g' or 'h' (the default is g)"<<endl;
269 18 akiss
      return 0;
270 18 akiss
    }
271 18 akiss
272 18 akiss
  //----------------------------------------------read images and check the names
273 18 akiss
  //Original image
274 18 akiss
  CImg<char> description;
275 18 akiss
  float tailleVoxel[3] = {0}; // resolution initialisation
276 18 akiss
277 18 akiss
  bool gzipped=false;
278 18 akiss
279 18 akiss
  string filename_img=argv[1];
280 18 akiss
  CImg<unsigned char> img_prev;
281 18 akiss
  if(filename_img.compare(filename_img.size()-4,4,".inr")==0)
282 18 akiss
    {
283 18 akiss
      img_prev.load(filename_img.c_str());
284 18 akiss
      img_prev.get_load_inr(filename_img.c_str(),tailleVoxel); // reads resolution
285 18 akiss
    }
286 18 akiss
  else if(filename_img.compare(filename_img.size()-7,7,".inr.gz")==0)
287 18 akiss
    {
288 18 akiss
          gzipped = true;
289 18 akiss
      string oldname = filename_img;
290 18 akiss
      filename_img.erase(filename_img.size()-3);
291 18 akiss
      string zip="gunzip -c "+oldname+" > "+filename_img;
292 18 akiss
      if(system(zip.c_str())); // decompress image file
293 18 akiss
      img_prev.load(filename_img.c_str());
294 18 akiss
      img_prev.get_load_inr(filename_img.c_str(),tailleVoxel); // reads resolution
295 18 akiss
      zip="rm "+filename_img;
296 18 akiss
      if(system(zip.c_str())); //removes decompressed image
297 18 akiss
    }
298 18 akiss
  else
299 18 akiss
    {cout<<"!! wrong file extension : "<<filename_img<<endl;
300 18 akiss
      return 0;}
301 18 akiss
  CImg<float> img=img_prev;
302 18 akiss
  img_prev.assign();
303 18 akiss
  cout<<"original image : "<<filename_img<<endl;
304 18 akiss
  cout<<"size : "<<img.size()<<endl;
305 18 akiss
  cout<<"size of original image : "<< img._width<<' '<< img._height <<' '<< img._depth<<' '<< endl;
306 18 akiss
307 18 akiss
  //Watershed
308 18 akiss
  string filename=argv[2];
309 18 akiss
  CImg<unsigned short> wat;
310 18 akiss
  if(filename.compare(filename.size()-4,4,".inr")==0)
311 18 akiss
    {
312 18 akiss
      wat.load(filename.c_str());
313 18 akiss
    }
314 18 akiss
  else if(filename.compare(filename.size()-7,7,".inr.gz")==0)
315 18 akiss
    {
316 18 akiss
      wat.load_gzip_external(filename.c_str());
317 18 akiss
      filename.erase(filename.size()-3);
318 18 akiss
    }
319 18 akiss
  else
320 18 akiss
    {cout<<"!! wrong file extension : "<<filename<<endl;
321 18 akiss
      return 0;}
322 18 akiss
  cout<<"watershed image : "<<filename<<endl;
323 18 akiss
cout<<"size : "<<wat.size()<<endl;
324 18 akiss
  cout<<"size of original image : "<< wat._width<<' '<< wat._height <<' '<< wat._depth<<' '<< endl;
325 18 akiss
326 18 akiss
  //Background
327 18 akiss
  string filename_bg=argv[3];
328 18 akiss
  CImg<unsigned char> background(img._width, img._height, img._depth,1,0);
329 18 akiss
   if(filename_bg.compare("None")==0)
330 18 akiss
    {
331 18 akiss
       cout<<"!! no background entered !!"<<endl;
332 18 akiss
    }
333 18 akiss
    else if(filename_bg.compare(filename_bg.size()-4,4,".inr")==0)
334 18 akiss
    {
335 18 akiss
      background.load(filename_bg.c_str());
336 18 akiss
    }
337 18 akiss
  else if(filename_bg.compare(filename_bg.size()-7,7,".inr.gz")==0)
338 18 akiss
    {
339 18 akiss
      background.load_gzip_external(filename_bg.c_str());
340 18 akiss
      filename_bg.erase(filename_bg.size()-3);
341 18 akiss
    }
342 18 akiss
  else
343 18 akiss
    {cout<<"!! wrong file extension : "<<filename_bg<<endl;
344 18 akiss
      return 0;}
345 18 akiss
  cout<<"background image : "<<filename_bg<<endl;
346 18 akiss
347 18 akiss
  if((wat.size()!=img.size())or(background.size()!=img.size()))
348 18 akiss
    {
349 18 akiss
      cout<<"!! images are not the same size"<<endl;
350 18 akiss
      return 0;
351 18 akiss
    }
352 18 akiss
  else cout<<"size : "<<img.size()<<endl;
353 18 akiss
354 18 akiss
355 18 akiss
  //---------------------------------------------------------------Parameters
356 18 akiss
  //model parameters
357 18 akiss
358 18 akiss
  int c0=-4;
359 18 akiss
  int erosion=atoi(argv[4]);
360 18 akiss
  int marge=10; //10
361 18 akiss
362 18 akiss
  int lam=10;
363 18 akiss
  float alf=0.5;//1
364 18 akiss
  float beta=0;
365 18 akiss
  float gamma=1;
366 18 akiss
  float smooth=0;
367 18 akiss
  string lsm_type="g";
368 18 akiss
369 18 akiss
  string ar=argv[4];
370 18 akiss
  string insert="_cellLSM-d"+ar;
371 18 akiss
  if(argc>5)
372 18 akiss
    {
373 18 akiss
    alf=atof(argv[5]);
374 18 akiss
    ar=argv[5];
375 18 akiss
    insert=insert+"-a"+ar;
376 18 akiss
    }
377 18 akiss
  if(argc>6)
378 18 akiss
    {
379 18 akiss
    beta=atof(argv[6]);
380 18 akiss
    ar=argv[6];
381 18 akiss
    insert+="-b"+ar;
382 18 akiss
    }
383 18 akiss
  if(argc>7)
384 18 akiss
    {
385 18 akiss
    gamma=atof(argv[7]);
386 18 akiss
    ar=argv[7];
387 18 akiss
    insert+="-g"+ar;
388 18 akiss
        }
389 18 akiss
  if(argc>8)
390 18 akiss
    {
391 18 akiss
    smooth=atof(argv[8]);
392 18 akiss
    ar=argv[8];
393 18 akiss
    insert+="-s"+ar;
394 18 akiss
        }
395 18 akiss
  if(argc>9)
396 18 akiss
    {
397 18 akiss
        lsm_type=argv[9];
398 18 akiss
        ar=argv[9];
399 18 akiss
        insert+="-"+ar;
400 18 akiss
        }
401 18 akiss
402 18 akiss
403 18 akiss
404 18 akiss
  //numerical parameters
405 18 akiss
  float epsilon=0.5;
406 18 akiss
  int dt=1;   //it was 50, changed into 1 the 2015/10/16
407 18 akiss
  float mu=0.1/dt;
408 18 akiss
  int timestep_max=10000; // it was 1000, changed into 10000 the 2015/10/16
409 18 akiss
410 18 akiss
411 18 akiss
  //------------------------------------Names and directories
412 18 akiss
  //new name with arguments
413 18 akiss
  filename.insert(filename.size()-4,insert);
414 18 akiss
415 18 akiss
  //create directories and update names
416 18 akiss
  size_t test=filename.rfind("/");
417 18 akiss
  if(test!=filename.npos)
418 18 akiss
    {filename.erase(0,test+1);}
419 18 akiss
  string outputdir=filename;
420 18 akiss
  outputdir.erase(filename.size()-4);
421 18 akiss
  string mkdir="mkdir -p "+outputdir;
422 28 akiss
  if(system(mkdir.c_str()));
423 18 akiss
424 28 akiss
  string filename_txt=outputdir+"/"+filename;
425 28 akiss
  filename_txt.erase(filename_txt.size()-4);
426 18 akiss
  filename=outputdir+"/"+filename;
427 18 akiss
  string wat_eroded_name=filename;
428 18 akiss
  wat_eroded_name.insert(filename.size()-4,"_eroded");
429 18 akiss
  string edge_detection_name=filename;
430 18 akiss
  edge_detection_name.insert(filename.size()-4,"_evoEdge");
431 18 akiss
  string edge_evolve_name=filename;
432 18 akiss
  edge_evolve_name.insert(filename.size()-4,"_final");
433 18 akiss
434 18 akiss
  //txt files
435 18 akiss
  ofstream file;
436 28 akiss
  string txt_name=filename_txt+".txt";
437 18 akiss
  file.open(txt_name.c_str());
438 18 akiss
  file<<argv[0]<<endl;
439 18 akiss
  time_t t;
440 18 akiss
  struct tm * timeinfo;
441 18 akiss
  time(&t);
442 18 akiss
  timeinfo=localtime(&t);
443 18 akiss
  file<<asctime(timeinfo);
444 18 akiss
  file<<"image : "<<argv[1]<<endl;
445 18 akiss
  file<<"watershed : "<<argv[2]<<endl;
446 18 akiss
  file<<"background : "<<argv[3]<<endl;
447 18 akiss
  file<<"_________________________________"<<endl;
448 18 akiss
  file<<"Parameters"<<endl;
449 18 akiss
  file<<"lsm_type : "<<lsm_type<<endl;
450 18 akiss
  file<<"lambda : "<<lam<<endl;
451 18 akiss
  file<<"alpha : "<<alf<<endl;
452 18 akiss
  file<<"beta : "<<beta<<endl;
453 18 akiss
  file<<"gamma :"<<gamma<<endl;
454 18 akiss
  //file<<"alphabis : "<<alfabis<<endl;
455 18 akiss
  //file<<"betabis : "<<betabis<<endl;
456 18 akiss
  file<<"erosion : "<<erosion<<endl;
457 18 akiss
  file<<"marge : "<<marge<<endl;
458 18 akiss
  file<<"epsilon : "<<epsilon <<endl;
459 18 akiss
  file<<"mu : "<<mu <<endl;
460 18 akiss
  file<<"dt : "<<dt <<endl;
461 18 akiss
  file<<"timestep_max : "<<timestep_max <<endl;
462 18 akiss
463 18 akiss
  //-----------------------------------------Image Pre-processing
464 18 akiss
465 18 akiss
  //smooth image
466 18 akiss
  file<<"smooth : "<<smooth<<endl;
467 18 akiss
  if (smooth>0)
468 18 akiss
  {
469 18 akiss
  img.blur(smooth);
470 18 akiss
  }
471 18 akiss
472 18 akiss
  //-------------------------------------Initialization with erosion
473 18 akiss
  //compute fixed terms
474 18 akiss
  CImg<float> g;
475 18 akiss
  if(lsm_type.compare("g")==0)
476 18 akiss
    {
477 18 akiss
  g=edge_indicator1(img, gamma);
478 18 akiss
    }
479 18 akiss
  else if (lsm_type.compare("h")==0)
480 18 akiss
   {
481 18 akiss
  g=edge_indicator2s(img, gamma);
482 18 akiss
   }
483 18 akiss
  else if (lsm_type.compare("i")==0)
484 18 akiss
   {
485 18 akiss
  g=edge_indicator3(img, gamma);
486 18 akiss
   }
487 18 akiss
  else
488 18 akiss
  cout<<"Wrong lsm type given :'"<<lsm_type<<"'('g' for gradient-based, 'h' for Hessien-based) "<<endl;
489 18 akiss
490 18 akiss
  CImgList<float> gg=gradient(g);
491 18 akiss
  CImg<float> h=g;
492 18 akiss
  img.assign();
493 18 akiss
494 18 akiss
  //initialize psi for every cell
495 18 akiss
  int maxcells=wat.max()+1; //indice maximum
496 18 akiss
  vector<int> list=index(wat,maxcells);
497 18 akiss
  int nbcells=list.size();
498 18 akiss
  cout<<"number of cells : "<<nbcells<<endl;
499 18 akiss
  file<<"number of cells : "<<nbcells<<endl;
500 18 akiss
  vector<CImg<float> > psi_list(nbcells);
501 18 akiss
  vector<vector<int> > min_list(nbcells,vector<int>(3,0));
502 18 akiss
  vector<vector<int> > max_list(nbcells,vector<int>(3,0));
503 18 akiss
504 18 akiss
#pragma omp parallel shared(wat,marge,erosion,c0,psi_list,min_list,list)
505 18 akiss
  {
506 18 akiss
  int xmin=0;
507 18 akiss
  int ymin=0;
508 18 akiss
  int zmin=0;
509 18 akiss
#pragma omp for schedule(dynamic)
510 18 akiss
  for(int i=0;i<nbcells;i++)
511 18 akiss
    {
512 18 akiss
      int ind=list[i];
513 18 akiss
      psi_list[i]=box_cell(wat,marge,erosion,c0,ind,xmin,ymin,zmin);
514 18 akiss
      min_list[i][0]=xmin;
515 18 akiss
      min_list[i][1]=ymin;
516 18 akiss
      min_list[i][2]=zmin;
517 28 akiss
      cout <<"cell "<<ind<<" initialised."<<endl;
518 18 akiss
    }
519 18 akiss
  }
520 18 akiss
  wat.assign();
521 18 akiss
522 28 akiss
  //reconstruct image of eroded cells
523 18 akiss
  CImg<unsigned short> wat_eroded=reconstruct(background,psi_list,min_list,nbcells,list);
524 28 akiss
  cout <<"saving file "<<wat_eroded_name<<"..."<<endl;
525 18 akiss
  wat_eroded.save_inr(wat_eroded_name.c_str(),tailleVoxel);
526 24 akiss
  string zip="gzip -f "+wat_eroded_name;
527 28 akiss
  if(system(zip.c_str()));
528 28 akiss
  cout <<"Eroded watershed segmentation saved in file:"<<wat_eroded_name<<endl;
529 18 akiss
530 18 akiss
  //Segmented inital = background segmentation
531 18 akiss
  CImg<unsigned char> segmented=background;
532 18 akiss
533 18 akiss
  double end1=omp_get_wtime();
534 18 akiss
  double time1=double(end1-begin);
535 27 akiss
  cout<<"Evolving cells..... "<<endl;
536 28 akiss
537 18 akiss
  //---------------------------------------------------------Edge detection
538 18 akiss
  //evolve each cell one by one, attract to maximal gradient
539 18 akiss
#pragma omp parallel shared(psi_list,min_list,g,gg,h,lam,mu,alf,beta,epsilon,dt,list)
540 18 akiss
  {
541 18 akiss
#pragma omp for schedule(dynamic)
542 18 akiss
  for(int i=0;i<nbcells;i++)
543 18 akiss
    {
544 18 akiss
      psi_list[i]=lsm_segment2(psi_list[i],g,gg,h,lam,mu,alf,beta,epsilon,dt,min_list[i]);
545 28 akiss
      cout <<"cell "<<list[i]<<" evolved."<<endl;
546 18 akiss
    }
547 18 akiss
  }
548 18 akiss
549 18 akiss
  //reconstruct image of edge detection, overlap=not segmented
550 18 akiss
  CImg<unsigned char>free=background;
551 18 akiss
  CImg<unsigned short> edge=reconstruct_overlap(background,psi_list,min_list,nbcells,free,list);
552 18 akiss
  edge.save_inr(edge_detection_name.c_str(),tailleVoxel);
553 18 akiss
  zip="gzip -f "+edge_detection_name;
554 28 akiss
  if(system(zip.c_str()));
555 18 akiss
556 28 akiss
// time measurements
557 18 akiss
  double end2=omp_get_wtime();
558 18 akiss
  double time2=double(end2-begin);
559 28 akiss
560 18 akiss
  double end=omp_get_wtime();
561 18 akiss
  double time=double(end-begin);
562 28 akiss
  cout<<"total time : "<<time<<"s"<<" (~"<<time/60<<" mn  ~"<<time/60/60<<" h)"<<endl;
563 28 akiss
  cout<<"-initialization with erosion : "<<time1<<"s"<<endl;
564 28 akiss
  cout<<"-edge detection : "<<time2<<"s"<<endl;
565 28 akiss
  file<<"total time : "<<time<<"s"<<" (~"<<time/60<<" mn  ~"<<time/60/60<<" h)"<<endl;
566 28 akiss
  file<<"-initialization with erosion : "<<time1<<"s"<<endl;
567 28 akiss
  file<<"-edge detection : "<<time2<<"s"<<endl;
568 18 akiss
  file.close();
569 18 akiss
570 18 akiss
  return 0;
571 18 akiss
}