Statistiques
| Révision :

root / bin / lsm_detect_contour_tiffonly.cpp @ 18

Historique | Voir | Annoter | Télécharger (7,33 ko)

1
/*
2
Level-set Method to detect contour (exterior shape of a tissue)
3
Sequential standard version
4
* background : 0; object : 255
5

6
To compile
7
 g++ -o lsm_detect_contour-mgx-tiffonly.exe lsm_detect_contour-mgx-tiffonly.cpp -O2 -L/usr/X11R6/lib -lm -lpthread -lX11 -l:libtiff.so.4
8
 Needs CImg.h and lsm_lib.h
9
 
10
To execute
11
 ./lsm_detect_contour-mgx.exe img t_up t_down b smooth
12

13
 img : grayscale image of cells, (.tif)
14
 t_up,t_down : linear threshold value (int)
15
 b : curvature term (float)
16
 smooth : amount of gaussian blur to apply to the image
17
 
18
 * implemented by Typhaine Moreau during her M1 internship (April-July 2014)
19
 * supervisors Annamaria Kiss (RDP) and Cerasela Calugaru (CBP)
20
 * ENS-Lyon
21
 * 
22
 * Reference : Li et al. Distance Regularized Level Set Evolution and Its Application to Image Segmentation, 
23
 * IEEE Transactions on Image Processing, Vol.19. No. 12, December 2010
24
 
25
*/
26

    
27
#include <iostream>
28
#include <math.h>
29
#include <sstream>
30
#include <vector>
31
#include <fstream>
32

    
33
#include "lsm_lib.h"
34

    
35
using namespace cimg_library;
36
using namespace std;
37

    
38
//------------------------------------------------------------------------------
39
//Main
40
//------------------------------------------------------------------------------
41
int main (int argc, char* argv[])
42
{
43
  clock_t begin=clock();
44

    
45
  if(argc!=6)
46
    {
47
      cout<<"!! wrong number of arguments"<<endl;
48
      cout<<"how to execute : ./lsm_detect_contour.exe img t_up t_down b smooth"<<endl;
49
      return 0;
50
    }
51

    
52
  //Open image with name in argument
53
  //image is convert to unsigned char (0 to 255) and then to float
54
  string name=argv[1];
55
  //CImg<unsigned char> img_prev;
56
  CImg<> img1;
57
  CImg<char> description;
58
  float tailleVoxel[3] = {0}; // resolution initialisation
59
          cout<<"file to read : "<<name<<endl;
60
          img1.load_tiff(name.c_str(),0,~0U,1,tailleVoxel,&description);
61
  CImg<float> img=img1;
62
  img1.assign();
63
  cout<<"image : "<<name<<endl;
64
  cout<<"image depth : "<<img.depth()<<endl;
65
  if(img.depth()<=1)
66
    {
67
      cout<<"This is not a 3D image"<<endl;
68
      return  0;
69
    }
70
     
71
    
72
  string filename = name;
73

    
74
  //--------------------------------------------Parameters
75
  //model parameters
76
  int lam=10;
77
  int alf=0;
78
  int beta=atoi(argv[4]);
79

    
80
  //numerical parameters
81
  float epsilon=1.5;
82
  int dt=100;
83
  float mu=0.1/dt;
84
  int timestep_max=2000;
85

    
86
  //linear threshold
87
  int t_up=atoi(argv[2]);
88
  int t_down=atoi(argv[3]);
89

    
90
  float smooth=atof(argv[5]);
91

    
92
  
93

    
94
  //-------------------------------------------Names and directories
95
  //new name with arguments
96
  string ar2=argv[2];
97
  string ar3=argv[3];
98
  string ar4=argv[4];
99
  string ar5=argv[5];
100
  string insert="_LSMcont"+ar2+"-"+ar3+"b"+ar4+"s"+ar5;
101
  filename.insert(filename.size()-4,insert);
102

    
103
  //create directories and update names
104
  size_t test=filename.rfind("/");
105
  if(test!=filename.npos)
106
    {filename.erase(0,test+1);}
107
  string outputdir=filename;
108
  outputdir.erase(filename.size()-4);
109
  string mkdir="mkdir -p "+outputdir;
110
  if(system(mkdir.c_str())); 
111
  mkdir="mkdir -p "+outputdir+"/evolution";
112
  if(system(mkdir.c_str()));
113

    
114
  string filename_cut=outputdir+"/evolution/"+filename;
115
  filename_cut.erase(filename_cut.size()-4);
116
  filename=outputdir+"/"+filename;
117
  string result_name=filename;
118

    
119
  //txt files 
120
  ofstream file;
121
  string txt_name=filename_cut+".txt";
122
  file.open(txt_name.c_str());
123
  file<<argv[0]<<endl;
124
  time_t t;
125
  struct tm * timeinfo;
126
  time(&t);
127
  timeinfo=localtime(&t);
128
  file<<asctime(timeinfo);
129
  file<<"image : "<<argv[1]<<endl;
130
  file<<"_________________________________"<<endl;
131
  file<<"Parameters"<<endl;
132
  file<<"lambda : "<<lam<<endl;
133
  file<<"alpha : "<<alf<<endl;
134
  file<<"epsilon : "<<epsilon<<endl;
135
  file<<"dt : "<<dt<<endl;
136
  file<<"mu : "<<mu<<endl;
137
  file<<"timestep_max : "<<timestep_max<<endl;
138
  file<<"\nthreshold up : "<<t_up<<endl;
139
  file<<"threshold down : "<<t_down<<endl;
140
  file<<"beta : "<<beta<<endl;
141

    
142
  ofstream bg_file;
143
  string bg_name=filename_cut+"_BGgrowth.txt";
144
  bg_file.open(bg_name.c_str());
145
  bg_file<<"it\tbg_growth"<<endl;
146

    
147
  //-----------------------------------------Image Pre-processing
148
  //add slices
149
  img=add_side_slices(img,3);
150

    
151
  //define and save cut
152
  int cut=img._depth/2;
153
  cout <<"cut z= "<<cut<<endl;
154
  file <<"\ncut z= "<<cut<<endl;
155
  CImg<float> imgCut=img.get_crop(0,0,cut,0,img._width,img._height,cut,0);
156
  imgCut.save((filename_cut+".png").c_str());
157

    
158
  //smooth image
159
  file<<"smooth : "<<smooth<<endl;
160
  img.blur(smooth);
161

    
162
  //-------------------------------------------Initialization
163
  //compute fixed terms
164
  CImg<float> g=edge_indicator(gradient(img));
165
  CImgList<float> gg=gradient(g);
166
 
167
  //initialize level-set
168
  int c0=-4;
169
  CImg<unsigned char> segmented=threshold_linear_alongZ(img,t_up,t_down);
170
  string segmentedName=filename+".gz";
171
  segmentedName.insert(filename.size()-4,"_initial");
172
  segmented.save_gzip_external(segmentedName.c_str());
173

    
174
  CImg<float> psi=lsm_contour_init(segmented,c0);
175

    
176
  int it=0;
177
  int it_stop=0;
178
  bool contour_evolves=true;
179
  int nb_pix=img.width()*img.height()*img.depth();
180
  double prev_backsegm=segmented.sum();
181

    
182
  //-------------------------------------------Time iterations
183
  while( (it<timestep_max) and (contour_evolves==true) )
184
    {
185
      //LSM
186
      psi=evolution_AK2_contour(psi,g,gg,g,lam,mu,alf,beta,epsilon,dt);
187

    
188
      //Update segmentation
189
      double backsegm=0;
190
      cimg_forXYZ(segmented,x,y,z)
191
        {
192
          if(psi(x,y,z)>0)
193
            {
194
              segmented(x,y,z)=1;
195
              backsegm+=1;
196
            }
197
          else
198
            {segmented(x,y,z)=0;}
199
        }        
200

    
201
      //Background evolution
202
      double bg_evolution=backsegm-prev_backsegm;
203
      double bg100=(bg_evolution*1.0/nb_pix)*100;
204
      prev_backsegm=backsegm;
205

    
206
      cout<<"----------------------------------- it : "<<it<<endl;
207
      cout<<"bg growth : "<<bg_evolution<<endl;
208
      cout<<"% of bg growth : "<<bg100<<endl;
209
      bg_file<<it<<"\t"<<bg_evolution<<endl;
210
   
211

    
212
      //Stop criteria 
213
      if((it>10) and (bg100<0.002) and (bg100)>-0.002)
214
        {
215
          it_stop+=1;
216
          if(it_stop>9)
217
            {contour_evolves=false;}
218
        }
219
      else
220
        {
221
          it_stop=0;
222
        }
223

    
224
      //Graphics to follow evolution
225
      if((it%50==0)or(contour_evolves==false)or(it==timestep_max-1))
226
        {
227
          ostringstream oss;
228
          oss << it;
229
          string iterstring="";
230
          if(it<10) {iterstring="00"+oss.str();}
231
          else if (it<100) {iterstring="0"+oss.str();}
232
          else {iterstring=oss.str();}
233
          cout<<"-----------------------------------"<<endl;
234
          cout<<" *** time step for graphics : "<<iterstring<<endl;
235
          //Save cut
236
          CImg<float>segCut=segmented.get_crop(0,0,cut,0,img._width,img._height,cut,0);
237
          string temp_name=filename_cut+"it"+iterstring+".png";
238
          segCut.normalize(0,255).save(temp_name.c_str());
239
        }
240
      if((((it%50)==0)and(it!=0))or(contour_evolves==false)or(it==timestep_max-1))
241
                {
242
                  //Save result
243
                  CImg<unsigned char>segSave=remove_side_slices(segmented,3);
244
                  segSave = invert_image(segSave)*255;
245
                        segSave.save_tiff(result_name.c_str(),0,tailleVoxel,description.data());
246
                  segSave.assign();
247
                }
248
      it+=1;
249
    }
250

    
251
  clock_t end=clock();
252
  double time=double(end-begin)/CLOCKS_PER_SEC;
253
  cout <<"elapsed time : "<<time<<" sec ( ~ "<<time/60<<" mn ~ "<<time/60/60<<" h)"<<endl;
254
  file <<"last iteration : "<<it-1<<endl;
255
  file <<"elapsed time : "<<time<<" sec ( ~ "<<time/60<<" mn ~ "<<time/60/60<<" h)"<<endl;
256

    
257
  file<<"width "<<img.width()<<endl;
258
  file<<"height "<<img.height()<<endl;
259
  file<<"depth "<<img.depth()<<endl;
260

    
261
  file<<"number of pixel "<<img._width*img._height*img._depth<<endl;
262

    
263
  file.close();
264
  return 0;
265
}