Statistiques
| Révision :

root / src / lsm_lib.h @ 24

Historique | Voir | Annoter | Télécharger (16,78 ko)

1 18 akiss
#include <iostream>
2 18 akiss
#include <math.h>
3 18 akiss
#include <sstream>
4 18 akiss
#include <vector>
5 18 akiss
#include <fstream>
6 18 akiss
#include <algorithm>
7 18 akiss
8 18 akiss
#include "CImg.h"
9 18 akiss
10 18 akiss
using namespace cimg_library;
11 18 akiss
using namespace std;
12 18 akiss
13 18 akiss
14 18 akiss
//**************************************** GLOBAL IMAGE *************************************************************************
15 18 akiss
16 21 akiss
//Invert the image
17 21 akiss
//----------------------------------------------------------------------------
18 21 akiss
CImg<unsigned char> invert_image(CImg<unsigned char> const & img)
19 21 akiss
{
20 21 akiss
  CImg<unsigned char> unity(img._width,img._height,img._depth,1,1);
21 21 akiss
  CImg<unsigned char> inverted = unity - img;
22 21 akiss
  return inverted;
23 21 akiss
}
24 21 akiss
25 18 akiss
//Add black slices on each side of the image
26 18 akiss
//----------------------------------------------------------------------------
27 18 akiss
CImg<float> add_side_slices(CImg<float> const & img, int side)
28 18 akiss
{
29 18 akiss
  int s=side*2;
30 18 akiss
  CImg<float> newImg(img._width+s,img._height+s,img._depth+s,1,1);
31 18 akiss
32 18 akiss
  cimg_forXYZ(img,x,y,z)
33 18 akiss
    {
34 18 akiss
      newImg(x+side,y+side,z+side)=img(x,y,z);
35 18 akiss
    }
36 18 akiss
  return newImg;
37 18 akiss
}
38 18 akiss
39 18 akiss
//Remove slices
40 18 akiss
//----------------------------------------------------------------------------
41 18 akiss
CImg<float> remove_side_slices(CImg<float> const & img, int side)
42 18 akiss
{
43 18 akiss
  int s=side*2;
44 18 akiss
  CImg<float> newImg(img._width-s,img._height-s,img._depth-s,1,0);
45 18 akiss
46 18 akiss
  cimg_forXYZ(newImg,x,y,z)
47 18 akiss
    {
48 18 akiss
      newImg(x,y,z)=img(x+side,y+side,z+side);
49 18 akiss
    }
50 18 akiss
  return newImg;
51 18 akiss
}
52 18 akiss
53 18 akiss
//Threshold linear along Z   1:background  0:cells
54 18 akiss
//----------------------------------------------------------------------------
55 18 akiss
CImg<unsigned char> threshold_linear_alongZ(CImg<float> const & img, int t1, int t2)
56 18 akiss
{
57 18 akiss
  CImg<unsigned char> outside(img._width,img._height,img._depth,1,0);
58 18 akiss
  for(int z=0; z<img._depth ; z++)
59 18 akiss
    {
60 18 akiss
      cimg_forXY(outside,x,y)
61 18 akiss
        {
62 18 akiss
          float thresh = t1 + (t2-t1)*(z*1.0/img._depth);
63 18 akiss
          if(img(x,y,z)<thresh)
64 18 akiss
            {outside(x,y,z)=1;}
65 18 akiss
        }
66 18 akiss
    }
67 18 akiss
  outside.label();
68 18 akiss
  cimg_forXYZ(outside,x,y,z)
69 18 akiss
    {
70 18 akiss
      if(outside(x,y,z)>0) {outside(x,y,z)=0;}
71 18 akiss
      else {outside(x,y,z)=1;}
72 18 akiss
    }
73 18 akiss
  return outside;
74 18 akiss
}
75 18 akiss
76 18 akiss
//LSM contour init +c0 background, -c0 cells
77 18 akiss
//--------------------------------------------------------------------------
78 18 akiss
CImg<float> lsm_contour_init(CImg<unsigned char> const & region,int c0)
79 18 akiss
{
80 18 akiss
  CImg<float> initLSM(region._width,region._height,region._depth,1,c0);
81 18 akiss
  initLSM=initLSM-2*c0*region;
82 18 akiss
  return initLSM;
83 18 akiss
}
84 18 akiss
85 18 akiss
//Gradient 3D with central finite differences
86 18 akiss
//----------------------------------------------------------------------------
87 18 akiss
CImgList<float> gradient(CImg<float> const & img)
88 18 akiss
{
89 18 akiss
  //List of 3 images the same size as img
90 18 akiss
  CImgList<float> grad(3,img._width,img._height,img._depth,1,0);
91 18 akiss
92 18 akiss
  //Image loop with a 3*3*3 neighborhood
93 18 akiss
  CImg_3x3x3(I,float);
94 18 akiss
  cimg_for3x3x3(img,x,y,z,0,I,float)
95 18 akiss
    {
96 18 akiss
      grad(0,x,y,z) = (Incc - Ipcc)/2; //grad x = (img(x+1,y,z)-img(x-1,y,z))/2
97 18 akiss
      grad(1,x,y,z) = (Icnc - Icpc)/2; //grad y
98 18 akiss
      grad(2,x,y,z) = (Iccn - Iccp)/2; //grad z
99 18 akiss
    }
100 18 akiss
  return grad;
101 18 akiss
}
102 18 akiss
103 18 akiss
//Norm of the gradient
104 18 akiss
//---------------------------------------------------------------------------
105 18 akiss
CImg<float> gradient_norm(CImg<float> const & img)
106 18 akiss
{
107 18 akiss
  CImgList<float> grad = gradient(img);
108 18 akiss
  CImg<float> res(grad[0]._width,grad[0]._height,grad[0]._depth,1,0);
109 18 akiss
  float f=0;
110 18 akiss
  cimg_forXYZ(res,x,y,z)
111 18 akiss
    {
112 18 akiss
      f=grad(0,x,y,z)*grad(0,x,y,z) + grad(1,x,y,z)*grad(1,x,y,z) + grad(2,x,y,z)*grad(2,x,y,z);
113 18 akiss
      res(x,y,z)=sqrt(f);
114 18 akiss
    }
115 18 akiss
  return res;
116 18 akiss
}
117 18 akiss
118 18 akiss
119 18 akiss
//Edge indicator
120 18 akiss
//---------------------------------------------------------------------------
121 18 akiss
CImg<float> edge_indicator(CImgList<float> const & grad)
122 18 akiss
{
123 18 akiss
  CImg<float> res(grad[0]._width,grad[0]._height,grad[0]._depth,1,0);
124 18 akiss
  float f=0;
125 18 akiss
  cimg_forXYZ(res,x,y,z)
126 18 akiss
    {
127 18 akiss
      f=grad(0,x,y,z)*grad(0,x,y,z) + grad(1,x,y,z)*grad(1,x,y,z) + grad(2,x,y,z)*grad(2,x,y,z);
128 18 akiss
      res(x,y,z)=1.0/(1.0+f);
129 18 akiss
      //res(x,y,z)=exp(-f);
130 18 akiss
    }
131 18 akiss
  return res;
132 18 akiss
}
133 18 akiss
134 18 akiss
//Edge indicator 1 (gradient)
135 18 akiss
//---------------------------------------------------------------------------
136 18 akiss
CImg<float> edge_indicator1(CImg<float> const & img)
137 18 akiss
{
138 18 akiss
  CImgList<float> grad;
139 18 akiss
  grad = gradient(img);
140 18 akiss
  CImg<float> res(img._width,img._height,img._depth,1,0);
141 18 akiss
  float f=0;
142 18 akiss
  cimg_forXYZ(res,x,y,z)
143 18 akiss
    {
144 18 akiss
      f=grad(0,x,y,z)*grad(0,x,y,z) + grad(1,x,y,z)*grad(1,x,y,z) + grad(2,x,y,z)*grad(2,x,y,z);
145 18 akiss
      res(x,y,z)=1.0/(1.0+f);
146 18 akiss
    }
147 18 akiss
  return res;
148 18 akiss
}
149 18 akiss
150 18 akiss
CImg<float> edge_indicator1(CImg<float> const & img, float gamma)
151 18 akiss
{
152 18 akiss
  CImgList<float> grad;
153 18 akiss
  grad = gradient(img);
154 18 akiss
  CImg<float> res(img._width,img._height,img._depth,1,0);
155 18 akiss
  float f=0;
156 18 akiss
  cimg_forXYZ(res,x,y,z)
157 18 akiss
    {
158 18 akiss
      f=grad(0,x,y,z)*grad(0,x,y,z) + grad(1,x,y,z)*grad(1,x,y,z) + grad(2,x,y,z)*grad(2,x,y,z);
159 18 akiss
      res(x,y,z)=1.0/(1.0+f/gamma/gamma);
160 18 akiss
    }
161 18 akiss
  return res;
162 18 akiss
}
163 18 akiss
164 18 akiss
//Edge indicator 2 (hessienne, computed without smoothing)
165 18 akiss
//---------------------------------------------------------------------------
166 18 akiss
CImg<float> edge_indicator2(CImg<float> const & img)
167 18 akiss
{
168 18 akiss
  CImg<float> res(img._width,img._height,img._depth,1,0);
169 18 akiss
  float f=0;
170 18 akiss
  cimg_forXYZ(res,x,y,z)
171 18 akiss
    {
172 18 akiss
    int xp=x-1;
173 18 akiss
        if (x==0){xp=x;}
174 18 akiss
        int xn=x+1;
175 18 akiss
        if (x==img._width-1){xn=x;}
176 18 akiss
        int yp=y-1;
177 18 akiss
        if (y==0){yp=y;}
178 18 akiss
        int yn=y+1;
179 18 akiss
        if (y==img._height-1){yn=y;}
180 18 akiss
        int zp=z-1;
181 18 akiss
        if (z==0){zp=z;}
182 18 akiss
        int zn=z+1;
183 18 akiss
        if (z==img._depth-1){zn=z;}
184 18 akiss
185 18 akiss
        CImg<float> hess(3,3,1,1,0);
186 18 akiss
        hess(0,0) = img(xp,y,z) + img(xn,y,z) - 2*img(x,y,z);          // Hxx
187 18 akiss
        hess(1,1) = img(x,yp,z) + img(x,yn,z) - 2*img(x,y,z);          // Hyy
188 18 akiss
        hess(2,2) = img(x,y,zp) + img(x,y,zn) - 2*img(x,y,z);          // Hzz
189 18 akiss
        hess(1,0) = hess(0,1) = (img(xp,yp,z) + img(xn,yn,z) - img(xp,yn,z) - img(xn,yp,z))/4; // Hxy = Hyx
190 18 akiss
        hess(2,0) = hess(0,2) = (img(xp,y,zp) + img(xn,y,zn) - img(xp,y,zn) - img(xn,y,zp))/4; // Hxz = Hzx
191 18 akiss
        hess(2,1) = hess(1,2) = (img(x,yp,zp) + img(x,yn,zn) - img(x,yp,zn) - img(x,yn,zp))/4; // Hyz = Hzy
192 18 akiss
193 18 akiss
        //val : 3 eigen values as an array, decreasing order
194 18 akiss
        //vec : 3 eigen vectors as a 3*3 image
195 18 akiss
        //have to be double or create NaN
196 18 akiss
        CImg<double> val,vec;
197 18 akiss
        hess.symmetric_eigen(val,vec);
198 18 akiss
        if (val[2]>0) val[2]=0;
199 18 akiss
        val[2]=-val[2];
200 18 akiss
        //res(x,y,z)=1.0/(1.0 +val[2]*(50/3.));  //h=g test4
201 18 akiss
    //res(x,y,z)=1.0/(1.0 +val[2]*val[2]*(50/3.)*(50/3.) );
202 18 akiss
    //res(x,y,z)=1.0/(1.0 +exp(-val[2]));
203 18 akiss
    //res(x,y,z)=exp(-val[2]);
204 18 akiss
    //res(x,y,z)=exp(-val[2]*val[2]);
205 18 akiss
    res(x,y,z)=1.0/(1.0 +val[2]*val[2]);
206 18 akiss
    }
207 18 akiss
  return res;
208 18 akiss
}
209 18 akiss
210 18 akiss
//Edge indicator 2 (hessienne, computed with smoothing)
211 18 akiss
//---------------------------------------------------------------------------
212 18 akiss
CImg<float> edge_indicator2s(CImg<float> const & img, float gamma)
213 18 akiss
{
214 18 akiss
  CImg<float> res(img._width,img._height,img._depth,1,0);
215 18 akiss
216 18 akiss
  // make a minimal blur before taking derivatives
217 18 akiss
  CImg<float> imgBlur=img.get_blur(2);
218 18 akiss
219 18 akiss
  float f=0;
220 18 akiss
  cimg_forXYZ(res,x,y,z)
221 18 akiss
    {
222 18 akiss
    int xp=x-1;
223 18 akiss
        if (x==0){xp=x;}
224 18 akiss
        int xn=x+1;
225 18 akiss
        if (x==img._width-1){xn=x;}
226 18 akiss
        int yp=y-1;
227 18 akiss
        if (y==0){yp=y;}
228 18 akiss
        int yn=y+1;
229 18 akiss
        if (y==img._height-1){yn=y;}
230 18 akiss
        int zp=z-1;
231 18 akiss
        if (z==0){zp=z;}
232 18 akiss
        int zn=z+1;
233 18 akiss
        if (z==img._depth-1){zn=z;}
234 18 akiss
235 18 akiss
        CImg<float> hess(3,3,1,1,0);
236 18 akiss
        hess(0,0) = imgBlur(xp,y,z) + imgBlur(xn,y,z) - 2*imgBlur(x,y,z);          // Hxx
237 18 akiss
        hess(1,1) = imgBlur(x,yp,z) + imgBlur(x,yn,z) - 2*imgBlur(x,y,z);          // Hyy
238 18 akiss
        hess(2,2) = imgBlur(x,y,zp) + imgBlur(x,y,zn) - 2*imgBlur(x,y,z);          // Hzz
239 18 akiss
        hess(1,0) = hess(0,1) = (imgBlur(xp,yp,z) + imgBlur(xn,yn,z) - imgBlur(xp,yn,z) - imgBlur(xn,yp,z))/4; // Hxy = Hyx
240 18 akiss
        hess(2,0) = hess(0,2) = (imgBlur(xp,y,zp) + imgBlur(xn,y,zn) - imgBlur(xp,y,zn) - imgBlur(xn,y,zp))/4; // Hxz = Hzx
241 18 akiss
        hess(2,1) = hess(1,2) = (imgBlur(x,yp,zp) + imgBlur(x,yn,zn) - imgBlur(x,yp,zn) - imgBlur(x,yn,zp))/4; // Hyz = Hzy
242 18 akiss
243 18 akiss
        //val : 3 eigen values as an array, decreasing order
244 18 akiss
        //vec : 3 eigen vectors as a 3*3 image
245 18 akiss
        //have to be double or create NaN
246 18 akiss
        CImg<double> val,vec;
247 18 akiss
        hess.symmetric_eigen(val,vec);
248 18 akiss
        if (val[2]>0) val[2]=0;
249 18 akiss
        val[2]=-val[2];
250 18 akiss
    res(x,y,z)=1.0/(1.0 +val[2]*val[2]/gamma/gamma);
251 18 akiss
    }
252 18 akiss
  return res;
253 18 akiss
}
254 18 akiss
255 18 akiss
256 18 akiss
CImg<float> edge_indicator2(CImg<float> const & img, float gamma)
257 18 akiss
{
258 18 akiss
  CImg<float> res(img._width,img._height,img._depth,1,0);
259 18 akiss
  float f=0;
260 18 akiss
  cimg_forXYZ(res,x,y,z)
261 18 akiss
    {
262 18 akiss
    int xp=x-1;
263 18 akiss
        if (x==0){xp=x;}
264 18 akiss
        int xn=x+1;
265 18 akiss
        if (x==img._width-1){xn=x;}
266 18 akiss
        int yp=y-1;
267 18 akiss
        if (y==0){yp=y;}
268 18 akiss
        int yn=y+1;
269 18 akiss
        if (y==img._height-1){yn=y;}
270 18 akiss
        int zp=z-1;
271 18 akiss
        if (z==0){zp=z;}
272 18 akiss
        int zn=z+1;
273 18 akiss
        if (z==img._depth-1){zn=z;}
274 18 akiss
275 18 akiss
        CImg<float> hess(3,3,1,1,0);
276 18 akiss
        hess(0,0) = img(xp,y,z) + img(xn,y,z) - 2*img(x,y,z);          // Hxx
277 18 akiss
        hess(1,1) = img(x,yp,z) + img(x,yn,z) - 2*img(x,y,z);          // Hyy
278 18 akiss
        hess(2,2) = img(x,y,zp) + img(x,y,zn) - 2*img(x,y,z);          // Hzz
279 18 akiss
        hess(1,0) = hess(0,1) = (img(xp,yp,z) + img(xn,yn,z) - img(xp,yn,z) - img(xn,yp,z))/4; // Hxy = Hyx
280 18 akiss
        hess(2,0) = hess(0,2) = (img(xp,y,zp) + img(xn,y,zn) - img(xp,y,zn) - img(xn,y,zp))/4; // Hxz = Hzx
281 18 akiss
        hess(2,1) = hess(1,2) = (img(x,yp,zp) + img(x,yn,zn) - img(x,yp,zn) - img(x,yn,zp))/4; // Hyz = Hzy
282 18 akiss
283 18 akiss
        //val : 3 eigen values as an array, decreasing order
284 18 akiss
        //vec : 3 eigen vectors as a 3*3 image
285 18 akiss
        //have to be double or create NaN
286 18 akiss
        CImg<double> val,vec;
287 18 akiss
        hess.symmetric_eigen(val,vec);
288 18 akiss
        if (val[2]>0) val[2]=0;
289 18 akiss
        //val[2]=-val[2];
290 18 akiss
    res(x,y,z)=1.0/(1.0 +val[2]*val[2]/gamma/gamma);
291 18 akiss
    }
292 18 akiss
  return res;
293 18 akiss
}
294 18 akiss
295 18 akiss
//Edge indicator 3 (image based)
296 18 akiss
//---------------------------------------------------------------------------
297 18 akiss
CImg<float> edge_indicator3(CImg<float> const & img)
298 18 akiss
{
299 18 akiss
  CImg<float> res(img._width,img._height,img._depth,1,0);
300 18 akiss
  cimg_forXYZ(res,x,y,z)
301 18 akiss
    {
302 18 akiss
      res(x,y,z)=1.0/(1.0+img(x,y,z)*img(x,y,z));
303 18 akiss
    }
304 18 akiss
  return res;
305 18 akiss
}
306 18 akiss
307 18 akiss
CImg<float> edge_indicator3(CImg<float> const & img, float gamma)
308 18 akiss
{
309 18 akiss
  CImg<float> res(img._width,img._height,img._depth,1,0);
310 18 akiss
  cimg_forXYZ(res,x,y,z)
311 18 akiss
    {
312 18 akiss
                res(x,y,z)=1.0/(1.0+(img(x,y,z)/gamma)*(img(x,y,z)/gamma));
313 18 akiss
    }
314 18 akiss
  return res;
315 18 akiss
}
316 18 akiss
317 18 akiss
//Edge image (based on lambda3 of the hessien)
318 18 akiss
//---------------------------------------------------------------------------
319 18 akiss
CImg<float> edge_lambda3(CImg<float> const & img)
320 18 akiss
{
321 18 akiss
  CImg<float> res(img._width,img._height,img._depth,1,0);
322 18 akiss
  float f=0;
323 18 akiss
  cimg_forXYZ(res,x,y,z)
324 18 akiss
    {
325 18 akiss
    int xp=x-1;
326 18 akiss
        if (x==0){xp=x;}
327 18 akiss
        int xn=x+1;
328 18 akiss
        if (x==img._width-1){xn=x;}
329 18 akiss
        int yp=y-1;
330 18 akiss
        if (y==0){yp=y;}
331 18 akiss
        int yn=y+1;
332 18 akiss
        if (y==img._height-1){yn=y;}
333 18 akiss
        int zp=z-1;
334 18 akiss
        if (z==0){zp=z;}
335 18 akiss
        int zn=z+1;
336 18 akiss
        if (z==img._depth-1){zn=z;}
337 18 akiss
338 18 akiss
        CImg<float> hess(3,3,1,1,0);
339 18 akiss
        hess(0,0) = img(xp,y,z) + img(xn,y,z) - 2*img(x,y,z);          // Hxx
340 18 akiss
        hess(1,1) = img(x,yp,z) + img(x,yn,z) - 2*img(x,y,z);          // Hyy
341 18 akiss
        hess(2,2) = img(x,y,zp) + img(x,y,zn) - 2*img(x,y,z);          // Hzz
342 18 akiss
        hess(1,0) = hess(0,1) = (img(xp,yp,z) + img(xn,yn,z) - img(xp,yn,z) - img(xn,yp,z))/4; // Hxy = Hyx
343 18 akiss
        hess(2,0) = hess(0,2) = (img(xp,y,zp) + img(xn,y,zn) - img(xp,y,zn) - img(xn,y,zp))/4; // Hxz = Hzx
344 18 akiss
        hess(2,1) = hess(1,2) = (img(x,yp,zp) + img(x,yn,zn) - img(x,yp,zn) - img(x,yn,zp))/4; // Hyz = Hzy
345 18 akiss
346 18 akiss
        //val : 3 eigen values as an array, decreasing order
347 18 akiss
        //vec : 3 eigen vectors as a 3*3 image
348 18 akiss
        //have to be double or create NaN
349 18 akiss
        CImg<double> val,vec;
350 18 akiss
        hess.symmetric_eigen(val,vec);
351 18 akiss
        if (val[2]>0) val[2]=0;
352 18 akiss
    res(x,y,z)=-val[2];
353 18 akiss
    }
354 18 akiss
  return res;
355 18 akiss
}
356 18 akiss
357 18 akiss
358 18 akiss
//Wall indicator
359 18 akiss
//---------------------------------------------------------------------------
360 18 akiss
CImg<float> wall_indicator(CImg<float> const & img)
361 18 akiss
{
362 18 akiss
  CImg<float> res(img._width,img._height,img._depth,1,0);
363 18 akiss
  cimg_forXYZ(res,x,y,z)
364 18 akiss
    {
365 18 akiss
      res(x,y,z)=1.0/(1.0+(img(x,y,z)*img(x,y,z)));
366 18 akiss
    }
367 18 akiss
  return res;
368 18 akiss
}
369 18 akiss
370 18 akiss
//Dirac function
371 18 akiss
//-------------------------------------------------------------------------
372 18 akiss
CImg<float> Dirac(CImg<float> const & img, float sigma)
373 18 akiss
{
374 18 akiss
  CImg<float> fImg(img._width,img._height,img._depth,1,0);
375 18 akiss
  float f=0;
376 18 akiss
  cimg_forXYZ(img,x,y,z)
377 18 akiss
    {
378 18 akiss
      if(abs(img(x,y,z))<=sigma)
379 18 akiss
        {
380 18 akiss
          f=(1.0/(2*sigma))*(1+cos(M_PI*img(x,y,z)/sigma));
381 18 akiss
        }
382 18 akiss
      else {f=0;}
383 18 akiss
      fImg(x,y,z)=f;
384 18 akiss
    }
385 18 akiss
  return fImg;
386 18 akiss
}
387 18 akiss
388 18 akiss
//Normal vector
389 18 akiss
//------------------------------------------------------------------------
390 18 akiss
CImgList<float> normal_vector(CImg<float> const & img)
391 18 akiss
{
392 18 akiss
  CImgList<float> normal_vector(3,img._width,img._height,img._depth,1,0);
393 18 akiss
394 18 akiss
  CImg_3x3x3(I,float);
395 18 akiss
  cimg_for3x3x3(img,x,y,z,0,I,float)
396 18 akiss
    {
397 18 akiss
      float nx = (Incc-Ipcc)/2.0;
398 18 akiss
      float ny = (Icnc-Icpc)/2.0;
399 18 akiss
      float nz = (Iccn-Iccp)/2.0;
400 18 akiss
      //border
401 18 akiss
      if((x==0)or(y==0)or(z==0))
402 18 akiss
        {nx=ny=nz=0;}
403 18 akiss
      if((x==img.width()-1)or(y==img.height()-1)or(z==img.depth()-1))
404 18 akiss
        {nx=ny=nz=0;}
405 18 akiss
406 18 akiss
      float norm=1;
407 18 akiss
      if((nx!=0)or(ny!=0)or(nz!=0))
408 18 akiss
        {norm = sqrt(nx*nx+ny*ny+nz*nz);}
409 18 akiss
410 18 akiss
      normal_vector(0,x,y,z)=nx/norm;
411 18 akiss
      normal_vector(1,x,y,z)=ny/norm;
412 18 akiss
      normal_vector(2,x,y,z)=nz/norm;
413 18 akiss
    }
414 18 akiss
  return normal_vector;
415 18 akiss
}
416 18 akiss
417 18 akiss
418 18 akiss
//Curvature
419 18 akiss
//------------------------------------------------------------------------
420 18 akiss
CImg<float> curvature2(CImgList<float> const & N)
421 18 akiss
{
422 18 akiss
  CImg<float> K(N[0]._width,N[0]._height,N[0]._depth,1,0);
423 18 akiss
  cimg_forXYZ(N[0],x,y,z)
424 18 akiss
    {
425 18 akiss
      float kx=0;
426 18 akiss
      float ky=0;
427 18 akiss
      float kz=0;
428 18 akiss
      if(x==0)
429 18 akiss
        {kx=N[0](x+1,y,z)-N[0](x,y,z);}
430 18 akiss
      else if(x==N[0]._width-1)
431 18 akiss
        {kx=N[0](x,y,z)-N[0](x-1,y,z);}
432 18 akiss
      else
433 18 akiss
        {kx=(N[0](x+1,y,z)-N[0](x-1,y,z))/2.0;}
434 18 akiss
435 18 akiss
     if(y==0)
436 18 akiss
        {ky=N[1](x,y+1,z)-N[1](x,y,z);}
437 18 akiss
      else if(y==N[1]._height-1)
438 18 akiss
        {ky=N[1](x,y,z)-N[1](x,y-1,z);}
439 18 akiss
      else
440 18 akiss
        {ky=(N[1](x,y+1,z)-N[1](x,y-1,z))/2.0;}
441 18 akiss
442 18 akiss
     if(z==0)
443 18 akiss
        {kz=N[2](x,y,z+1)-N[2](x,y,z);}
444 18 akiss
      else if(z==N[2]._depth-1)
445 18 akiss
        {kz=N[2](x,y,z)-N[2](x,y,z-1);}
446 18 akiss
      else
447 18 akiss
        {kz=(N[2](x,y,z+1)-N[2](x,y,z-1))/2.0;}
448 18 akiss
449 18 akiss
     K(x,y,z)=kx+ky+kz;
450 18 akiss
    }
451 18 akiss
  return K;
452 18 akiss
}
453 18 akiss
454 18 akiss
// Compute image laplacian
455 18 akiss
//--------------------------------------------------------------------
456 18 akiss
CImg<float> laplacian(CImg<float> const & img)
457 18 akiss
{
458 18 akiss
  CImg<float> laplacian(img._width,img._height,img._depth,1,0);
459 18 akiss
  CImg_3x3x3(I,float);
460 18 akiss
  cimg_for3x3x3(img,x,y,z,0,I,float)
461 18 akiss
    {
462 18 akiss
      laplacian(x,y,z) =Incc+Ipcc+Icnc+Icpc+Iccn+Iccp - 6*Iccc;
463 18 akiss
    }
464 18 akiss
  return laplacian;
465 18 akiss
}
466 18 akiss
467 18 akiss
//Evolution AK2 contour
468 18 akiss
//-------------------------------------------------------------------------
469 18 akiss
CImg<float> evolution_AK2_contour(CImg<float> u, CImg<float> const & g, CImgList<float> const & gg, CImg<float> const & h, int lam, float mu, float alf, float beta, float epsilon, int dt)
470 18 akiss
{
471 18 akiss
  CImg<float> diracU=Dirac(u,epsilon);
472 18 akiss
  CImgList<float> N=normal_vector(u);
473 18 akiss
  CImg<float> K=curvature2(N);
474 18 akiss
  CImg<float> L=laplacian(u);
475 18 akiss
  float term=0;
476 18 akiss
477 18 akiss
  cimg_forXYZ(u,x,y,z)
478 18 akiss
    {
479 18 akiss
      term=0;
480 18 akiss
      if (diracU(x,y,z)!=0)
481 18 akiss
        {
482 18 akiss
          //weighted length term
483 18 akiss
          if(lam!=0)
484 18 akiss
            {term=( gg(0,x,y,z)*N(0,x,y,z) + gg(1,x,y,z)*N(1,x,y,z) + gg(2,x,y,z)*N(2,x,y,z) + (g(x,y,z)*K(x,y,z))) *lam;}
485 18 akiss
          //length term
486 18 akiss
          if(beta!=0)
487 18 akiss
            {term=term + K(x,y,z)*beta;}
488 18 akiss
          //weighted area term
489 18 akiss
          if(alf!=0)
490 18 akiss
            {term=term + h(x,y,z)*alf;}
491 18 akiss
          //regularization
492 18 akiss
          term=term*diracU(x,y,z);
493 18 akiss
          //penalizing term
494 18 akiss
          term=term + (L(x,y,z)-K(x,y,z))*mu;
495 18 akiss
        }
496 18 akiss
      else
497 18 akiss
        {
498 18 akiss
          //penalizing term
499 18 akiss
          term=(L(x,y,z)-K(x,y,z))*mu;
500 18 akiss
        }
501 18 akiss
502 18 akiss
      u(x,y,z)=u(x,y,z) + term*dt;
503 18 akiss
    }
504 18 akiss
  return u;
505 18 akiss
}
506 18 akiss
507 18 akiss
//Evolution AK2 contour cells
508 18 akiss
//-------------------------------------------------------------------------
509 18 akiss
CImg<float> evolution_AK2_contour_cells(CImg<float> u, CImg<float> const & g, CImgList<float> const & gg, CImg<float> const & h, int lam, float mu, float alf, int beta, float epsilon, int dt, vector<int> min_list)
510 18 akiss
{
511 18 akiss
  CImg<float> diracU=Dirac(u,epsilon);
512 18 akiss
  CImgList<float> N=normal_vector(u);
513 18 akiss
  CImg<float> K=curvature2(N);
514 18 akiss
  CImg<float> L=laplacian(u);
515 18 akiss
  float term=0;
516 18 akiss
517 18 akiss
518 18 akiss
  cimg_forXYZ(u,x,y,z)
519 18 akiss
    {
520 18 akiss
      int xb=x+min_list[0];
521 18 akiss
      int yb=y+min_list[1];
522 18 akiss
      int zb=z+min_list[2];
523 18 akiss
      term=0;
524 18 akiss
      if (diracU(x,y,z)!=0)
525 18 akiss
        {
526 18 akiss
          //weighted length term
527 18 akiss
          if(lam!=0)
528 18 akiss
            {term=( gg(0,xb,yb,zb)*N(0,x,y,z) + gg(1,xb,yb,zb)*N(1,x,y,z) + gg(2,xb,yb,zb)*N(2,x,y,z) + (g(xb,yb,zb)*K(x,y,z))) *lam;}
529 18 akiss
          //length term
530 18 akiss
          if(beta!=0)
531 18 akiss
            {term=term + K(x,y,z)*beta;}
532 18 akiss
          //weighted area term
533 18 akiss
          if(alf!=0)
534 18 akiss
            {term=term + h(xb,yb,zb)*alf;}
535 18 akiss
          //regularization
536 18 akiss
          term=term*diracU(x,y,z);
537 18 akiss
          //penalizing term
538 18 akiss
          term=term + (L(x,y,z)-K(x,y,z))*mu;
539 18 akiss
        }
540 18 akiss
      else
541 18 akiss
        {
542 18 akiss
          //penalizing term
543 18 akiss
          term=(L(x,y,z)-K(x,y,z))*mu;
544 18 akiss
        }
545 18 akiss
546 18 akiss
      u(x,y,z)=u(x,y,z) + term*dt;
547 18 akiss
    }
548 18 akiss
  return u;
549 18 akiss
}
550 18 akiss
551 18 akiss
//Evolution AK2 contour INTERRACT
552 18 akiss
//-------------------------------------------------------------------------
553 18 akiss
CImg<float> evolution_AK2_contour_interact(CImg<float> u, CImg<float> const & g, CImgList<float> const & gg, CImg<float> const & h, int lam, float mu, float alf, int beta, float epsilon, int dt, CImg<unsigned char> const & free, vector<int>min_list)
554 18 akiss
{
555 18 akiss
  CImg<float> diracU=Dirac(u,epsilon);
556 18 akiss
  CImgList<float> N=normal_vector(u);
557 18 akiss
  CImg<float> K=curvature2(N);
558 18 akiss
  CImg<float> L=laplacian(u);
559 18 akiss
  float term=0;
560 18 akiss
561 18 akiss
  cimg_forXYZ(u,x,y,z)
562 18 akiss
    {
563 18 akiss
      int xb=x+min_list[0];
564 18 akiss
      int yb=y+min_list[1];
565 18 akiss
      int zb=z+min_list[2];
566 18 akiss
      term=0;
567 18 akiss
      if(free(xb,yb,zb)==0)
568 18 akiss
        {
569 18 akiss
          if (diracU(x,y,z)!=0)
570 18 akiss
            {
571 18 akiss
              //weighted length term
572 18 akiss
              if(lam!=0)
573 18 akiss
                {term=( gg(0,xb,yb,zb)*N(0,x,y,z) + gg(1,xb,yb,zb)*N(1,x,y,z) + gg(2,xb,yb,zb)*N(2,x,y,z) + (g(xb,yb,zb)*K(x,y,z))) *lam;}
574 18 akiss
              //length term
575 18 akiss
              if(beta!=0)
576 18 akiss
                {term=term + K(x,y,z)*beta;}
577 18 akiss
              //weighted area term
578 18 akiss
              if(alf!=0)
579 18 akiss
                {term=term + h(xb,yb,zb)*alf;}
580 18 akiss
              //regularization
581 18 akiss
              term=term*diracU(x,y,z);
582 18 akiss
              //penalizing term
583 18 akiss
              term=term + (L(x,y,z)-K(x,y,z))*mu;
584 18 akiss
            }
585 18 akiss
          else
586 18 akiss
            {
587 18 akiss
              //penalizing term
588 18 akiss
              term=(L(x,y,z)-K(x,y,z))*mu;
589 18 akiss
            }
590 18 akiss
          u(x,y,z)=u(x,y,z) + term*dt;
591 18 akiss
        }
592 18 akiss
    }
593 18 akiss
  return u;
594 18 akiss
}